From 6b548103e995e1ba964678f75d1517ac1201c7e1 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Fri, 2 Aug 2024 10:48:17 -0400 Subject: [PATCH 01/19] add version field to plugin definition. --- .../node-service/src/plugins/asana/index.ts | 20 +++++++++++++++++- .../src/plugins/circleCi/index.ts | 18 ++++++++++++++++ .../src/plugins/cloudinary/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/couchdb/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/datadog/index.ts | 18 ++++++++++++++++ server/node-service/src/plugins/did/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/front/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/github/index.ts | 18 ++++++++++++++++ .../src/plugins/huggingFaceEndpoint/index.ts | 18 ++++++++++++++++ server/node-service/src/plugins/jira/index.ts | 18 ++++++++++++++++ .../src/plugins/lowcoder/index.ts | 20 +++++++++++++++++- server/node-service/src/plugins/n8n/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/notion/index.ts | 18 ++++++++++++++++ .../src/plugins/oneSignal/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/openAi/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/openApi/index.ts | 2 +- .../src/plugins/postmanEcho/index.ts | 21 ++++++++++++++++++- .../src/plugins/sendGrid/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/stripe/index.ts | 18 ++++++++++++++++ .../node-service/src/plugins/twilio/index.ts | 18 ++++++++++++++++ .../src/plugins/woocommerce/index.ts | 18 ++++++++++++++++ 21 files changed, 365 insertions(+), 4 deletions(-) diff --git a/server/node-service/src/plugins/asana/index.ts b/server/node-service/src/plugins/asana/index.ts index 04ba8ec3a..7677bf505 100644 --- a/server/node-service/src/plugins/asana/index.ts +++ b/server/node-service/src/plugins/asana/index.ts @@ -23,7 +23,24 @@ const dataSourceConfig = { "key": "personalAccessToken.value", "label": "Token", "tooltip": "A [personal access token](https://developers.asana.com/docs/personal-access-token) allows access to the api for the user who created it. This should be kept a secret and be treated like a password.", - } + }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ] } as const; @@ -58,6 +75,7 @@ const asanaPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/circleCi/index.ts b/server/node-service/src/plugins/circleCi/index.ts index d30eff7d1..501f34783 100644 --- a/server/node-service/src/plugins/circleCi/index.ts +++ b/server/node-service/src/plugins/circleCi/index.ts @@ -16,6 +16,23 @@ const dataSourceConfig = { tooltip: "[Personal API Token](https://circleci.com/docs/managing-api-tokens/#creating-a-personal-api-token)", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -53,6 +70,7 @@ const circleCiPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/cloudinary/index.ts b/server/node-service/src/plugins/cloudinary/index.ts index 196123899..1055e1150 100644 --- a/server/node-service/src/plugins/cloudinary/index.ts +++ b/server/node-service/src/plugins/cloudinary/index.ts @@ -32,6 +32,23 @@ const dataSourceConfig = { tooltip: "Basic auth password", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -74,6 +91,7 @@ const cloudinaryPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, specList); }, diff --git a/server/node-service/src/plugins/couchdb/index.ts b/server/node-service/src/plugins/couchdb/index.ts index 7c5731307..3004961be 100644 --- a/server/node-service/src/plugins/couchdb/index.ts +++ b/server/node-service/src/plugins/couchdb/index.ts @@ -38,6 +38,23 @@ const dataSourceConfig = { tooltip: "", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -77,6 +94,7 @@ const couchdbPlugin: DataSourcePlugin = { url: "", serverURL: serverURL, dynamicParamsConfig: otherDataSourceConfig, + specVersion: dataSourceConfig.specVersion }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV2.Document); }, diff --git a/server/node-service/src/plugins/datadog/index.ts b/server/node-service/src/plugins/datadog/index.ts index 8e581bf0e..0d82e00c7 100644 --- a/server/node-service/src/plugins/datadog/index.ts +++ b/server/node-service/src/plugins/datadog/index.ts @@ -27,6 +27,23 @@ const dataSourceConfig = { key: "appKeyAuth.value", label: "Application Key", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -64,6 +81,7 @@ const datadogPlugin: DataSourcePlugin = { url: "", serverURL: dataSourceConfig.serverURL, dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/did/index.ts b/server/node-service/src/plugins/did/index.ts index 268e9dff6..3ba568d01 100644 --- a/server/node-service/src/plugins/did/index.ts +++ b/server/node-service/src/plugins/did/index.ts @@ -44,6 +44,23 @@ const dataSourceConfig = { tooltip: "Basic auth password", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -83,6 +100,7 @@ const didPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, specList); }, diff --git a/server/node-service/src/plugins/front/index.ts b/server/node-service/src/plugins/front/index.ts index 7833ffe06..6af38c992 100644 --- a/server/node-service/src/plugins/front/index.ts +++ b/server/node-service/src/plugins/front/index.ts @@ -14,6 +14,23 @@ const dataSourceConfig = { key: "http.value", label: "Token", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -51,6 +68,7 @@ const frontPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/github/index.ts b/server/node-service/src/plugins/github/index.ts index 3f031b65e..614eb3469 100644 --- a/server/node-service/src/plugins/github/index.ts +++ b/server/node-service/src/plugins/github/index.ts @@ -27,6 +27,23 @@ const dataSourceConfig = { "[Document](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) about how to create a personal access token", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -62,6 +79,7 @@ const gitHubPlugin: DataSourcePlugin = { url: "", serverURL: "https://api.github.com", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document, undefined, await deRefedSpec); }, diff --git a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts index 47acade14..56b90bf6d 100644 --- a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts +++ b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts @@ -25,6 +25,23 @@ const dataSourceConfig = { tooltip: "You can get an Access Token [in your profile setting page](https://huggingface.co/settings/tokens)", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -62,6 +79,7 @@ const huggingFacePlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/jira/index.ts b/server/node-service/src/plugins/jira/index.ts index 60830b7f0..46464d828 100644 --- a/server/node-service/src/plugins/jira/index.ts +++ b/server/node-service/src/plugins/jira/index.ts @@ -36,6 +36,23 @@ const dataSourceConfig = { tooltip: "Basic auth password", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -79,6 +96,7 @@ const jiraPlugin: DataSourcePlugin = { url: "", serverURL: dataSourceConfig.serverUrl, dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec); }, diff --git a/server/node-service/src/plugins/lowcoder/index.ts b/server/node-service/src/plugins/lowcoder/index.ts index 53d2699d0..5800dee68 100644 --- a/server/node-service/src/plugins/lowcoder/index.ts +++ b/server/node-service/src/plugins/lowcoder/index.ts @@ -30,7 +30,24 @@ const dataSourceConfig = { label: "Authorization", "tooltip": "API Key Authentication with a Bearer token. Copy your API Key here. (e.g. 'Bearer eyJhbGciO...')", "placeholder": "API Key Authentication with a Bearer token. Copy your API Key here. (e.g. 'Bearer eyJhbGciO...')" - } + }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ] } as const; @@ -67,6 +84,7 @@ const lowcoderPlugin: DataSourcePlugin = { url: "", serverURL: serverURL, dynamicParamsConfig: otherDataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/n8n/index.ts b/server/node-service/src/plugins/n8n/index.ts index 4178b0b63..dcad50827 100644 --- a/server/node-service/src/plugins/n8n/index.ts +++ b/server/node-service/src/plugins/n8n/index.ts @@ -35,6 +35,23 @@ const dataSourceConfig = { tooltip: "You api key, doc: [n8n API authentication](https://docs.n8n.io/api/authentication/)", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -77,6 +94,7 @@ const n8nPlugin: DataSourcePlugin = { dynamicParamsConfig: { "ApiKeyAuth.value": apiKey, }, + specVersion: dataSourceConfig.specVersion }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/notion/index.ts b/server/node-service/src/plugins/notion/index.ts index 54657d1aa..f616431d7 100644 --- a/server/node-service/src/plugins/notion/index.ts +++ b/server/node-service/src/plugins/notion/index.ts @@ -24,6 +24,23 @@ const dataSourceConfig = { key: "bearerAuth.value", label: "Token", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -58,6 +75,7 @@ const notionPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document, { "Notion-Version": dataSourceConfig.notionVersion, diff --git a/server/node-service/src/plugins/oneSignal/index.ts b/server/node-service/src/plugins/oneSignal/index.ts index c29ee37a7..38a51c651 100644 --- a/server/node-service/src/plugins/oneSignal/index.ts +++ b/server/node-service/src/plugins/oneSignal/index.ts @@ -23,6 +23,23 @@ const dataSourceConfig = { tooltip: "Another type of REST API key used for viewing Apps and related updates. [Documentation](https://documentation.onesignal.com/docs/accounts-and-keys#user-auth-key)", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -60,6 +77,7 @@ const oneSignalPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/openAi/index.ts b/server/node-service/src/plugins/openAi/index.ts index e16d5a031..2d0c3de98 100644 --- a/server/node-service/src/plugins/openAi/index.ts +++ b/server/node-service/src/plugins/openAi/index.ts @@ -20,6 +20,23 @@ const dataSourceConfig = { tooltip: "[In your Open AI account page](https://platform.openai.com/account/api-keys) on which you can create your api key", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -54,6 +71,7 @@ const openAiPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/openApi/index.ts b/server/node-service/src/plugins/openApi/index.ts index fcc095f13..e0133a8cf 100644 --- a/server/node-service/src/plugins/openApi/index.ts +++ b/server/node-service/src/plugins/openApi/index.ts @@ -39,7 +39,7 @@ const dataSourceConfig = { type: "textInput", tooltip: "Change the default server url written in the spec file.", placeholder: "https://example.com/api/v1", - }, + } ], } as const; diff --git a/server/node-service/src/plugins/postmanEcho/index.ts b/server/node-service/src/plugins/postmanEcho/index.ts index 381c86b9e..49da21d3f 100644 --- a/server/node-service/src/plugins/postmanEcho/index.ts +++ b/server/node-service/src/plugins/postmanEcho/index.ts @@ -11,7 +11,25 @@ import spec from './postmanEcho.spec.json'; const dataSourceConfig = { type: "dataSource", - params: [] + params: [ + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, + ] } as const; const parseOptions: ParseOpenApiOptions = { @@ -45,6 +63,7 @@ const postmanEchoPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/sendGrid/index.ts b/server/node-service/src/plugins/sendGrid/index.ts index 0b49461a1..0cc834ed9 100644 --- a/server/node-service/src/plugins/sendGrid/index.ts +++ b/server/node-service/src/plugins/sendGrid/index.ts @@ -16,6 +16,23 @@ const dataSourceConfig = { tooltip: "[Documentation](https://docs.sendgrid.com/ui/account-and-settings/api-keys#creating-an-api-key)", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -55,6 +72,7 @@ const sendGridPlugin: DataSourcePlugin = { ...dataSourceConfig, "Authorization.value": "Bearer " + dataSourceConfig["Authorization.value"], }, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); }, diff --git a/server/node-service/src/plugins/stripe/index.ts b/server/node-service/src/plugins/stripe/index.ts index 3119131ea..67b69f801 100644 --- a/server/node-service/src/plugins/stripe/index.ts +++ b/server/node-service/src/plugins/stripe/index.ts @@ -25,6 +25,23 @@ const dataSourceConfig = { tooltip: "You can gen a Secret Key [here](https://dashboard.stripe.com/test/apikeys)", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -60,6 +77,7 @@ const stripePlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; // always use a new spec object // because of this bug: https://github.com/APIDevTools/json-schema-ref-parser/issues/271 diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index c3f249816..e8525d4f8 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -49,6 +49,23 @@ const dataSourceConfig = { label: "Secret", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -90,6 +107,7 @@ const twilioPlugin: DataSourcePlugin = { url: "", serverURL: "", dynamicParamsConfig: dataSourceConfig, + specVersion: dataSourceConfig.specVersion, }; return runOpenApi(actionData, runApiDsConfig, specList); }, diff --git a/server/node-service/src/plugins/woocommerce/index.ts b/server/node-service/src/plugins/woocommerce/index.ts index 2e94e9be3..b1e9d46e1 100644 --- a/server/node-service/src/plugins/woocommerce/index.ts +++ b/server/node-service/src/plugins/woocommerce/index.ts @@ -45,6 +45,23 @@ const dataSourceConfig = { tooltip: "", placeholder: "", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: [ + { + value: "v1.0", + label: "v1.0", + }, + { + value: "v2.0", + label: "v2.0", + } + ] + }, ], } as const; @@ -83,6 +100,7 @@ const wooCommercePlugin: DataSourcePlugin = { url: "", serverURL: prepareServerUrl(serverURL), dynamicParamsConfig: otherDataSourceConfig, + specVersion: dataSourceConfig.specVersion }; return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV2.Document); }, From da3c0aa0d661c95dc1d377cb158c2c5f1970395c Mon Sep 17 00:00:00 2001 From: Thomasr Date: Fri, 2 Aug 2024 13:15:35 -0400 Subject: [PATCH 02/19] refactor code and test with twilio plugin --- server/node-service/src/common/util.ts | 37 + .../node-service/src/plugins/asana/index.ts | 18 +- .../src/plugins/circleCi/index.ts | 16 +- .../src/plugins/cloudinary/index.ts | 18 +- .../node-service/src/plugins/couchdb/index.ts | 17 +- .../node-service/src/plugins/datadog/index.ts | 17 +- server/node-service/src/plugins/did/index.ts | 43 +- .../node-service/src/plugins/front/index.ts | 16 +- .../node-service/src/plugins/github/index.ts | 17 +- .../src/plugins/huggingFaceEndpoint/index.ts | 16 +- server/node-service/src/plugins/jira/index.ts | 17 +- .../src/plugins/lowcoder/index.ts | 17 +- server/node-service/src/plugins/n8n/index.ts | 16 +- .../node-service/src/plugins/notion/index.ts | 17 +- .../src/plugins/oneSignal/index.ts | 16 +- .../node-service/src/plugins/openAi/index.ts | 17 +- .../src/plugins/postmanEcho/index.ts | 17 +- .../src/plugins/sendGrid/index.ts | 16 +- .../node-service/src/plugins/stripe/index.ts | 17 +- .../plugins/twilio/did.spec/animations.json | 686 ++++++++++ .../src/plugins/twilio/did.spec/audios.json | 228 ++++ .../src/plugins/twilio/did.spec/clips.json | 795 +++++++++++ .../src/plugins/twilio/did.spec/credits.json | 162 +++ .../src/plugins/twilio/did.spec/images.json | 247 ++++ .../src/plugins/twilio/did.spec/settings.json | 130 ++ .../src/plugins/twilio/did.spec/talks.json | 1159 +++++++++++++++++ .../node-service/src/plugins/twilio/index.ts | 56 +- .../src/plugins/woocommerce/index.ts | 16 +- 28 files changed, 3578 insertions(+), 266 deletions(-) create mode 100644 server/node-service/src/plugins/twilio/did.spec/animations.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/audios.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/clips.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/credits.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/images.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/settings.json create mode 100644 server/node-service/src/plugins/twilio/did.spec/talks.json diff --git a/server/node-service/src/common/util.ts b/server/node-service/src/common/util.ts index 316a850f0..df3760fe6 100644 --- a/server/node-service/src/common/util.ts +++ b/server/node-service/src/common/util.ts @@ -1,5 +1,9 @@ import yaml from "yaml"; import fs from "fs"; +import { MultiOpenApiSpecItem } from "../plugins/openApi/parse"; +import path from "path"; +import { appendTags } from "../plugins/openApi/util"; +import _ from "lodash"; export function kvToRecord( kvs: { key: string; value: string }[], @@ -85,3 +89,36 @@ export function safeJsonStringify(data: any) { return null; } } + +export function specsToOptions(specs: any) { + return Object.keys(specs).map(k => ({value: k, label: k})); +} + +function genTagFromFileName(name: string) { + const fileName = name.replace(/\.yaml|twilio_|\.json/g, ""); + const parts = fileName.split("_"); + return parts.reduce((a, b) => { + if (/v\d+/.test(b)) { + return `${a}(${b})`; + } + return a + _.upperFirst(b); + }, ""); +} + +export function dirToSpecList(specDir: string) { + const specList: MultiOpenApiSpecItem[] = []; + + const start = performance.now(); + const specFiles = fs.readdirSync(specDir); + specFiles.forEach((specFile) => { + const spec = readYaml(path.join(specDir, specFile)); + const tag = genTagFromFileName(specFile); + appendTags(spec, tag); + specList.push({ + id: tag, + spec, + }); + }); + logger.info("spec list loaded %s, duration: %d ms",specDir, performance.now() - start); + return specList; +} \ No newline at end of file diff --git a/server/node-service/src/plugins/asana/index.ts b/server/node-service/src/plugins/asana/index.ts index 7677bf505..1c1fd5774 100644 --- a/server/node-service/src/plugins/asana/index.ts +++ b/server/node-service/src/plugins/asana/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -8,7 +8,10 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./asana.spec.yaml")); - +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -30,16 +33,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ] } as const; diff --git a/server/node-service/src/plugins/circleCi/index.ts b/server/node-service/src/plugins/circleCi/index.ts index 501f34783..873f9022b 100644 --- a/server/node-service/src/plugins/circleCi/index.ts +++ b/server/node-service/src/plugins/circleCi/index.ts @@ -5,6 +5,11 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./circleCi.spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -22,16 +27,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/cloudinary/index.ts b/server/node-service/src/plugins/cloudinary/index.ts index 1055e1150..65f7ee403 100644 --- a/server/node-service/src/plugins/cloudinary/index.ts +++ b/server/node-service/src/plugins/cloudinary/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPI } from "openapi-types"; @@ -14,7 +14,12 @@ const specList = [ { spec: adminApiSpec, id: "admin" }, { spec: uploadApiSpec, id: "upload" }, ]; +const specs = { + "v1.0": specList, + "v2.0": specList, +} +//TODO: Thomas const dataSourceConfig = { type: "dataSource", params: [ @@ -38,16 +43,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/couchdb/index.ts b/server/node-service/src/plugins/couchdb/index.ts index 3004961be..9a41b7c7b 100644 --- a/server/node-service/src/plugins/couchdb/index.ts +++ b/server/node-service/src/plugins/couchdb/index.ts @@ -4,7 +4,11 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./CouchDB-3.1.1-resolved.json"; - +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", params: [ @@ -44,16 +48,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/datadog/index.ts b/server/node-service/src/plugins/datadog/index.ts index 0d82e00c7..7a7cf24c6 100644 --- a/server/node-service/src/plugins/datadog/index.ts +++ b/server/node-service/src/plugins/datadog/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -7,6 +7,10 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./datadog.spec.yaml")); +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -33,16 +37,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/did/index.ts b/server/node-service/src/plugins/did/index.ts index 3ba568d01..5de707e4c 100644 --- a/server/node-service/src/plugins/did/index.ts +++ b/server/node-service/src/plugins/did/index.ts @@ -1,26 +1,14 @@ -import { readYaml } from "../../common/util"; +import { dirToSpecList, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; -import { OpenAPIV3, OpenAPI } from "openapi-types"; -import { QueryConfig, ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; +import { OpenAPI } from "openapi-types"; +import { ConfigToType, DataSourcePlugin, QueryConfig } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; -import { MultiOpenApiSpecItem, parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; -import { appendTags } from "../../plugins/openApi/util"; -import { readdirSync } from "fs"; +import { parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; -const specList: MultiOpenApiSpecItem[] = []; -const specFiles = readdirSync(path.join(__dirname, "./did.spec")); -const start = performance.now(); -specFiles.forEach((specFile) => { - const spec = readYaml(path.join(__dirname, "./did.spec", specFile)); - const tag = _.upperFirst(specFile.replace(".json", "")); - appendTags(spec, tag); - specList.push({ - spec, - id: tag, - }); -}); -logger.info("did spec list loaded, duration: %d ms", performance.now() - start); +const specs = { + "v1.0": dirToSpecList(path.join(__dirname, "./did.spec")), +} const dataSourceConfig = { type: "dataSource", @@ -50,16 +38,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; @@ -80,9 +59,9 @@ const didPlugin: DataSourcePlugin = { icon: "did.svg", category: "api", dataSourceConfig, - queryConfig: async () => { + queryConfig: async (data) => { if (!queryConfig) { - const { actions, categories } = await parseMultiOpenApi(specList, parseOptions); + const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); queryConfig = { type: "query", label: "Action", @@ -102,7 +81,7 @@ const didPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specList); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); }, }; diff --git a/server/node-service/src/plugins/front/index.ts b/server/node-service/src/plugins/front/index.ts index 6af38c992..8dedcb576 100644 --- a/server/node-service/src/plugins/front/index.ts +++ b/server/node-service/src/plugins/front/index.ts @@ -5,6 +5,11 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./front.spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -20,16 +25,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/github/index.ts b/server/node-service/src/plugins/github/index.ts index 614eb3469..8ca3f41d8 100644 --- a/server/node-service/src/plugins/github/index.ts +++ b/server/node-service/src/plugins/github/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -8,6 +8,10 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import SwaggerParser from "@apidevtools/swagger-parser"; const spec = readYaml(path.join(__dirname, "./github.spec.yaml")); +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -33,16 +37,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts index 56b90bf6d..32595da2d 100644 --- a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts +++ b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts @@ -5,6 +5,11 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./huggingFace.spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -31,16 +36,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/jira/index.ts b/server/node-service/src/plugins/jira/index.ts index 46464d828..db1818edd 100644 --- a/server/node-service/src/plugins/jira/index.ts +++ b/server/node-service/src/plugins/jira/index.ts @@ -5,8 +5,14 @@ import { ConfigToType, DataSourcePlugin, QueryConfig } from "lowcoder-sdk/dataSo import path from "path"; import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; +import { specsToOptions } from "../../common/util"; const specJson = readFileSync(path.join(__dirname, "./jira.spec.json")).toString(); +const specs = { + "v1.0": specJson, + "v2.0": specJson, +} +//TODO: Thomas const dataSourceConfig = { type: "dataSource", @@ -42,16 +48,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/lowcoder/index.ts b/server/node-service/src/plugins/lowcoder/index.ts index 5800dee68..a2204e71f 100644 --- a/server/node-service/src/plugins/lowcoder/index.ts +++ b/server/node-service/src/plugins/lowcoder/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -7,6 +7,10 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from './lowcoder.spec.json'; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -37,16 +41,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ] } as const; diff --git a/server/node-service/src/plugins/n8n/index.ts b/server/node-service/src/plugins/n8n/index.ts index dcad50827..812048fbc 100644 --- a/server/node-service/src/plugins/n8n/index.ts +++ b/server/node-service/src/plugins/n8n/index.ts @@ -4,6 +4,11 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} export function prepareServerUrl(url: string) { if (/\/api\/v[12]$/.test(url)) { @@ -41,16 +46,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/notion/index.ts b/server/node-service/src/plugins/notion/index.ts index f616431d7..85c9e8c31 100644 --- a/server/node-service/src/plugins/notion/index.ts +++ b/server/node-service/src/plugins/notion/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -7,6 +7,10 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./notion.spec.yaml")); +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -30,16 +34,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/oneSignal/index.ts b/server/node-service/src/plugins/oneSignal/index.ts index 38a51c651..17b1def2f 100644 --- a/server/node-service/src/plugins/oneSignal/index.ts +++ b/server/node-service/src/plugins/oneSignal/index.ts @@ -5,6 +5,11 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./oneSignal.spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -29,16 +34,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/openAi/index.ts b/server/node-service/src/plugins/openAi/index.ts index 2d0c3de98..2b2a559a2 100644 --- a/server/node-service/src/plugins/openAi/index.ts +++ b/server/node-service/src/plugins/openAi/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -7,6 +7,10 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./openAi.yaml")); +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -26,16 +30,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/postmanEcho/index.ts b/server/node-service/src/plugins/postmanEcho/index.ts index 49da21d3f..3a0b31f51 100644 --- a/server/node-service/src/plugins/postmanEcho/index.ts +++ b/server/node-service/src/plugins/postmanEcho/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -7,6 +7,10 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from './postmanEcho.spec.json'; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { @@ -18,16 +22,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ] } as const; diff --git a/server/node-service/src/plugins/sendGrid/index.ts b/server/node-service/src/plugins/sendGrid/index.ts index 0cc834ed9..0b8c73bda 100644 --- a/server/node-service/src/plugins/sendGrid/index.ts +++ b/server/node-service/src/plugins/sendGrid/index.ts @@ -5,6 +5,11 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./sendGrid.spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} const dataSourceConfig = { type: "dataSource", @@ -22,16 +27,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/stripe/index.ts b/server/node-service/src/plugins/stripe/index.ts index 67b69f801..3084ed30f 100644 --- a/server/node-service/src/plugins/stripe/index.ts +++ b/server/node-service/src/plugins/stripe/index.ts @@ -1,4 +1,4 @@ -import { readYaml } from "../../common/util"; +import { readYaml, specsToOptions } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -9,6 +9,10 @@ import { readFileSync } from "fs"; import { parse } from "yaml"; const yamlContent = readFileSync(path.join(__dirname, "./stripe.spec.yaml"), "utf-8"); +const specs = { + "v1.0": yamlContent, + "v2.0": yamlContent, +} const dataSourceConfig = { type: "dataSource", @@ -31,16 +35,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; diff --git a/server/node-service/src/plugins/twilio/did.spec/animations.json b/server/node-service/src/plugins/twilio/did.spec/animations.json new file mode 100644 index 000000000..9ecb43602 --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/animations.json @@ -0,0 +1,686 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "AnimationStatus": { "enum": ["created", "done", "error", "started"], "type": "string" }, + "CreateAnimationResponseDto": { + "properties": { + "id": { "type": "string", "description": "The ID of the animation" }, + "object": { "type": "string", "description": "An identifier of this animation" }, + "created_by": { + "type": "string", + "description": "The user id of the user that created the animation" + }, + "created_at": { + "type": "string", + "description": "Animation creation time as iso-8601 string" + }, + "status": { + "$ref": "#/components/schemas/AnimationStatus", + "description": "The status of the animation" + } + }, + "required": ["id", "object", "created_by", "created_at", "status"], + "type": "object", + "additionalProperties": true + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": true + }, + "RemoteImageUrl": { + "type": "string", + "example": "https://path.to.directory/image.jpg", + "pattern": "(https|s3):.*\\.(?:jpg|jpeg|tiff|png|bmp|JPG|JPEG|TIFF|PNG|BMP)" + }, + "DriverUrl": { "type": "string", "pattern": "(https|s3|bank):\\/\\/.+" }, + "RemoteUrl": { + "type": "string", + "example": "https://path.to.directory/movie.mp4", + "pattern": "(https|s3):\\/\\/.+" + }, + "OverlapKind": { "enum": ["NO", "PARTIAL", "YES", "UNKNOWN"], "type": "string" }, + "Rect": { + "properties": { + "top": { "type": "number", "format": "double" }, + "left": { "type": "number", "format": "double" }, + "bottom": { "type": "number", "format": "double" }, + "right": { "type": "number", "format": "double" } + }, + "required": ["top", "left", "bottom", "right"], + "type": "object", + "additionalProperties": true + }, + "FaceSquareDto": { + "properties": { + "size": { + "type": "integer", + "format": "int32", + "description": "Size of the square side", + "minimum": 0 + }, + "top_left": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "Top left location of the face in the frame - can be negative", + "minItems": 2, + "maxItems": 2 + }, + "overlap": { "$ref": "#/components/schemas/OverlapKind" }, + "face_id": { "type": "string" }, + "detect_confidence": { "type": "number", "format": "double" }, + "detection": { "$ref": "#/components/schemas/Rect" } + }, + "required": ["size", "top_left"], + "type": "object", + "additionalProperties": true + }, + "SecuredUrl": { "type": "string", "pattern": "^(?:https):\\/\\/[\\S]+$" }, + "Logo": { + "properties": { + "url": { + "type": "string", + "description": "https url to an ARGB jpg/png image, a default logo is used otherwise", + "pattern": "((https|s3):\\/\\/.+)" + }, + "position": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "position of the logo in pixels from the top left corner (w,h) negative values are subtracted from last pixel", + "example": [0, 500], + "minItems": 2, + "maxItems": 2 + } + }, + "required": ["url", "position"], + "type": "object", + "additionalProperties": true + }, + "LogoDto": { "anyOf": [{ "$ref": "#/components/schemas/Logo" }, { "type": "boolean" }] }, + "VideoPath": { + "type": "string", + "example": "https://path.to.directory/movie.mp4", + "pattern": "(https|s3):.*\\.(?:mp4|mov|mpeg)" + }, + "ResultFormat": { "type": "string", "enum": ["mp4", "gif", "mov"] }, + "AnimateConfigDto": { + "properties": { + "logo": { "$ref": "#/components/schemas/LogoDto" }, + "overlay": { + "$ref": "#/components/schemas/VideoPath", + "description": "URL to overlay video to add on the animated result" + }, + "stitch": { + "type": "boolean", + "description": "stitch back the animated result to the original image" + }, + "max_animated_faces": { + "type": "number", + "format": "double", + "description": "the amount of faces to animate when stitch: true. Defaults to 5", + "minimum": 1, + "maximum": 5 + }, + "result_format": { + "$ref": "#/components/schemas/ResultFormat", + "description": "the file format of the animated video result" + } + }, + "type": "object", + "additionalProperties": true + }, + "UserData": { + "type": "string", + "minLength": 1, + "maxLength": 500, + "pattern": "^(?!\\s*$).+$" + }, + "CreateAnimationDto": { + "properties": { + "source_url": { + "$ref": "#/components/schemas/RemoteImageUrl", + "description": "The URL of the source image to be animated by the driver video. Image type of jpg|jpeg|tiff|png|bmp", + "example": "https://path.to/image.jpg" + }, + "driver_url": { + "$ref": "#/components/schemas/DriverUrl", + "description": "The URL of the driver video to drive the animation, if not provided a driver video will be selected for you from the predefined DriversBank", + "example": "bank://nostalgia/" + }, + "result_url": { + "$ref": "#/components/schemas/RemoteUrl", + "description": "The URL of the animation video, if not provided use default destination\nSupports S3 Signed URLs", + "example": "https://path.to.directory/movie.mp4" + }, + "face": { + "$ref": "#/components/schemas/FaceSquareDto", + "description": "the face to animate - otherwise detects the dominant face", + "example": { "top_left": [0, 0], "size": 512 } + }, + "webhook": { + "$ref": "#/components/schemas/SecuredUrl", + "description": "A webhook URL for sending the payload including animate details. In a case of empty value, the webhook will not be triggered", + "example": "https://host.domain.tld/to/webhook" + }, + "config": { + "$ref": "#/components/schemas/AnimateConfigDto", + "description": "Advanced configuration option" + }, + "user_data": { + "$ref": "#/components/schemas/UserData", + "description": "Non-sensitive custom data that will be added to the animation response and webhook." + } + }, + "required": ["source_url"], + "type": "object", + "additionalProperties": true + }, + "Record_string.any_": { + "properties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "DriverError": { + "properties": { + "kind": { "type": "string", "default": "DriverError" }, + "description": { + "type": "string", + "default": "Driver provided is invalid or cannot be loaded" + } + }, + "type": "object", + "additionalProperties": true + }, + "LogoError": { + "properties": { + "kind": { "type": "string", "default": "LogoError" }, + "description": { + "type": "string", + "default": "Could not load logo image or invalid format or position" + } + }, + "type": "object", + "additionalProperties": true + }, + "SourceError": { + "properties": { + "kind": { "type": "string", "default": "SourceError" }, + "description": { + "type": "string", + "default": "Could not load source image or invalid format" + } + }, + "type": "object", + "additionalProperties": true + }, + "FaceError": { + "properties": { + "kind": { "type": "string", "default": "FaceError" }, + "description": { "type": "string", "default": "face not detected" } + }, + "type": "object", + "additionalProperties": true + }, + "VideoEnhanceError": { + "properties": { + "kind": { "type": "string", "default": "VideoEnhanceError" }, + "description": { + "type": "string", + "default": "Failed to create enhanced video (logo, subsample)" + } + }, + "type": "object", + "additionalProperties": true + }, + "UnknownError": { + "properties": { + "kind": { "type": "string", "default": "UnknownError" }, + "description": { "type": "string", "default": "Unknown internal error" } + }, + "type": "object", + "additionalProperties": true + }, + "AnimationError": { + "anyOf": [ + { "$ref": "#/components/schemas/DriverError" }, + { "$ref": "#/components/schemas/LogoError" }, + { "$ref": "#/components/schemas/SourceError" }, + { "$ref": "#/components/schemas/FaceError" }, + { "$ref": "#/components/schemas/VideoEnhanceError" }, + { "$ref": "#/components/schemas/UnknownError" } + ] + }, + "GetAnimationResponseDto": { + "properties": { + "id": { "type": "string", "description": "Unique identifier for the object" }, + "user_id": { + "type": "string", + "description": "Unique identifier of the user that submitted the animation" + }, + "source_url": { + "type": "string", + "description": "The URL of the source image to be animated by the driver video. Image type of .jpg | .png" + }, + "driver_url": { + "type": "string", + "description": "The URL of the driver video to drive the animation, if not provided a driver video will be selected for you from the predefined DriversBank" + }, + "created_at": { + "type": "string", + "description": "Animation creation time as iso-8601 string" + }, + "created_by": { + "type": "string", + "description": "The user id of the user that created the animation" + }, + "started_at": { + "type": "string", + "description": "Animation start time as iso-8601 string" + }, + "modified_at": { + "type": "string", + "description": "last modified time as iso-8601 string" + }, + "status": { + "$ref": "#/components/schemas/AnimationStatus", + "description": "The status of the animation" + }, + "result_url": { "type": "string", "description": "s3 uri to the resulting video" }, + "metadata": { + "$ref": "#/components/schemas/Record_string.any_", + "description": "metadata that has been collected through the process" + }, + "error": { + "$ref": "#/components/schemas/AnimationError", + "description": "The error that failed the animation" + }, + "webhook": { + "type": "string", + "description": "A webhook URL for sending the payload including animate details. In a case of empty value, the webhook will not be triggered" + }, + "config": { + "$ref": "#/components/schemas/AnimateConfigDto", + "description": "The configuration that used to process the animation" + } + }, + "required": ["id", "user_id", "source_url", "created_at", "modified_at", "status"], + "type": "object", + "additionalProperties": true + }, + "GetAnimationsResponseDto": { + "properties": { + "animations": { + "items": { "$ref": "#/components/schemas/GetAnimationResponseDto" }, + "type": "array" + }, + "token": { "type": "string" } + }, + "required": ["animations"], + "type": "object", + "additionalProperties": true + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "animations", + "version": "1.3.0", + "description": "Animations", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/animations": { + "post": { + "operationId": "Create", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateAnimationResponseDto" }, + "examples": { + "Example 1": { + "value": { + "id": "52907745-7672-470e-a803-a2f8feb52944", + "object": "animation", + "created_at": "2020-09-03T13:56:54.995", + "created_by": "995", + "status": "created" + } + } + } + } + } + }, + "400": { + "description": "BadRequestError | InvalidFileSizeError | InvalidImageResolutionError | ConfigError | InvalidFaceError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid source url" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "403": { + "description": "PermissionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "PermissionError", + "description": "user has no permission for stitch" + } + } + } + } + } + } + }, + "description": "Create an animation", + "summary": "Create an animation", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/CreateAnimationDto" } } + } + } + }, + "get": { + "operationId": "GetMany", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAnimationsResponseDto" } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + } + }, + "description": "Get animations", + "summary": "Get animations", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { + "description": "pagination - the amount of animations to return", + "in": "query", + "name": "limit", + "required": false, + "schema": { "default": 100, "format": "double", "type": "number" } + }, + { + "description": "pagination - the pagination token from the previous response, default = 100", + "in": "query", + "name": "token", + "required": false, + "schema": { "type": "string" } + } + ] + } + }, + "/animations/tasks": { + "post": { + "operationId": "CreateTask", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateAnimationResponseDto" }, + "examples": { + "Example 1": { + "value": { + "id": "52907745-7672-470e-a803-a2f8feb52944", + "object": "animation", + "created_at": "2020-09-03T13:56:54.995", + "created_by": "995", + "status": "created" + } + } + } + } + } + }, + "400": { + "description": "BadRequestError | InvalidFileSizeError | InvalidImageResolutionError | ConfigError | InvalidFaceError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid source url" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "403": { + "description": "PermissionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "PermissionError", + "description": "user has no permission for stitch" + } + } + } + } + } + } + }, + "description": "Create an animation task", + "summary": "Create an animation task", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/CreateAnimationDto" } } + } + } + } + }, + "/animations/{id}": { + "get": { + "operationId": "GetById", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAnimationResponseDto" } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { "value": { "kind": "NotFoundError", "description": "not found" } } + } + } + } + } + }, + "description": "Get a specific animation", + "summary": "Get a specific animation", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + }, + "delete": { + "operationId": "Delete", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetAnimationResponseDto" } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { "value": { "kind": "NotFoundError", "description": "not found" } } + } + } + } + }, + "409": { + "description": "NotReadyError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "NotReadyError", + "description": "animation is in process, try again later" + } + } + } + } + } + } + }, + "description": "Delete a specific animation", + "summary": "Delete a specific animation", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/audios.json b/server/node-service/src/plugins/twilio/did.spec/audios.json new file mode 100644 index 000000000..3acb79451 --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/audios.json @@ -0,0 +1,228 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "Record_string.any_": { + "properties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "UploadAudioResponseDto": { + "properties": { + "url": { + "type": "string", + "description": "The temporary URL of the audio.\nThis URL should be provided when creating an animation via the /animations endpoint." + }, + "id": { + "type": "string", + "description": "A unique identifier for the audio.\nThis identifier should be used when deleting the audio via the /audio/{id} endpoint." + }, + "duration": { + "type": "number", + "format": "double", + "description": "The duration of the audio in seconds" + }, + "moderation_metadata": { + "$ref": "#/components/schemas/Record_string.any_", + "description": "The audio moderation results metadata." + } + }, + "required": ["url"], + "type": "object", + "additionalProperties": false + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": false + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "audios", + "version": "1.1.0", + "description": "Audios", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/audios": { + "post": { + "operationId": "Upload an audio", + "responses": { + "201": { + "description": "The audio has been uploaded successfully", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/UploadAudioResponseDto" }, + "examples": { "Example 1": { "value": { "id": "DE8sPnUCMg7MBcFJisx5Z" } } } + } + } + }, + "400": { + "description": "BadRequestError | InvalidFileSizeError | InvalidAudioDurationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid audio" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "415": { + "description": "UnsupportedMimeTypeError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "UnsupportedMimeTypeError", + "description": "The provided mime type is not supported", + "details": { "received": "image/jpg", "supported": ["audio/*", "video/*"] } + } + } + } + } + } + }, + "451": { + "description": "AudioModerationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AudioModerationError", + "description": "Automatic audio moderation failed - Please try a different audio file" + } + } + } + } + } + } + }, + "description": "Upload an audio file to a temporary storage before creating an animation.\nThe audio is uploaded using `multipart/form-data`; the filename directive is optional and if provided should contain up to 50 valid characters long.\nThe resulting file is stored as a .wav file in a 16kHz sample rate.\n\nValid characters: a-z A-Z 0-9 . _ -\nSupported mime types: \"audio/*, video/*\"\nStorage duration: 24-48H", + "summary": "Upload audio file", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": false, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "audio": { + "type": "string", + "format": "binary", + "description": "The uploaded audio file, the file must not exceed 6MB in size." + }, + "source_url": { "type": "string" }, + "result_url": { + "type": "string", + "description": "A URL to upload the audio to. If provided, the audio will be uploaded to this URL instead of the default bucket. https presigned URL supported. S3 presigned urls should have the putObject permission with content type audio/wav." + } + } + } + } + } + } + } + }, + "/audios/{id}": { + "delete": { + "operationId": "Delete", + "responses": { + "204": { "description": "OK" }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "NotFoundError", "description": "audio not found" } + } + } + } + } + } + }, + "description": "Delete an audio file", + "summary": "Delete an audio file", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { + "description": "The id of the audio file", + "in": "path", + "name": "id", + "required": true, + "schema": { "type": "string" } + } + ] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/clips.json b/server/node-service/src/plugins/twilio/did.spec/clips.json new file mode 100644 index 000000000..0866de0e8 --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/clips.json @@ -0,0 +1,795 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "ClipActorDto": { + "properties": { + "id": { "type": "string", "description": "The id of the actor", "example": "amy" }, + "gender": { + "type": "string", + "description": "The gender of the presenter.\nmale / female / other" + }, + "created_at": { "type": "string", "description": "Creation time as iso-8601 string" }, + "modified_at": { + "type": "string", + "description": "Last modified time as iso-8601 string" + }, + "image_url": { "type": "string", "description": "High resolution image of the actor" }, + "thumbnail_url": { + "type": "string", + "description": "A low resolution image representing the actor" + } + }, + "required": ["id", "gender", "created_at", "modified_at", "image_url", "thumbnail_url"], + "type": "object", + "additionalProperties": true + }, + "GetClipsActorsResponse": { + "properties": { + "actors": { "items": { "$ref": "#/components/schemas/ClipActorDto" }, "type": "array" }, + "token": { "type": "string" } + }, + "required": ["actors"], + "type": "object", + "additionalProperties": true + }, + "ClipDriverDto": { + "properties": { + "presenter_id": { "type": "string", "example": "amy-zjBKSuTooU" }, + "driver_id": { "type": "string", "example": "a5PgMbeGQE" }, + "gender": { + "type": "string", + "description": "The gender of the presenter.\nmale / female / other" + }, + "created_at": { "type": "string", "description": "Creation time as iso-8601 string" }, + "owner_id": { "type": "string", "description": "The owner id of the driver" }, + "modified_at": { + "type": "string", + "description": "Last modified time as iso-8601 string" + }, + "width": { + "type": "number", + "format": "double", + "description": "The video width in pixels" + }, + "height": { + "type": "number", + "format": "double", + "description": "The video height in pixels" + }, + "driver_image_url": { + "type": "string", + "description": "High resolution image of the driver image" + }, + "thumbnail_url": { + "type": "string", + "description": "A low resolution image representing the presenter in the video" + }, + "video_url": { + "type": "string", + "description": "A short video, trimmed from the original driver in high resolution" + }, + "preview_url": { + "type": "string", + "description": "A short gif, trimmed from the original driver in low resolution" + } + }, + "required": [ + "presenter_id", + "driver_id", + "gender", + "created_at", + "owner_id", + "modified_at", + "width", + "height", + "driver_image_url", + "thumbnail_url", + "video_url", + "preview_url" + ], + "type": "object", + "additionalProperties": true + }, + "GetClipsDriversResponse": { + "properties": { + "clips_drivers": { + "items": { "$ref": "#/components/schemas/ClipDriverDto" }, + "type": "array" + }, + "token": { "type": "string" } + }, + "required": ["clips_drivers"], + "type": "object", + "additionalProperties": true + }, + "ClipStatus": { + "enum": ["created", "done", "error", "started", "rejected"], + "type": "string" + }, + "CreateClipResponse": { + "properties": { + "id": { "type": "string", "description": "The ID of the clip" }, + "object": { + "type": "string", + "enum": ["clip"], + "nullable": false, + "description": "An identifier of this clip" + }, + "created_at": { + "type": "string", + "description": "Clip creation time as iso-8601 string" + }, + "status": { + "$ref": "#/components/schemas/ClipStatus", + "description": "The status of the clip" + } + }, + "required": ["id", "object", "created_at", "status"], + "type": "object", + "additionalProperties": true + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": true + }, + "VoiceConfigMicrosoft": { + "properties": { + "style": { + "type": "string", + "description": "The style of the voice.\nAvailable styles change between voices." + }, + "rate": { + "type": "string", + "description": "The speed of the voice.\nThe value is relative to 1, 0.5 being half speed, 2 being twice as fast, etc.\nAnother option is a constant value from x-slow/slow/medium/fast/x-fast.", + "example": "0.5" + }, + "pitch": { + "type": "string", + "description": "The pitch of the voice.\nValue could be an absolute value in Hz (including units), a relative value in Hz or st(semitones)\nor a constant value from x-low/low/medium/high/x-high.", + "example": "+2st" + } + }, + "type": "object", + "additionalProperties": true + }, + "Microsoft_tts_provider": { + "description": "AzureMicrosoft provider details, contains the provider type and requested voice id and style", + "properties": { + "type": { "type": "string", "enum": ["microsoft"], "nullable": false }, + "voice_id": { + "type": "string", + "description": "The voice_id from the list of available voices.\nFor full list of voice_ids: https://d-id.readme.io/reference/microsoft-azure", + "example": "Jenny", + "default": "Jenny" + }, + "voice_config": { + "$ref": "#/components/schemas/VoiceConfigMicrosoft", + "description": "Voice customization options" + } + }, + "required": ["type", "voice_id"], + "type": "object", + "additionalProperties": true + }, + "TextToSpeechProviders": { "$ref": "#/components/schemas/Microsoft_tts_provider" }, + "TextScript": { + "description": "Text script contains an input text to be spoken by the actor", + "properties": { + "type": { + "type": "string", + "enum": ["text"], + "nullable": false, + "description": "The type of the script." + }, + "provider": { + "$ref": "#/components/schemas/Microsoft_tts_provider", + "description": "text-to-speech provider from list of supported providers. default is microsoft tts" + }, + "input": { + "type": "string", + "description": "The input text that will be synthesized to an audio file.\nNote that each provider has its own limitations on the text length.", + "example": "This is an example text", + "maxLength": 40000, + "minLength": 3 + }, + "ssml": { + "type": "boolean", + "description": "Is the text provided in ssml form.", + "default": "false" + } + }, + "required": ["type", "input"], + "type": "object", + "additionalProperties": true + }, + "AudioUrl": { + "type": "string", + "example": "https://path.to/audio.mp3", + "pattern": "^(https|s3):\\/\\/[\\S]+\\.(?:m4a|M4A|flac|FLAC|mp3|MP3|mp4|MP4|wav|WAV)([?#][\\w.\\/=&#%-]+)?$" + }, + "ScriptType": { "type": "string", "enum": ["text", "audio"] }, + "AudioScript": { + "description": "Audio script contains an audio file url to be spoken by the actor", + "properties": { + "type": { + "type": "string", + "enum": ["audio"], + "nullable": false, + "description": "The type of the script." + }, + "audio_url": { + "$ref": "#/components/schemas/AudioUrl", + "description": "The URL of the audio file which will be used by the actor.\nFile size is limit to 15MB." + } + }, + "required": ["type", "audio_url"], + "type": "object", + "additionalProperties": true + }, + "Script": { + "anyOf": [ + { "$ref": "#/components/schemas/TextScript" }, + { "$ref": "#/components/schemas/AudioScript" } + ] + }, + "Logo": { + "properties": { + "url": { + "type": "string", + "description": "https url to an ARGB jpg/png image, a default logo is used otherwise", + "pattern": "((https|s3):\\/\\/.+)" + }, + "position": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "position of the logo in pixels from the top left corner (w,h) negative values are subtracted from last pixel", + "example": [0, 500], + "minItems": 2, + "maxItems": 2 + } + }, + "required": ["url", "position"], + "type": "object", + "additionalProperties": true + }, + "ClipConfig": { + "properties": { + "logo": { "anyOf": [{ "$ref": "#/components/schemas/Logo" }, { "type": "boolean" }] }, + "result_format": { + "type": "string", + "enum": ["mp4", "gif", "mov", "webm"], + "description": "File format of the animated result", + "default": "mp4" + } + }, + "type": "object", + "additionalProperties": true + }, + "CropType": { "type": "string", "enum": ["rectangle"], "nullable": false }, + "RectangleCrop": { + "description": "Custom crop", + "properties": { + "type": { + "type": "string", + "enum": ["rectangle"], + "nullable": false, + "description": "The type of the crop." + }, + "rectangle": { + "properties": { + "bottom": { "type": "number", "format": "double" }, + "right": { "type": "number", "format": "double" }, + "left": { "type": "number", "format": "double" }, + "top": { "type": "number", "format": "double" } + }, + "required": ["bottom", "right", "left", "top"], + "type": "object" + } + }, + "required": ["type", "rectangle"], + "type": "object", + "additionalProperties": true + }, + "Crop": { "$ref": "#/components/schemas/RectangleCrop" }, + "ClipPresenterConfig": { + "properties": { "crop": { "$ref": "#/components/schemas/RectangleCrop" } }, + "type": "object", + "additionalProperties": true + }, + "ClipBackground": { + "properties": { + "color": { + "anyOf": [{ "type": "string" }, { "type": "boolean", "enum": [false] }], + "description": "Background color of the animated result, or false to use transparent background in-case of webm result format.", + "example": "#47ffff", + "pattern": "^#[a-fA-F0-9]{6}$" + } + }, + "type": "object", + "additionalProperties": true + }, + "UserData": { + "type": "string", + "minLength": 1, + "maxLength": 500, + "pattern": "^(?!\\s*$).+$" + }, + "SecuredUrl": { "type": "string", "pattern": "^(?:https):\\/\\/[\\S]+$" }, + "RemoteUrl": { + "type": "string", + "example": "https://path.to.directory/movie.mp4", + "pattern": "(https|s3):\\/\\/.+" + }, + "CreateClipRequest": { + "properties": { + "presenter_id": { + "type": "string", + "description": "a selection from the list or provided driver ids.", + "example": "amy-zjBKSuTooU" + }, + "driver_id": { + "type": "string", + "description": "a selection from the list or provided driver ids.\nIf not provided a driver video will be selected for you from the predefined drivers bank.", + "example": "a5PgMbeGQE", + "default": "a5PgMbeGQE" + }, + "script": { "$ref": "#/components/schemas/Script" }, + "config": { + "$ref": "#/components/schemas/ClipConfig", + "description": "Advanced configuration options." + }, + "created_by": { "type": "string", "description": "The user created the clip." }, + "presenter_config": { + "$ref": "#/components/schemas/ClipPresenterConfig", + "description": "Advanced presenter configuration options." + }, + "background": { + "$ref": "#/components/schemas/ClipBackground", + "description": "Background color of the clip result" + }, + "user_data": { + "$ref": "#/components/schemas/UserData", + "description": "Non-sensitive custom data that will be added to the clip response and webhook." + }, + "name": { "type": "string", "description": "The name of the clip" }, + "webhook": { + "$ref": "#/components/schemas/SecuredUrl", + "description": "A webhook URL for sending the payload including animate details.\nIn a case of empty value, the webhook will not be triggered.", + "example": "https://host.domain.tld/to/webhook" + }, + "result_url": { + "$ref": "#/components/schemas/RemoteUrl", + "description": "The URL of the clip video, if not provided use default destination.", + "example": "https://path.to.directory/" + } + }, + "required": ["presenter_id", "driver_id", "script"], + "type": "object", + "additionalProperties": true + }, + "Record_string.any_": { + "properties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "GetClipResponse": { + "properties": { + "id": { "type": "string", "description": "Unique identifier for the object" }, + "owner_id": { + "type": "string", + "description": "Unique identifier of the owner that submitted the clip" + }, + "audio_url": { + "$ref": "#/components/schemas/SecuredUrl", + "description": "The URL of the audio file which will be used by the actor", + "example": "https://path.to/audio.mp3" + }, + "created_at": { + "type": "string", + "description": "Clip creation time as iso-8601 string" + }, + "created_by": { "type": "string", "description": "The user id that created the clip" }, + "modified_at": { + "type": "string", + "description": "last modified time as iso-8601 string" + }, + "started_at": { "type": "string", "description": "Clip start time as iso-8601 string" }, + "completed_at": { + "type": "string", + "description": "Clip completion time as iso-8601 string" + }, + "config": { + "$ref": "#/components/schemas/ClipConfig", + "description": "The configuration that used to process the clip" + }, + "status": { + "$ref": "#/components/schemas/ClipStatus", + "description": "The status of the clip" + }, + "result_url": { "type": "string", "description": "The result url of the clip" }, + "presenter_id": { + "type": "string", + "description": "The identity of the actor that is used in the clip" + }, + "driver_id": { + "type": "string", + "description": "The identifier of the presenter's acting driver that is used in the clip" + }, + "metadata": { + "$ref": "#/components/schemas/Record_string.any_", + "description": "metadata that has been collected through the process" + }, + "webhook": { + "type": "string", + "description": "A webhook URL for sending the payload including animate details. In a case of empty value, the webhook will not be triggered" + }, + "name": { "type": "string", "description": "The name of the clip" } + }, + "required": ["id", "owner_id", "created_at", "modified_at", "status"], + "type": "object", + "additionalProperties": true + }, + "GetClipsResponse": { + "properties": { + "clips": { "items": { "$ref": "#/components/schemas/GetClipResponse" }, "type": "array" }, + "token": { "type": "string" } + }, + "required": ["clips"], + "type": "object", + "additionalProperties": true + }, + "UpdateClipFields": { + "properties": { "name": { "type": "string" } }, + "type": "object", + "additionalProperties": true + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "clips", + "version": "1.1.0", + "description": "Clips", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/clips/actors": { + "get": { + "operationId": "GetActors", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetClipsActorsResponse" } + } + } + } + }, + "description": "Get clips actors", + "summary": "Get actors list", + "security": [{ "optional": [] }], + "parameters": [ + { + "description": "pagination - the amount of actors to return", + "in": "query", + "name": "limit", + "required": false, + "schema": { "default": 100, "format": "double", "type": "number" } + }, + { + "description": "pagination - the pagination token from the previous response, default = 100", + "in": "query", + "name": "token", + "required": false, + "schema": { "type": "string" } + } + ] + } + }, + "/clips/actors/{id}/drivers": { + "get": { + "operationId": "GetActorDrivers", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/GetClipsDriversResponse" } + } + } + } + }, + "description": "Get clips actor drivers", + "summary": "Get driver list of an actor", + "security": [{ "optional": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }, + { + "description": "pagination - the amount of actors to return", + "in": "query", + "name": "limit", + "required": false, + "schema": { "default": 100, "format": "double", "type": "number" } + }, + { + "description": "pagination - the pagination token from the previous response, default = 100", + "in": "query", + "name": "token", + "required": false, + "schema": { "type": "string" } + } + ] + } + }, + "/clips": { + "post": { + "operationId": "Create", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateClipResponse" }, + "examples": { + "Example 1": { + "value": { + "id": "clp_s4d-SZd2xs", + "object": "clip", + "created_at": "2020-09-03T13:56:54.995", + "status": "created" + } + } + } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid actor url" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "403": { + "description": "PermissionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "PermissionError", + "description": "user has no permission for stitch" + } + } + } + } + } + }, + "451": { + "description": "ImageModerationError | CelebrityRecognizedError | TextModerationError | AudioModerationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "ImageModerationError", + "description": "Automatic content moderation - contact support if you would like to submit for manual review" + } + } + } + } + } + } + }, + "description": "Create a clip", + "summary": "Create a clip", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/CreateClipRequest" } } + } + } + }, + "get": { + "operationId": "GetMany", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetClipsResponse" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + } + }, + "description": "Get clips", + "summary": "Get clips", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { + "description": "pagination - the amount of clips to return", + "in": "query", + "name": "limit", + "required": false, + "schema": { "default": 100, "format": "double", "type": "number" } + }, + { + "description": "pagination - the pagination token from the previous response, default = 100", + "in": "query", + "name": "token", + "required": false, + "schema": { "type": "string" } + } + ] + } + }, + "/clips/{id}": { + "get": { + "operationId": "GetById", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetClipResponse" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { "value": { "kind": "NotFoundError", "description": "not found" } } + } + } + } + } + }, + "description": "Get a specific clip", + "summary": "Get a specific clip", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + }, + "delete": { + "operationId": "Delete", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetClipResponse" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { "value": { "kind": "NotFoundError", "description": "not found" } } + } + } + } + }, + "409": { + "description": "NotReadyError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "NotReadyError", + "description": "clip is in process, try again later" + } + } + } + } + } + } + }, + "description": "Delete a specific clip", + "summary": "Delete a specific clip", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/credits.json b/server/node-service/src/plugins/twilio/did.spec/credits.json new file mode 100644 index 000000000..f997d277d --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/credits.json @@ -0,0 +1,162 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "CreditsItem": { + "properties": { + "owner_id": { "type": "string" }, + "created_at": { "type": "string" }, + "modified_at": { "type": "string" }, + "remaining": { "type": "number", "format": "double" }, + "total": { "type": "number", "format": "double" }, + "expire_at": { "type": "string" }, + "valid_from": { "type": "string" }, + "product_id": { "type": "string" }, + "product_billing_interval": { "type": "string", "enum": ["month", "year"] } + }, + "required": ["owner_id", "created_at", "modified_at", "remaining", "total", "expire_at"], + "type": "object", + "additionalProperties": false + }, + "UserCredits": { + "properties": { + "credits": { "items": { "$ref": "#/components/schemas/CreditsItem" }, "type": "array" }, + "remaining": { "type": "number", "format": "double" }, + "total": { "type": "number", "format": "double" } + }, + "required": ["credits", "remaining", "total"], + "type": "object", + "additionalProperties": false + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": false + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "credits", + "version": "1.1.0", + "description": "information regarding your D-ID API credits", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/credits": { + "get": { + "operationId": "Get", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/UserCredits" }, + "examples": { + "Example 1": { + "value": { + "credits": [ + { + "owner_id": "52907745-7672-470e-a803-a2f8feb52944", + "remaining": 10000, + "total": 10000, + "expire_at": "2022-11-01T08:04:43.587Z" + } + ], + "remaining": 10000, + "total": 10000 + } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "NotFoundError", + "description": "not credits found for user" + } + } + } + } + } + } + }, + "description": "Gets the remaning credits object for the authenticated user", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [] + } + }, + "/credits/all": { + "get": { + "operationId": "GetAll", + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/UserCredits" }, + "examples": { + "Example 1": { + "value": { + "credits": [ + { + "owner_id": "52907745-7672-470e-a803-a2f8feb52944", + "remaining": 10000, + "total": 10000, + "expire_at": "2022-11-01T08:04:43.587Z" + } + ], + "remaining": 10000, + "total": 10000 + } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "NotFoundError", + "description": "not credits found for user" + } + } + } + } + } + } + }, + "description": "Gets the remaning credits object for the authenticated user, including inactive credits", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/images.json b/server/node-service/src/plugins/twilio/did.spec/images.json new file mode 100644 index 000000000..3089fcf95 --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/images.json @@ -0,0 +1,247 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "OverlapKind": { "enum": ["NO", "PARTIAL", "YES", "UNKNOWN"], "type": "string" }, + "Rect": { + "properties": { + "top": { "type": "number", "format": "double" }, + "left": { "type": "number", "format": "double" }, + "bottom": { "type": "number", "format": "double" }, + "right": { "type": "number", "format": "double" } + }, + "required": ["top", "left", "bottom", "right"], + "type": "object", + "additionalProperties": false + }, + "FaceSquare": { + "properties": { + "size": { + "type": "integer", + "format": "int32", + "description": "Size of the square side", + "minimum": 0 + }, + "top_left": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "Top left location of the face in the frame - can be negative", + "minItems": 2, + "maxItems": 2 + }, + "overlap": { "$ref": "#/components/schemas/OverlapKind" }, + "face_id": { "type": "string" }, + "detect_confidence": { "type": "number", "format": "double" }, + "detection": { "$ref": "#/components/schemas/Rect" } + }, + "required": ["size", "top_left"], + "type": "object", + "additionalProperties": false + }, + "UploadImageResponseDto": { + "properties": { + "url": { + "type": "string", + "description": "The temporary URL of the image.\nThis URL should be provided when creating an animation via the /animations endpoint." + }, + "id": { + "type": "string", + "description": "A unique identifier which represents this image operation" + }, + "faces": { "items": { "$ref": "#/components/schemas/FaceSquare" }, "type": "array" } + }, + "required": ["url"], + "type": "object", + "additionalProperties": false + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": false + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "images", + "version": "1.3.0", + "description": "Images", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/images": { + "post": { + "operationId": "Upload an image", + "responses": { + "201": { + "description": "The image has been uploaded successfully", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/UploadImageResponseDto" }, + "examples": { "Example 1": { "value": { "id": "tn8607bms7" } } } + } + } + }, + "400": { + "description": "BadRequestError | InvalidFileSizeError | InvalidImageResolutionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid image" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "415": { + "description": "UnsupportedMimeTypeError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "UnsupportedMimeTypeError", + "description": "The provided mime type is not supported", + "details": { "received": "image/png", "supported": ["image/jpeg"] } + } + } + } + } + } + }, + "451": { + "description": "ImageModerationError | CelebrityRecognizedError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "ImageModerationError", + "description": "Automatic content moderation - contact support if you would like to submit for manual review" + } + } + } + } + } + } + }, + "description": "Upload an image to a temporary storage before creating an animation.\nThe image is uploaded using `multipart/form-data`; the filename directive is optional and if provided should contain up to 50 valid characters long.\n\nValid characters: a-z A-Z 0-9 . _ -\nSupported mime types: image/jpeg,image/png\nStorage duration: 24-48H", + "summary": "Upload image", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": false, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "image": { + "type": "string", + "format": "binary", + "description": "The binary data of the image" + }, + "detect_faces": { "type": "string" }, + "metadata": { "type": "string" }, + "source_url": { "type": "string" }, + "result_url": { + "type": "string", + "description": "A URL to upload the image to. If provided, the image will be uploaded to this URL instead of the default bucket. Should be an https presigned URL. S3 presigned urls should have the putObject permission with content type matching the uploaded image." + } + } + } + } + } + } + } + }, + "/images/{id}": { + "delete": { + "operationId": "Delete", + "responses": { + "204": { "description": "OK" }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "NotFoundError", "description": "image not found" } + } + } + } + } + } + }, + "description": "Delete an image", + "summary": "Delete image", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/settings.json b/server/node-service/src/plugins/twilio/did.spec/settings.json new file mode 100644 index 000000000..664127182 --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/settings.json @@ -0,0 +1,130 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": false + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "settings", + "version": "0.0.1", + "description": "user related settings", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/settings/logo": { + "post": { + "operationId": "UpdateLogo", + "responses": { + "201": { "description": "The image has been uploaded successfully" }, + "400": { + "description": "BadRequestError | InvalidFileSizeError | InvalidImageResolutionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "BadRequestError", "description": "invalid image" } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + }, + "415": { + "description": "The image being uploaded is not supported", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "UnsupportedMimeTypeError", + "description": "The provided mime type is not supported", + "details": { "received": "image/gif" } + } + } + } + } + } + } + }, + "description": "Updates user logo", + "summary": "Updates user logo", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "logo": { "type": "string", "format": "binary" }, + "top": { "type": "string" }, + "left": { "type": "string" } + }, + "required": ["logo", "top", "left"] + } + } + } + } + }, + "delete": { + "operationId": "DeleteLogo", + "responses": { + "204": { "description": "The image has been deleted successfully" }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "AuthorizationError", "description": "user unauthenticated" } + } + } + } + } + } + }, + "description": "Deletes user logo", + "summary": "Deletes user logo", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [] + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/did.spec/talks.json b/server/node-service/src/plugins/twilio/did.spec/talks.json new file mode 100644 index 000000000..e66f73b6e --- /dev/null +++ b/server/node-service/src/plugins/twilio/did.spec/talks.json @@ -0,0 +1,1159 @@ +{ + "components": { + "examples": {}, + "headers": {}, + "parameters": {}, + "requestBodies": {}, + "responses": {}, + "schemas": { + "TalkStatus": { + "enum": ["created", "done", "error", "started", "rejected"], + "type": "string" + }, + "CreateTalkResponseDto": { + "properties": { + "id": { "type": "string", "description": "The ID of the talk" }, + "object": { "type": "string", "description": "An identifier of this talk" }, + "created_by": { + "type": "string", + "description": "The user id of the user that created the talk" + }, + "created_at": { + "type": "string", + "description": "Talk creation time as iso-8601 string" + }, + "status": { + "$ref": "#/components/schemas/TalkStatus", + "description": "The status of the talk" + } + }, + "required": ["id", "object", "created_by", "created_at", "status"], + "type": "object", + "additionalProperties": true + }, + "JsonError": { + "properties": { + "kind": { "type": "string" }, + "description": { "type": "string" }, + "details": {} + }, + "required": ["kind", "description"], + "type": "object", + "additionalProperties": true + }, + "ImagePath": { + "type": "string", + "example": "https://path.to.directory/image.jpg", + "pattern": "(https|s3):.*\\.(?:jpg|jpeg|png|JPG|JPEG|PNG)" + }, + "DriverUrl": { "type": "string", "pattern": "(https|s3|bank):\\/\\/.+" }, + "VoiceConfigMicrosoft": { + "properties": { + "style": { + "type": "string", + "description": "The style of the voice.\nAvailable styles change between voices." + }, + "rate": { + "type": "string", + "description": "The speed of the voice.\nThe value is relative to 1, 0.5 being half speed, 2 being twice as fast, etc.\nAnother option is a constant value from x-slow/slow/medium/fast/x-fast.", + "example": "0.5" + }, + "pitch": { + "type": "string", + "description": "The pitch of the voice.\nValue could be an absolute value in Hz (including units), a relative value in Hz or st(semitones)\nor a constant value from x-low/low/medium/high/x-high.", + "example": "+2st" + } + }, + "type": "object", + "additionalProperties": true + }, + "Microsoft_tts_provider": { + "description": "AzureMicrosoft provider details, contains the provider type and requested voice id and style", + "properties": { + "type": { "type": "string", "enum": ["microsoft"], "nullable": false }, + "voice_id": { + "type": "string", + "description": "The voice_id from the list of available voices.\nFor full list of voice_ids: https://d-id.readme.io/reference/microsoft-azure", + "example": "Jenny", + "default": "Jenny" + }, + "voice_config": { + "$ref": "#/components/schemas/VoiceConfigMicrosoft", + "description": "Voice customization options" + } + }, + "required": ["type", "voice_id"], + "type": "object", + "additionalProperties": true + }, + "VoiceIdsAmazon": { + "type": "string", + "enum": [ + "Amy", + "Aria", + "Ayanda", + "Bianca", + "Brian", + "Camila", + "Emma", + "Gabrielle", + "Ivy", + "Joanna", + "Joey", + "Justin", + "Kendra", + "Kevin", + "Kimberly", + "Lea", + "Lucia", + "Lupe", + "Matthew", + "Olivia", + "Salli", + "Seoyeon", + "Takumi", + "Vicki" + ], + "nullable": false + }, + "Amazon_tts_provider": { + "description": "Amazon provider details, contains the provider type and requested voice id", + "properties": { + "type": { "type": "string", "enum": ["amazon"], "nullable": false }, + "voice_id": { + "$ref": "#/components/schemas/VoiceIdsAmazon", + "description": "The voice_id from the list of available voices.\nFor full list of voice_ids: https://d-id.readme.io/reference/text-to-speech-providers", + "example": "Joanna" + } + }, + "required": ["type", "voice_id"], + "type": "object", + "additionalProperties": true + }, + "TextToSpeechProviders": { + "anyOf": [ + { "$ref": "#/components/schemas/Microsoft_tts_provider" }, + { "$ref": "#/components/schemas/Amazon_tts_provider" } + ] + }, + "TextScript": { + "description": "Text script contains an input text to be spoken by the actor", + "properties": { + "type": { + "type": "string", + "enum": ["text"], + "nullable": false, + "description": "The type of the script." + }, + "provider": { + "$ref": "#/components/schemas/TextToSpeechProviders", + "description": "text-to-speech provider from list of supported providers. default is microsoft tts" + }, + "input": { + "type": "string", + "description": "The input text that will be synthesized to an audio file.\nNote that each provider has its own limitations on the text length.", + "example": "This is an example text", + "maxLength": 40000, + "minLength": 3 + }, + "ssml": { + "type": "boolean", + "description": "Is the text provided in ssml form.", + "default": "false" + } + }, + "required": ["type", "input"], + "type": "object", + "additionalProperties": true + }, + "AudioUrl": { + "type": "string", + "example": "https://path.to/audio.mp3", + "pattern": "^(https|s3):\\/\\/[\\S]+\\.(?:m4a|M4A|flac|FLAC|mp3|MP3|mp4|MP4|wav|WAV)([?#][\\w.\\/=&#%-]+)?$" + }, + "ScriptType": { "type": "string", "enum": ["text", "audio"] }, + "AudioScript": { + "description": "Audio script contains an audio file url to be spoken by the actor", + "properties": { + "type": { + "type": "string", + "enum": ["audio"], + "nullable": false, + "description": "The type of the script." + }, + "audio_url": { + "$ref": "#/components/schemas/AudioUrl", + "description": "The URL of the audio file which will be used by the actor.\nFile size is limit to 15MB." + } + }, + "required": ["type", "audio_url"], + "type": "object", + "additionalProperties": true + }, + "Script": { + "anyOf": [ + { "$ref": "#/components/schemas/TextScript" }, + { "$ref": "#/components/schemas/AudioScript" } + ] + }, + "Logo": { + "properties": { + "url": { + "type": "string", + "description": "https url to an ARGB jpg/png image, a default logo is used otherwise", + "pattern": "((https|s3):\\/\\/.+)" + }, + "position": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "position of the logo in pixels from the top left corner (w,h) negative values are subtracted from last pixel", + "example": [0, 500], + "minItems": 2, + "maxItems": 2 + } + }, + "required": ["url", "position"], + "type": "object", + "additionalProperties": true + }, + "ResultFormat": { "type": "string", "enum": ["mp4", "gif", "mov"] }, + "TalksConfig": { + "properties": { + "logo": { "anyOf": [{ "$ref": "#/components/schemas/Logo" }, { "type": "boolean" }] }, + "stitch": { + "type": "boolean", + "description": "Stitch back the animated result to the original image" + }, + "result_format": { + "$ref": "#/components/schemas/ResultFormat", + "description": "File format of the animated result" + }, + "fluent": { + "type": "boolean", + "description": "Interpolate between the last & first frames of the driver video\nWhen used together with `pad_audio` can create a seamless transition between videos of the same driver", + "default": "false" + }, + "pad_audio": { + "type": "number", + "format": "double", + "description": "Pad the audio with silence at the end (given in seconds)\nWill increase the video duration & the credits it consumes", + "default": "0.0", + "minimum": 0, + "maximum": 60 + } + }, + "type": "object", + "additionalProperties": true + }, + "UserData": { + "type": "string", + "minLength": 1, + "maxLength": 500, + "pattern": "^(?!\\s*$).+$" + }, + "SecuredUrl": { "type": "string", "pattern": "^(?:https):\\/\\/[\\S]+$" }, + "RemoteUrl": { + "type": "string", + "example": "https://path.to.directory/movie.mp4", + "pattern": "(https|s3):\\/\\/.+" + }, + "OverlapKind": { "enum": ["NO", "PARTIAL", "YES", "UNKNOWN"], "type": "string" }, + "Rect": { + "properties": { + "top": { "type": "number", "format": "double" }, + "left": { "type": "number", "format": "double" }, + "bottom": { "type": "number", "format": "double" }, + "right": { "type": "number", "format": "double" } + }, + "required": ["top", "left", "bottom", "right"], + "type": "object", + "additionalProperties": true + }, + "FaceSquareDto": { + "properties": { + "size": { + "type": "integer", + "format": "int32", + "description": "Size of the square side", + "minimum": 0 + }, + "top_left": { + "items": { "type": "integer", "format": "int32" }, + "type": "array", + "description": "Top left location of the face in the frame - can be negative", + "minItems": 2, + "maxItems": 2 + }, + "overlap": { "$ref": "#/components/schemas/OverlapKind" }, + "face_id": { "type": "string" }, + "detect_confidence": { "type": "number", "format": "double" }, + "detection": { "$ref": "#/components/schemas/Rect" } + }, + "required": ["size", "top_left"], + "type": "object", + "additionalProperties": true + }, + "CreateTalkRequest": { + "properties": { + "source_url": { + "$ref": "#/components/schemas/ImagePath", + "description": "The URL of the source image to be animated by the driver video, or a selection from the list of provided\nstudio actors." + }, + "driver_url": { + "$ref": "#/components/schemas/DriverUrl", + "description": "The URL of the driver video to drive the talk, or a selection from the list or provided drivers\nIf not provided a driver video will be selected for you from the predefined drivers bank", + "example": "bank://lively" + }, + "script": { "$ref": "#/components/schemas/Script" }, + "config": { + "$ref": "#/components/schemas/TalksConfig", + "description": "Advanced configuration options" + }, + "user_data": { + "$ref": "#/components/schemas/UserData", + "description": "Non-sensitive custom data that will be added to the talk response and webhook" + }, + "name": { "type": "string", "description": "The name of the talk video" }, + "webhook": { + "$ref": "#/components/schemas/SecuredUrl", + "description": "A webhook URL for sending the payload including animate details\nIn a case of empty value, the webhook will not be triggered", + "example": "https://host.domain.tld/to/webhook" + }, + "result_url": { + "$ref": "#/components/schemas/RemoteUrl", + "description": "The URL of the talk video, if not provided use default destination.", + "example": "https://path.to.directory/" + }, + "face": { + "$ref": "#/components/schemas/FaceSquareDto", + "description": "The face to animate - otherwise detects the face automatically", + "example": { "top_left": [0, 0], "size": 512 } + } + }, + "required": ["source_url", "script"], + "type": "object", + "additionalProperties": true + }, + "Record_string.any_": { + "properties": {}, + "type": "object", + "description": "Construct a type with a set of properties K of type T" + }, + "GetTalkDto": { + "properties": { + "id": { "type": "string", "description": "Unique identifier for the object" }, + "user_id": { + "type": "string", + "description": "Unique identifier of the user that submitted the talk" + }, + "source_url": { + "type": "string", + "description": "The URL of the source image to be animated by the driver video. Image type of .jpg | .png" + }, + "driver_url": { + "type": "string", + "description": "The URL of the driver video to drive the talk, if not provided a driver video will be selected for you from the predefined DriversBank" + }, + "created_at": { + "type": "string", + "description": "Talk creation time as iso-8601 string" + }, + "created_by": { + "type": "string", + "description": "The user id of the user that created the talk" + }, + "audio_url": { + "$ref": "#/components/schemas/SecuredUrl", + "description": "The URL of the audio file which will be used by the actor", + "example": "https://path.to/audio.mp3" + }, + "started_at": { "type": "string", "description": "Talk start time as iso-8601 string" }, + "modified_at": { + "type": "string", + "description": "last modified time as iso-8601 string" + }, + "status": { + "$ref": "#/components/schemas/TalkStatus", + "description": "The status of the talk" + }, + "result_url": { "type": "string", "description": "s3 uri to the resulting video" }, + "metadata": { + "$ref": "#/components/schemas/Record_string.any_", + "description": "metadata that has been collected through the process" + }, + "webhook": { + "type": "string", + "description": "A webhook URL for sending the payload including animate details. In a case of empty value, the webhook will not be triggered" + }, + "config": { + "$ref": "#/components/schemas/TalksConfig", + "description": "The configuration that used to process the talk" + } + }, + "required": ["id", "user_id", "source_url", "created_at", "modified_at", "status"], + "type": "object", + "additionalProperties": true + }, + "GetTalksDto": { + "properties": { + "talks": { "items": { "$ref": "#/components/schemas/GetTalkDto" }, "type": "array" }, + "token": { "type": "string" } + }, + "required": ["talks"], + "type": "object", + "additionalProperties": true + }, + "UpdateTalkFields": { + "properties": { "name": { "type": "string" } }, + "type": "object", + "additionalProperties": true + }, + "Jsep": { + "properties": { + "type": { "type": "string", "enum": ["offer", "answer"] }, + "sdp": { "type": "string" } + }, + "required": ["type", "sdp"], + "type": "object", + "additionalProperties": true + }, + "IceServer": { + "properties": { + "urls": { + "anyOf": [{ "items": { "type": "string" }, "type": "array" }, { "type": "string" }] + }, + "username": { "type": "string" }, + "credential": { "type": "string" } + }, + "required": ["urls"], + "type": "object", + "additionalProperties": true + }, + "CreateStreamResponseDto": { + "properties": { + "session_id": { "type": "string" }, + "streamId": { "type": "string", "description": "Id of the stream", "deprecated": true }, + "id": { "type": "string", "description": "Id of the stream" }, + "jsep": { + "$ref": "#/components/schemas/Jsep", + "description": "Jsep offer object used to create a peer connection" + }, + "iceServers": { + "items": { "$ref": "#/components/schemas/IceServer" }, + "type": "array", + "description": "ICE servers used to create a peer connection", + "deprecated": true + }, + "ice_servers": { + "items": { "$ref": "#/components/schemas/IceServer" }, + "type": "array", + "description": "ICE servers used to create a peer connection" + } + }, + "required": ["streamId", "id", "jsep", "iceServers", "ice_servers"], + "type": "object", + "additionalProperties": true + }, + "IceCandidate": { + "properties": { + "candidate": { "type": "string" }, + "sdpMid": { "type": "string" }, + "sdpMLineIndex": { "type": "number", "format": "double" } + }, + "required": ["candidate", "sdpMid", "sdpMLineIndex"], + "type": "object", + "additionalProperties": true + }, + "Pick_TalksConfig.Exclude_keyofTalksConfig.logo__": { + "properties": { + "stitch": { + "type": "boolean", + "description": "Stitch back the animated result to the original image" + }, + "result_format": { + "$ref": "#/components/schemas/ResultFormat", + "description": "File format of the animated result" + }, + "fluent": { + "type": "boolean", + "description": "Interpolate between the last & first frames of the driver video\nWhen used together with `pad_audio` can create a seamless transition between videos of the same driver", + "default": "false" + }, + "pad_audio": { + "type": "number", + "format": "double", + "description": "Pad the audio with silence at the end (given in seconds)\nWill increase the video duration & the credits it consumes", + "default": "0.0", + "minimum": 0, + "maximum": 60 + } + }, + "type": "object", + "description": "From T, pick a set of properties whose keys are in the union K" + }, + "Omit_TalksConfig.logo_": { + "$ref": "#/components/schemas/Pick_TalksConfig.Exclude_keyofTalksConfig.logo__", + "description": "Construct a type with the properties of T except for those in type K." + }, + "CreateTalkStreamRequest": { + "properties": { + "session_id": { "type": "string" }, + "driver_url": { + "$ref": "#/components/schemas/DriverUrl", + "description": "The URL of the driver video to drive the talk, or a selection from the list or provided drivers.\nIf not provided a driver video will be selected for you from the predefined drivers bank.", + "example": "bank://lively" + }, + "script": { "$ref": "#/components/schemas/Script" }, + "config": { + "$ref": "#/components/schemas/Omit_TalksConfig.logo_", + "description": "Advanced configuration options." + }, + "user_data": { + "$ref": "#/components/schemas/UserData", + "description": "Non-sensitive custom data that will be added to the talk response and webhook." + }, + "name": { "type": "string", "description": "The name of the talk video" } + }, + "required": ["script"], + "type": "object", + "additionalProperties": true + } + }, + "securitySchemes": { + "basic": { "type": "http", "scheme": "basic" }, + "bearer": { "type": "http", "scheme": "bearer" } + } + }, + "info": { + "title": "talks", + "version": "1.1.0", + "description": "Talks", + "license": { "name": "ISC" }, + "contact": { "name": "D-ID" } + }, + "openapi": "3.0.0", + "paths": { + "/talks": { + "post": { + "operationId": "Create", + "responses": { + "201": { + "description": "Created", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateTalkResponseDto" }, + "examples": { + "Example 1": { + "value": { + "id": "tlk_AbCs-xcz", + "object": "talk", + "created_at": "2020-09-03T13:56:54.995", + "created_by": "123", + "status": "created" + } + } + } + } + } + }, + "400": { + "description": "", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "BadRequestError", + "description": "invalid actor url" + } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + }, + "402": { + "description": "InsufficientCreditsError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "InsufficientCreditsError", + "description": "not enough credits" + } + } + } + } + } + }, + "403": { + "description": "PermissionError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "PermissionError", + "description": "user has no permission for stitch" + } + } + } + } + } + }, + "451": { + "description": "ImageModerationError | CelebrityRecognizedError | TextModerationError | AudioModerationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "ImageModerationError", + "description": "Automatic content moderation - contact support if you would like to submit for manual review" + } + } + } + } + } + } + }, + "description": "Create a talk", + "summary": "Create a talk", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/CreateTalkRequest" } } + } + } + }, + "get": { + "operationId": "GetMany", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetTalksDto" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "description": "Get talks", + "summary": "Get talks", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { + "description": "pagination - the amount of talks to return", + "in": "query", + "name": "limit", + "required": false, + "schema": { "default": 100, "format": "double", "type": "number" } + }, + { + "description": "pagination - the pagination token from the previous response, default = 100", + "in": "query", + "name": "token", + "required": false, + "schema": { "type": "string" } + } + ] + } + }, + "/talks/{id}": { + "get": { + "operationId": "GetById", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetTalkDto" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "NotFoundError", "description": "not found" } + } + } + } + } + } + }, + "description": "Get a specific talk", + "summary": "Get a specific talk", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + }, + "delete": { + "operationId": "Delete", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { "schema": { "$ref": "#/components/schemas/GetTalkDto" } } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + }, + "404": { + "description": "NotFoundError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { "kind": "NotFoundError", "description": "not found" } + } + } + } + } + }, + "409": { + "description": "NotReadyError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "NotReadyError", + "description": "talk is in process, try again later" + } + } + } + } + } + } + }, + "description": "Delete a specific talk", + "summary": "Delete a specific talk", + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } } + ] + } + }, + "/talks/streams": { + "post": { + "operationId": "CreateStream", + "responses": { + "201": { + "description": "Created stream", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateStreamResponseDto" } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "face": { "$ref": "#/components/schemas/FaceSquareDto" }, + "source_url": { "type": "string" } + }, + "required": ["source_url"], + "type": "object" + } + } + } + } + } + }, + "/talks/streams/{id}/sdp": { + "post": { + "operationId": "StartConnection", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { "status": { "type": "string" } }, + "required": ["status"], + "type": "object" + } + } + } + }, + "400": { + "description": "MissingSessionCookie", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "MissingSessionCookie", + "description": "missing session cookie" + } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }, + { + "in": "header", + "name": "cookie", + "required": false, + "schema": { "type": "string" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { + "session_id": { "type": "string" }, + "answer": { "$ref": "#/components/schemas/Jsep" } + }, + "required": ["answer"], + "type": "object" + } + } + } + } + } + }, + "/talks/streams/{id}/ice": { + "post": { + "operationId": "AddIceCandidate", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { "status": { "type": "string" } }, + "required": ["status"], + "type": "object" + } + } + } + }, + "400": { + "description": "MissingSessionCookie", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "MissingSessionCookie", + "description": "missing session cookie" + } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }, + { + "in": "header", + "name": "cookie", + "required": false, + "schema": { "type": "string" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "allOf": [ + { + "anyOf": [ + { "$ref": "#/components/schemas/IceCandidate" }, + { "properties": {}, "type": "object" } + ] + }, + { + "properties": { "session_id": { "type": "string" } }, + "type": "object" + } + ] + } + } + } + } + } + }, + "/talks/streams/{id}": { + "post": { + "operationId": "CreateTalkStream", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { + "duration": { "type": "number", "format": "double" }, + "session_id": { "type": "string" }, + "status": { "type": "string" } + }, + "required": ["duration", "session_id", "status"], + "type": "object" + } + } + } + }, + "400": { + "description": "MissingSessionCookie", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "MissingSessionCookie", + "description": "missing session cookie" + } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }, + { + "in": "header", + "name": "cookie", + "required": false, + "schema": { "type": "string" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/CreateTalkStreamRequest" } + } + } + } + }, + "delete": { + "operationId": "DeleteStream", + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "properties": { "status": { "type": "string" } }, + "required": ["status"], + "type": "object" + } + } + } + }, + "400": { + "description": "MissingSessionCookie", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "MissingSessionCookie", + "description": "missing session cookie" + } + } + } + } + } + }, + "401": { + "description": "AuthorizationError", + "content": { + "application/json": { + "schema": { "$ref": "#/components/schemas/JsonError" }, + "examples": { + "Example 1": { + "value": { + "kind": "AuthorizationError", + "description": "user unauthenticated" + } + } + } + } + } + } + }, + "security": [{ "basic": [] }, { "bearer": [] }], + "parameters": [ + { "in": "path", "name": "id", "required": true, "schema": { "type": "string" } }, + { + "in": "header", + "name": "cookie", + "required": false, + "schema": { "type": "string" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "properties": { "session_id": { "type": "string" } }, + "type": "object" + } + } + } + } + } + } + }, + "servers": [{ "url": "https://api.d-id.com/" }] +} diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index e8525d4f8..797e3e498 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -1,38 +1,16 @@ -import { readYaml } from "../../common/util"; +import { dirToSpecList, specsToOptions } from "../../common/util"; import _ from "lodash"; -import fs from "fs"; import path from "path"; import { OpenAPI } from "openapi-types"; import { ConfigToType, DataSourcePlugin, QueryConfig } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; -import { MultiOpenApiSpecItem, parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; -import { appendTags } from "../openApi/util"; +import { parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; -function genTagFromFileName(name: string) { - const fileName = name.replace(/\.yaml|twilio_/g, ""); - const parts = fileName.split("_"); - return parts.reduce((a, b) => { - if (/v\d+/.test(b)) { - return `${a}(${b})`; - } - return a + _.upperFirst(b); - }, ""); -} - -const specList: MultiOpenApiSpecItem[] = []; -const start = performance.now(); -const specFiles = fs.readdirSync(path.join(__dirname, "./twilio.spec")); -specFiles.forEach((specFile) => { - const spec = readYaml(path.join(__dirname, "./twilio.spec", specFile)); - const tag = genTagFromFileName(specFile); - appendTags(spec, tag); - specList.push({ - id: tag, - spec, - }); -}); -logger.info("twilio spec list loaded, duration: %d ms", performance.now() - start); +const specs = { + "twilio--V": dirToSpecList(path.join(__dirname, "./twilio.spec")), + "did--V": dirToSpecList(path.join(__dirname, "./did.spec")), +} const dataSourceConfig = { type: "dataSource", @@ -55,16 +33,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; @@ -86,9 +55,10 @@ const twilioPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, - queryConfig: async () => { - if (!queryConfig) { - const { actions, categories } = await parseMultiOpenApi(specList, parseOptions); + queryConfig: async (data) => { + console.log(data.specVersion); + // if (!queryConfig) { + const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); queryConfig = { type: "query", label: "Action", @@ -98,7 +68,7 @@ const twilioPlugin: DataSourcePlugin = { }, actions, }; - } + // } return queryConfig; }, @@ -109,7 +79,7 @@ const twilioPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specList); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); }, }; diff --git a/server/node-service/src/plugins/woocommerce/index.ts b/server/node-service/src/plugins/woocommerce/index.ts index b1e9d46e1..694ec108b 100644 --- a/server/node-service/src/plugins/woocommerce/index.ts +++ b/server/node-service/src/plugins/woocommerce/index.ts @@ -5,6 +5,11 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./woocommerce-spec.json"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": spec, + "v2.0": spec, +} export function prepareServerUrl(url: string) { if (/\/wc\/v[12]$/.test(url)) { @@ -51,16 +56,7 @@ const dataSourceConfig = { type: "select", tooltip: "Version of the spec file.", placeholder: "v1.0", - options: [ - { - value: "v1.0", - label: "v1.0", - }, - { - value: "v2.0", - label: "v2.0", - } - ] + options: specsToOptions(specs) }, ], } as const; From 733591c2daf0c2b461222f3c2440ce317f3e5c70 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 11:40:25 -0400 Subject: [PATCH 03/19] Add s3 spec version --- .../node-service/src/plugins/s3/dataSourceConfig.ts | 11 ++++++++++- server/node-service/src/plugins/s3/index.ts | 13 +++++++++++-- server/node-service/src/plugins/s3/queryConfig.ts | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/server/node-service/src/plugins/s3/dataSourceConfig.ts b/server/node-service/src/plugins/s3/dataSourceConfig.ts index 8e9e7de61..d408a9fd9 100644 --- a/server/node-service/src/plugins/s3/dataSourceConfig.ts +++ b/server/node-service/src/plugins/s3/dataSourceConfig.ts @@ -1,7 +1,8 @@ import { ConfigToType } from "lowcoder-sdk/dataSource"; import { S3I18nTranslator } from "./i18n"; +import { specsToOptions } from "../../common/util"; -const getDataSourceConfig = (i18n: S3I18nTranslator) => { +const getDataSourceConfig = (i18n: S3I18nTranslator, specs: any) => { const dataSourceConfig = { type: "dataSource", params: [ @@ -30,6 +31,14 @@ const getDataSourceConfig = (i18n: S3I18nTranslator) => { label: i18n.trans("region"), defaultValue: "us-west-1", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: specsToOptions(specs) + }, ], } as const; return dataSourceConfig; diff --git a/server/node-service/src/plugins/s3/index.ts b/server/node-service/src/plugins/s3/index.ts index 561a9716b..b145cac42 100644 --- a/server/node-service/src/plugins/s3/index.ts +++ b/server/node-service/src/plugins/s3/index.ts @@ -8,6 +8,13 @@ import run, { validateDataSourceConfig } from "./run"; import getI18nTranslator from "./i18n"; import getDataSourceConfig from "./dataSourceConfig"; import getQueryConfig from "./queryConfig"; +import { dirToSpecList } from "../../common/util"; +import path from "path"; + + +const specs = { + "V1.0": "Nothing to do", +} const s3Plugin: DataSourcePluginFactory = (context: PluginContext) => { const i18n = getI18nTranslator(context.languages); @@ -17,8 +24,10 @@ const s3Plugin: DataSourcePluginFactory = (context: PluginContext) => { icon: "s3.svg", description: i18n.trans("description"), category: "api", - dataSourceConfig: getDataSourceConfig(i18n), - queryConfig: getQueryConfig(i18n), + dataSourceConfig: getDataSourceConfig(i18n, specs), + queryConfig: async (data) => { + return getQueryConfig(i18n, data.specVersion as keyof typeof specs) + }, validateDataSourceConfig: async (dataSourceConfig: DataSourceDataType) => { return validateDataSourceConfig(dataSourceConfig); diff --git a/server/node-service/src/plugins/s3/queryConfig.ts b/server/node-service/src/plugins/s3/queryConfig.ts index a4105db0f..12559bca9 100644 --- a/server/node-service/src/plugins/s3/queryConfig.ts +++ b/server/node-service/src/plugins/s3/queryConfig.ts @@ -1,7 +1,7 @@ import { ActionParamConfig, Config, ConfigToType, QueryConfig } from "lowcoder-sdk/dataSource"; import { S3I18nTranslator } from "./i18n"; -function getQueryConfig(i18n: S3I18nTranslator) { +function getQueryConfig(i18n: S3I18nTranslator, version: string) { const bucketActionParam = { key: "bucket", type: "textInput", From a3fc99471da010c2dfc52972a7828ee988b6393d Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:30:45 -0400 Subject: [PATCH 04/19] Add dynamo spec version --- .../src/plugins/dynamodb/dataSourceConfig.ts | 13 ++++++++++++- server/node-service/src/plugins/dynamodb/index.ts | 8 +++++++- server/node-service/src/plugins/n8n/index.ts | 7 +++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/server/node-service/src/plugins/dynamodb/dataSourceConfig.ts b/server/node-service/src/plugins/dynamodb/dataSourceConfig.ts index 999cf14ea..89d03b7ce 100644 --- a/server/node-service/src/plugins/dynamodb/dataSourceConfig.ts +++ b/server/node-service/src/plugins/dynamodb/dataSourceConfig.ts @@ -1,5 +1,8 @@ import { ConfigToType } from "lowcoder-sdk/dataSource"; - +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": "" +} const dataSourceConfig = { type: "dataSource", params: [ @@ -27,6 +30,14 @@ const dataSourceConfig = { label: "Region", defaultValue: "us-west-1", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: specsToOptions(specs) + }, ], } as const; diff --git a/server/node-service/src/plugins/dynamodb/index.ts b/server/node-service/src/plugins/dynamodb/index.ts index 03131239f..d3ee1edca 100644 --- a/server/node-service/src/plugins/dynamodb/index.ts +++ b/server/node-service/src/plugins/dynamodb/index.ts @@ -3,13 +3,19 @@ import dataSourceConfig, { DataSourceDataType } from "./dataSourceConfig"; import queryConfig, { ActionDataType } from "./queryConfig"; import { runDynamoDbQuery } from "./run"; +const specs = { + "v1.0": queryConfig +} + const dynamoDBPlugin: DataSourcePlugin = { id: "dynamodb", name: "DynamoDB", category: "database", icon: "dynamodb.svg", dataSourceConfig, - queryConfig, + queryConfig: async (data) => { + return specs[data.specVersion as keyof typeof specs] + }, run: async function (actionData, dataSourceConfig): Promise { return runDynamoDbQuery(actionData, dataSourceConfig); }, diff --git a/server/node-service/src/plugins/n8n/index.ts b/server/node-service/src/plugins/n8n/index.ts index 812048fbc..26876dd1a 100644 --- a/server/node-service/src/plugins/n8n/index.ts +++ b/server/node-service/src/plugins/n8n/index.ts @@ -7,7 +7,6 @@ import spec from "./spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } export function prepareServerUrl(url: string) { @@ -70,8 +69,8 @@ const n8nPlugin: DataSourcePlugin = { icon: "n8n.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -92,7 +91,7 @@ const n8nPlugin: DataSourcePlugin = { }, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; From f4a35920b6838b32a86ba9d930478242ed01c156 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:33:08 -0400 Subject: [PATCH 05/19] Add firebase spec version --- .../src/plugins/firebase/dataSourceConfig.ts | 12 ++++++++++++ server/node-service/src/plugins/firebase/index.ts | 8 +++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/server/node-service/src/plugins/firebase/dataSourceConfig.ts b/server/node-service/src/plugins/firebase/dataSourceConfig.ts index 84966c8c9..86fe2cb5d 100644 --- a/server/node-service/src/plugins/firebase/dataSourceConfig.ts +++ b/server/node-service/src/plugins/firebase/dataSourceConfig.ts @@ -1,5 +1,9 @@ import { ConfigToType } from "lowcoder-sdk/dataSource"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": "" +} const dataSourceConfig = { type: "dataSource", params: [ @@ -23,6 +27,14 @@ const dataSourceConfig = { tooltip: "The [document](https://firebase.google.com/docs/admin/setup) on how to obtain the private key.", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: specsToOptions(specs) + }, ], } as const; diff --git a/server/node-service/src/plugins/firebase/index.ts b/server/node-service/src/plugins/firebase/index.ts index 9648a83a3..d7d03dc75 100644 --- a/server/node-service/src/plugins/firebase/index.ts +++ b/server/node-service/src/plugins/firebase/index.ts @@ -3,12 +3,18 @@ import dataSourceConfig, { DataSourceDataType } from "./dataSourceConfig"; import queryConfig, { ActionDataType } from "./queryConfig"; import { runFirebasePlugin } from "./run"; +const specs = { + "v1.0": queryConfig +} + const firebasePlugin: DataSourcePlugin = { id: "firebase", icon: "firebase.svg", name: "Firebase", category: "api", - queryConfig, + queryConfig: async (data) => { + return specs[data.specVersion as keyof typeof specs] + }, dataSourceConfig, run: function (actionData, dataSourceConfig): Promise { return runFirebasePlugin(actionData, dataSourceConfig); From 7059b79b58437f1ccb289395128bfb319e5b8f56 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:34:48 -0400 Subject: [PATCH 06/19] Add couchdb spec version --- server/node-service/src/plugins/couchdb/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/node-service/src/plugins/couchdb/index.ts b/server/node-service/src/plugins/couchdb/index.ts index 9a41b7c7b..ce240decc 100644 --- a/server/node-service/src/plugins/couchdb/index.ts +++ b/server/node-service/src/plugins/couchdb/index.ts @@ -7,7 +7,6 @@ import spec from "./CouchDB-3.1.1-resolved.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { type: "dataSource", @@ -71,8 +70,8 @@ const couchdbPlugin: DataSourcePlugin = { icon: "couchdb.svg", category: "database", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -91,7 +90,7 @@ const couchdbPlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV2.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV2.Document); }, }; From 10d5859fb89f9857b1b14c32fa404e93ccea1f9c Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:36:24 -0400 Subject: [PATCH 07/19] Add woocommerce spec version --- server/node-service/src/plugins/woocommerce/index.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/node-service/src/plugins/woocommerce/index.ts b/server/node-service/src/plugins/woocommerce/index.ts index 694ec108b..b98ca62b8 100644 --- a/server/node-service/src/plugins/woocommerce/index.ts +++ b/server/node-service/src/plugins/woocommerce/index.ts @@ -78,8 +78,8 @@ const wooCommercePlugin: DataSourcePlugin = { icon: "woocommerce.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -98,7 +98,7 @@ const wooCommercePlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV2.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV2.Document); }, }; From ceeec59e613e0b69bd125f9b707c8e2032e033f5 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:38:53 -0400 Subject: [PATCH 08/19] Add openai spec version --- server/node-service/src/plugins/openAi/index.ts | 7 +++---- server/node-service/src/plugins/woocommerce/index.ts | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/server/node-service/src/plugins/openAi/index.ts b/server/node-service/src/plugins/openAi/index.ts index 2b2a559a2..a192189f6 100644 --- a/server/node-service/src/plugins/openAi/index.ts +++ b/server/node-service/src/plugins/openAi/index.ts @@ -9,7 +9,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./openAi.yaml")); const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -49,8 +48,8 @@ const openAiPlugin: DataSourcePlugin = { icon: "openAI.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); return { type: "query", label: "Action", @@ -68,7 +67,7 @@ const openAiPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/woocommerce/index.ts b/server/node-service/src/plugins/woocommerce/index.ts index b98ca62b8..00b459228 100644 --- a/server/node-service/src/plugins/woocommerce/index.ts +++ b/server/node-service/src/plugins/woocommerce/index.ts @@ -8,7 +8,6 @@ import spec from "./woocommerce-spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } export function prepareServerUrl(url: string) { From df93bd85e7611136a6fa83c0204f9337cf512d56 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:51:17 -0400 Subject: [PATCH 09/19] Add gcstorage spec version --- .../plugins/googleCloudStorage/dataSourceConfig.ts | 12 ++++++++++++ .../src/plugins/googleCloudStorage/index.ts | 7 ++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/server/node-service/src/plugins/googleCloudStorage/dataSourceConfig.ts b/server/node-service/src/plugins/googleCloudStorage/dataSourceConfig.ts index 45c75ddd5..6c55c507a 100644 --- a/server/node-service/src/plugins/googleCloudStorage/dataSourceConfig.ts +++ b/server/node-service/src/plugins/googleCloudStorage/dataSourceConfig.ts @@ -1,5 +1,9 @@ import { ConfigToType } from "lowcoder-sdk/dataSource"; +import { specsToOptions } from "../../common/util"; +const specs = { + "v1.0": "" +} export const dataSourceConfig = { type: "dataSource", params: [ @@ -18,6 +22,14 @@ export const dataSourceConfig = { type: "textInput", label: "Region", }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: specsToOptions(specs) + }, ], } as const; diff --git a/server/node-service/src/plugins/googleCloudStorage/index.ts b/server/node-service/src/plugins/googleCloudStorage/index.ts index c86e0c97f..c7ddadff3 100644 --- a/server/node-service/src/plugins/googleCloudStorage/index.ts +++ b/server/node-service/src/plugins/googleCloudStorage/index.ts @@ -7,13 +7,18 @@ import { DataSourceDataType } from "./dataSourceConfig"; import run, { validateDataSourceConfig } from "./run"; import { dataSourceConfig } from "./dataSourceConfig"; +const specs = { + "v1.0": queryConfig +} const gcsPlugin = { id: "googleCloudStorage", name: "Google Cloud Storage", icon: "gcs.svg", category: "api", dataSourceConfig, - queryConfig: queryConfig, + queryConfig: async (data: any) => { + return specs[data.specVersion as keyof typeof specs]; + }, validateDataSourceConfig: async (dataSourceConfig: DataSourceDataType) => { return validateDataSourceConfig(dataSourceConfig); From 70101b70714e3f58848fc73df975edaaeb53ae1a Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 12:53:53 -0400 Subject: [PATCH 10/19] Add stripe spec version --- server/node-service/src/plugins/stripe/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/server/node-service/src/plugins/stripe/index.ts b/server/node-service/src/plugins/stripe/index.ts index 3084ed30f..9d585ac21 100644 --- a/server/node-service/src/plugins/stripe/index.ts +++ b/server/node-service/src/plugins/stripe/index.ts @@ -11,7 +11,6 @@ import { parse } from "yaml"; const yamlContent = readFileSync(path.join(__dirname, "./stripe.spec.yaml"), "utf-8"); const specs = { "v1.0": yamlContent, - "v2.0": yamlContent, } const dataSourceConfig = { @@ -54,8 +53,8 @@ const stripePlugin: DataSourcePlugin = { icon: "stripe.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const spec = parse(yamlContent); + queryConfig: async (data) => { + const spec = parse(specs[data.specVersion as keyof typeof specs]); const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); return { type: "query", @@ -76,7 +75,7 @@ const stripePlugin: DataSourcePlugin = { }; // always use a new spec object // because of this bug: https://github.com/APIDevTools/json-schema-ref-parser/issues/271 - const spec = parse(yamlContent); + const spec = parse(specs[dataSourceConfig.specVersion as keyof typeof specs]); return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, }; From e3866a9a3fbe7c02246b6955bae66bd8cf459690 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 13:07:50 -0400 Subject: [PATCH 11/19] Add asana, circleci spec version --- server/node-service/src/plugins/asana/index.ts | 7 +++---- server/node-service/src/plugins/circleCi/index.ts | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/server/node-service/src/plugins/asana/index.ts b/server/node-service/src/plugins/asana/index.ts index 1c1fd5774..3bc77766d 100644 --- a/server/node-service/src/plugins/asana/index.ts +++ b/server/node-service/src/plugins/asana/index.ts @@ -10,7 +10,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./asana.spec.yaml")); const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -52,8 +51,8 @@ const asanaPlugin: DataSourcePlugin = { icon: "asana.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -71,7 +70,7 @@ const asanaPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/circleCi/index.ts b/server/node-service/src/plugins/circleCi/index.ts index 873f9022b..2111c85bc 100644 --- a/server/node-service/src/plugins/circleCi/index.ts +++ b/server/node-service/src/plugins/circleCi/index.ts @@ -8,7 +8,6 @@ import spec from "./circleCi.spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -46,9 +45,9 @@ const circleCiPlugin: DataSourcePlugin = { icon: "circleCI.svg", category: "api", dataSourceConfig, - queryConfig: async () => { + queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - spec as unknown as OpenAPI.Document, + specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions ); return { @@ -68,7 +67,7 @@ const circleCiPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); }, }; From cd4c117c11b7cd467b81a0d2e6c362e9dc767cc5 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 13:09:54 -0400 Subject: [PATCH 12/19] Add front, github spec version --- server/node-service/src/plugins/front/index.ts | 7 +++---- server/node-service/src/plugins/github/index.ts | 7 +++---- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/server/node-service/src/plugins/front/index.ts b/server/node-service/src/plugins/front/index.ts index 8dedcb576..3cd89da70 100644 --- a/server/node-service/src/plugins/front/index.ts +++ b/server/node-service/src/plugins/front/index.ts @@ -8,7 +8,6 @@ import spec from "./front.spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -47,8 +46,8 @@ const frontPlugin: DataSourcePlugin = { icon: "front.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -66,7 +65,7 @@ const frontPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/github/index.ts b/server/node-service/src/plugins/github/index.ts index 8ca3f41d8..5e6151d4d 100644 --- a/server/node-service/src/plugins/github/index.ts +++ b/server/node-service/src/plugins/github/index.ts @@ -10,7 +10,6 @@ import SwaggerParser from "@apidevtools/swagger-parser"; const spec = readYaml(path.join(__dirname, "./github.spec.yaml")); const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -57,8 +56,8 @@ const gitHubPlugin: DataSourcePlugin = { icon: "github.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); return { type: "query", label: "Action", @@ -76,7 +75,7 @@ const gitHubPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document, undefined, await deRefedSpec); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document, undefined, await deRefedSpec); }, }; From 222cf9c9264ceaf39623cb3f5de1f598075491f5 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 13:21:19 -0400 Subject: [PATCH 13/19] Add huggingface, jira, onesignal spec version --- server/node-service/src/plugins/did/index.ts | 8 ++-- .../src/plugins/huggingFaceEndpoint/index.ts | 7 ++- .../src/plugins/huggingFaceInference/index.ts | 43 ++++++++++++------- server/node-service/src/plugins/jira/index.ts | 15 +++---- .../src/plugins/oneSignal/index.ts | 7 ++- .../node-service/src/plugins/twilio/index.ts | 11 +++-- 6 files changed, 50 insertions(+), 41 deletions(-) diff --git a/server/node-service/src/plugins/did/index.ts b/server/node-service/src/plugins/did/index.ts index 5de707e4c..a955d131a 100644 --- a/server/node-service/src/plugins/did/index.ts +++ b/server/node-service/src/plugins/did/index.ts @@ -51,7 +51,7 @@ const parseOptions: ParseOpenApiOptions = { type DataSourceConfigType = ConfigToType; -let queryConfig: QueryConfig | undefined; +let queryConfig: any = {}; const didPlugin: DataSourcePlugin = { id: "did", @@ -60,9 +60,9 @@ const didPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - if (!queryConfig) { + if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); - queryConfig = { + queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", categories: { @@ -72,7 +72,7 @@ const didPlugin: DataSourcePlugin = { actions, }; } - return queryConfig; + return queryConfig[data.specVersion as keyof typeof queryConfig]; }, run: function (actionData, dataSourceConfig): Promise { const runApiDsConfig = { diff --git a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts index 32595da2d..d49f7d31b 100644 --- a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts +++ b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts @@ -8,7 +8,6 @@ import spec from "./huggingFace.spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -55,9 +54,9 @@ const huggingFacePlugin: DataSourcePlugin = { icon: "huggingFace.svg", category: "api", dataSourceConfig, - queryConfig: async () => { + queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - spec as unknown as OpenAPI.Document, + specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions ); return { @@ -77,7 +76,7 @@ const huggingFacePlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/huggingFaceInference/index.ts b/server/node-service/src/plugins/huggingFaceInference/index.ts index 840b66d73..d860b66b3 100644 --- a/server/node-service/src/plugins/huggingFaceInference/index.ts +++ b/server/node-service/src/plugins/huggingFaceInference/index.ts @@ -1,19 +1,6 @@ import _ from "lodash"; import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; - -const dataSourceConfig = { - type: "dataSource", - params: [ - { - type: "password", - key: "token", - label: "Access Token", - rules: [{ required: true }], - tooltip: - "You can get an Access Token [in your profile setting page](https://huggingface.co/settings/tokens)", - }, - ], -} as const; +import { specsToOptions } from "../../common/util"; const queryConfig = { type: "query", @@ -42,6 +29,30 @@ const queryConfig = { }, ], } as const; +const specs = { + "v1.0": queryConfig +} +const dataSourceConfig = { + type: "dataSource", + params: [ + { + type: "password", + key: "token", + label: "Access Token", + rules: [{ required: true }], + tooltip: + "You can get an Access Token [in your profile setting page](https://huggingface.co/settings/tokens)", + }, + { + label: "Spec Version", + key: "specVersion", + type: "select", + tooltip: "Version of the spec file.", + placeholder: "v1.0", + options: specsToOptions(specs) + }, + ], +} as const; type DataSourceConfigType = ConfigToType; type ActionConfigType = ConfigToType; @@ -52,7 +63,9 @@ const huggingFaceInferencePlugin: DataSourcePlugin { + return specs[data.specVersion as keyof typeof specs]; + }, run: async (actionData, dataSourceConfig) => { const response = await fetch( `https://api-inference.huggingface.co/models/${actionData.model}`, diff --git a/server/node-service/src/plugins/jira/index.ts b/server/node-service/src/plugins/jira/index.ts index db1818edd..35a9eba6f 100644 --- a/server/node-service/src/plugins/jira/index.ts +++ b/server/node-service/src/plugins/jira/index.ts @@ -10,7 +10,6 @@ import { specsToOptions } from "../../common/util"; const specJson = readFileSync(path.join(__dirname, "./jira.spec.json")).toString(); const specs = { "v1.0": specJson, - "v2.0": specJson, } //TODO: Thomas @@ -64,7 +63,7 @@ const parseOptions: ParseOpenApiOptions = { type DataSourceConfigType = ConfigToType; -let queryConfig: QueryConfig; +let queryConfig: any = {}; const jiraPlugin: DataSourcePlugin = { id: "jira", @@ -72,10 +71,10 @@ const jiraPlugin: DataSourcePlugin = { icon: "jira.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - if (!queryConfig) { - const { actions, categories } = await parseOpenApi(JSON.parse(specJson), parseOptions); - queryConfig = { + queryConfig: async (data) => { + if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { + const { actions, categories } = await parseOpenApi(JSON.parse(specs[data.specVersion as keyof typeof specs]), parseOptions); + queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", categories: { @@ -85,10 +84,10 @@ const jiraPlugin: DataSourcePlugin = { actions, }; } - return queryConfig; + return queryConfig[data.specVersion as keyof typeof queryConfig]; }, run: function (actionData, dataSourceConfig): Promise { - const spec = JSON.parse(specJson); + const spec = JSON.parse(specs[dataSourceConfig.specVersion as keyof typeof specs]); const runApiDsConfig = { url: "", serverURL: dataSourceConfig.serverUrl, diff --git a/server/node-service/src/plugins/oneSignal/index.ts b/server/node-service/src/plugins/oneSignal/index.ts index 17b1def2f..c02292b4e 100644 --- a/server/node-service/src/plugins/oneSignal/index.ts +++ b/server/node-service/src/plugins/oneSignal/index.ts @@ -8,7 +8,6 @@ import spec from "./oneSignal.spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -53,9 +52,9 @@ const oneSignalPlugin: DataSourcePlugin = { icon: "oneSignal.svg", category: "api", dataSourceConfig, - queryConfig: async () => { + queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - spec as unknown as OpenAPI.Document, + specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions ); return { @@ -75,7 +74,7 @@ const oneSignalPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index 797e3e498..30e84e0ec 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -44,7 +44,7 @@ const parseOptions: ParseOpenApiOptions = { }, }; -let queryConfig: QueryConfig; +let queryConfig: any = {}; type DataSourceConfigType = ConfigToType; @@ -56,10 +56,9 @@ const twilioPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { - console.log(data.specVersion); - // if (!queryConfig) { + if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); - queryConfig = { + queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", categories: { @@ -68,8 +67,8 @@ const twilioPlugin: DataSourcePlugin = { }, actions, }; - // } - return queryConfig; + } + return queryConfig[data.specVersion as keyof typeof queryConfig]; }, run: function (actionData, dataSourceConfig): Promise { From 206e03c206013eb341a7738d796f7bff49a0d4f2 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 13:29:02 -0400 Subject: [PATCH 14/19] Add cloudinary, datadog, lowcoder, notion, postmanecho, sendgrid spec version --- .../node-service/src/plugins/cloudinary/index.ts | 16 +++++++--------- server/node-service/src/plugins/datadog/index.ts | 7 +++---- .../node-service/src/plugins/lowcoder/index.ts | 7 +++---- server/node-service/src/plugins/notion/index.ts | 7 +++---- .../src/plugins/postmanEcho/index.ts | 7 +++---- .../node-service/src/plugins/sendGrid/index.ts | 7 +++---- 6 files changed, 22 insertions(+), 29 deletions(-) diff --git a/server/node-service/src/plugins/cloudinary/index.ts b/server/node-service/src/plugins/cloudinary/index.ts index 65f7ee403..08f2ec362 100644 --- a/server/node-service/src/plugins/cloudinary/index.ts +++ b/server/node-service/src/plugins/cloudinary/index.ts @@ -16,10 +16,8 @@ const specList = [ ]; const specs = { "v1.0": specList, - "v2.0": specList, } -//TODO: Thomas const dataSourceConfig = { type: "dataSource", params: [ @@ -59,7 +57,7 @@ const parseOptions: ParseOpenApiOptions = { type DataSourceConfigType = ConfigToType; -let queryConfig: QueryConfig; +let queryConfig: any = {}; const cloudinaryPlugin: DataSourcePlugin = { id: "cloudinary", @@ -67,10 +65,10 @@ const cloudinaryPlugin: DataSourcePlugin = { icon: "cloudinary.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - if (!queryConfig) { - const { actions, categories } = await parseMultiOpenApi(specList, parseOptions); - queryConfig = { + queryConfig: async (data) => { + if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { + const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", categories: { @@ -80,7 +78,7 @@ const cloudinaryPlugin: DataSourcePlugin = { actions, }; } - return queryConfig; + return queryConfig[data.specVersion as keyof typeof queryConfig]; }, run: function (actionData, dataSourceConfig): Promise { const runApiDsConfig = { @@ -89,7 +87,7 @@ const cloudinaryPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specList); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); }, }; diff --git a/server/node-service/src/plugins/datadog/index.ts b/server/node-service/src/plugins/datadog/index.ts index 7a7cf24c6..b1ff8a52d 100644 --- a/server/node-service/src/plugins/datadog/index.ts +++ b/server/node-service/src/plugins/datadog/index.ts @@ -9,7 +9,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./datadog.spec.yaml")); const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -59,8 +58,8 @@ const datadogPlugin: DataSourcePlugin = { icon: "datadog.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); return { type: "query", label: "Action", @@ -78,7 +77,7 @@ const datadogPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/lowcoder/index.ts b/server/node-service/src/plugins/lowcoder/index.ts index a2204e71f..0a0331657 100644 --- a/server/node-service/src/plugins/lowcoder/index.ts +++ b/server/node-service/src/plugins/lowcoder/index.ts @@ -9,7 +9,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from './lowcoder.spec.json'; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -60,8 +59,8 @@ const lowcoderPlugin: DataSourcePlugin = { icon: "lowcoder.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as unknown as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -81,7 +80,7 @@ const lowcoderPlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/notion/index.ts b/server/node-service/src/plugins/notion/index.ts index 85c9e8c31..9213d8efb 100644 --- a/server/node-service/src/plugins/notion/index.ts +++ b/server/node-service/src/plugins/notion/index.ts @@ -9,7 +9,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const spec = readYaml(path.join(__dirname, "./notion.spec.yaml")); const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -53,8 +52,8 @@ const notionPlugin: DataSourcePlugin = { icon: "notion.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); return { type: "query", label: "Action", @@ -72,7 +71,7 @@ const notionPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document, { + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document, { "Notion-Version": dataSourceConfig.notionVersion, }); }, diff --git a/server/node-service/src/plugins/postmanEcho/index.ts b/server/node-service/src/plugins/postmanEcho/index.ts index 3a0b31f51..500f734e7 100644 --- a/server/node-service/src/plugins/postmanEcho/index.ts +++ b/server/node-service/src/plugins/postmanEcho/index.ts @@ -9,7 +9,6 @@ import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from './postmanEcho.spec.json'; const specs = { "v1.0": spec, - "v2.0": spec, } @@ -41,8 +40,8 @@ const postmanEchoPlugin: DataSourcePlugin = { icon: "postmanEcho.svg", category: "api", dataSourceConfig, - queryConfig: async () => { - const { actions, categories } = await parseOpenApi(spec as unknown as OpenAPI.Document, parseOptions); + queryConfig: async (data) => { + const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -60,7 +59,7 @@ const postmanEchoPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/sendGrid/index.ts b/server/node-service/src/plugins/sendGrid/index.ts index 0b8c73bda..dec4ce044 100644 --- a/server/node-service/src/plugins/sendGrid/index.ts +++ b/server/node-service/src/plugins/sendGrid/index.ts @@ -8,7 +8,6 @@ import spec from "./sendGrid.spec.json"; import { specsToOptions } from "../../common/util"; const specs = { "v1.0": spec, - "v2.0": spec, } const dataSourceConfig = { @@ -45,9 +44,9 @@ const sendGridPlugin: DataSourcePlugin = { icon: "sendGrid.svg", category: "api", dataSourceConfig, - queryConfig: async () => { + queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - spec as unknown as OpenAPI.Document, + specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions ); return { @@ -70,7 +69,7 @@ const sendGridPlugin: DataSourcePlugin = { }, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, spec as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); }, }; From 998625ed87da0f3d0f7774a21391342bdbb35a54 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Mon, 5 Aug 2024 13:55:35 -0400 Subject: [PATCH 15/19] remove test code --- server/node-service/src/plugins/twilio/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index 30e84e0ec..ab2e3c977 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -8,8 +8,7 @@ import { parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const specs = { - "twilio--V": dirToSpecList(path.join(__dirname, "./twilio.spec")), - "did--V": dirToSpecList(path.join(__dirname, "./did.spec")), + "v1.0": dirToSpecList(path.join(__dirname, "./twilio.spec")), } const dataSourceConfig = { From 13212ef6d68434b147ec9e9c79fec7d20f24af98 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Tue, 6 Aug 2024 11:11:04 -0400 Subject: [PATCH 16/19] backward compatibility when no version is selected --- server/node-service/src/common/util.ts | 9 +++++++++ server/node-service/src/plugins/asana/index.ts | 6 +++--- server/node-service/src/plugins/circleCi/index.ts | 6 +++--- server/node-service/src/plugins/cloudinary/index.ts | 6 +++--- server/node-service/src/plugins/couchdb/index.ts | 6 +++--- server/node-service/src/plugins/datadog/index.ts | 6 +++--- server/node-service/src/plugins/did/index.ts | 6 +++--- server/node-service/src/plugins/dynamodb/index.ts | 3 ++- server/node-service/src/plugins/firebase/index.ts | 3 ++- server/node-service/src/plugins/front/index.ts | 6 +++--- server/node-service/src/plugins/github/index.ts | 6 +++--- .../node-service/src/plugins/googleCloudStorage/index.ts | 3 ++- .../src/plugins/huggingFaceEndpoint/index.ts | 6 +++--- .../src/plugins/huggingFaceInference/index.ts | 4 ++-- server/node-service/src/plugins/jira/index.ts | 6 +++--- server/node-service/src/plugins/lowcoder/index.ts | 6 +++--- server/node-service/src/plugins/n8n/index.ts | 6 +++--- server/node-service/src/plugins/notion/index.ts | 6 +++--- server/node-service/src/plugins/oneSignal/index.ts | 6 +++--- server/node-service/src/plugins/openAi/index.ts | 6 +++--- server/node-service/src/plugins/postmanEcho/index.ts | 6 +++--- server/node-service/src/plugins/sendGrid/index.ts | 6 +++--- server/node-service/src/plugins/stripe/index.ts | 6 +++--- server/node-service/src/plugins/twilio/index.ts | 6 +++--- server/node-service/src/plugins/woocommerce/index.ts | 6 +++--- 25 files changed, 77 insertions(+), 65 deletions(-) diff --git a/server/node-service/src/common/util.ts b/server/node-service/src/common/util.ts index df3760fe6..821c07639 100644 --- a/server/node-service/src/common/util.ts +++ b/server/node-service/src/common/util.ts @@ -94,6 +94,15 @@ export function specsToOptions(specs: any) { return Object.keys(specs).map(k => ({value: k, label: k})); } +export function version2spec(specs: any, version: any) { + if(version == undefined || version == "") { + const keys = Object.keys(specs); + if(keys.length == 0) return; + return specs[keys[0]]; + } + return specs[version]; +} + function genTagFromFileName(name: string) { const fileName = name.replace(/\.yaml|twilio_|\.json/g, ""); const parts = fileName.split("_"); diff --git a/server/node-service/src/plugins/asana/index.ts b/server/node-service/src/plugins/asana/index.ts index 3bc77766d..d15c2a5ea 100644 --- a/server/node-service/src/plugins/asana/index.ts +++ b/server/node-service/src/plugins/asana/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -52,7 +52,7 @@ const asanaPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -70,7 +70,7 @@ const asanaPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/circleCi/index.ts b/server/node-service/src/plugins/circleCi/index.ts index 2111c85bc..758606377 100644 --- a/server/node-service/src/plugins/circleCi/index.ts +++ b/server/node-service/src/plugins/circleCi/index.ts @@ -5,7 +5,7 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./circleCi.spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -47,7 +47,7 @@ const circleCiPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, + version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions ); return { @@ -67,7 +67,7 @@ const circleCiPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as unknown as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/cloudinary/index.ts b/server/node-service/src/plugins/cloudinary/index.ts index 08f2ec362..bf1eb1a1b 100644 --- a/server/node-service/src/plugins/cloudinary/index.ts +++ b/server/node-service/src/plugins/cloudinary/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPI } from "openapi-types"; @@ -67,7 +67,7 @@ const cloudinaryPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { - const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseMultiOpenApi(version2spec(specs, data.specVersion), parseOptions); queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", @@ -87,7 +87,7 @@ const cloudinaryPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion)); }, }; diff --git a/server/node-service/src/plugins/couchdb/index.ts b/server/node-service/src/plugins/couchdb/index.ts index ce240decc..00c1dc70e 100644 --- a/server/node-service/src/plugins/couchdb/index.ts +++ b/server/node-service/src/plugins/couchdb/index.ts @@ -4,7 +4,7 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./CouchDB-3.1.1-resolved.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -71,7 +71,7 @@ const couchdbPlugin: DataSourcePlugin = { category: "database", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -90,7 +90,7 @@ const couchdbPlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV2.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV2.Document); }, }; diff --git a/server/node-service/src/plugins/datadog/index.ts b/server/node-service/src/plugins/datadog/index.ts index b1ff8a52d..7167c4c7c 100644 --- a/server/node-service/src/plugins/datadog/index.ts +++ b/server/node-service/src/plugins/datadog/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -59,7 +59,7 @@ const datadogPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion), parseOptions); return { type: "query", label: "Action", @@ -77,7 +77,7 @@ const datadogPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/did/index.ts b/server/node-service/src/plugins/did/index.ts index a955d131a..b5ac4cc45 100644 --- a/server/node-service/src/plugins/did/index.ts +++ b/server/node-service/src/plugins/did/index.ts @@ -1,4 +1,4 @@ -import { dirToSpecList, specsToOptions } from "../../common/util"; +import { dirToSpecList, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPI } from "openapi-types"; @@ -61,7 +61,7 @@ const didPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { - const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseMultiOpenApi(version2spec(specs, data.specVersion), parseOptions); queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", @@ -81,7 +81,7 @@ const didPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion)); }, }; diff --git a/server/node-service/src/plugins/dynamodb/index.ts b/server/node-service/src/plugins/dynamodb/index.ts index d3ee1edca..5938fb878 100644 --- a/server/node-service/src/plugins/dynamodb/index.ts +++ b/server/node-service/src/plugins/dynamodb/index.ts @@ -2,6 +2,7 @@ import { DataSourcePlugin } from "lowcoder-sdk/dataSource"; import dataSourceConfig, { DataSourceDataType } from "./dataSourceConfig"; import queryConfig, { ActionDataType } from "./queryConfig"; import { runDynamoDbQuery } from "./run"; +import { version2spec } from "../../common/util"; const specs = { "v1.0": queryConfig @@ -14,7 +15,7 @@ const dynamoDBPlugin: DataSourcePlugin = { icon: "dynamodb.svg", dataSourceConfig, queryConfig: async (data) => { - return specs[data.specVersion as keyof typeof specs] + return version2spec(specs, data.specVersion); }, run: async function (actionData, dataSourceConfig): Promise { return runDynamoDbQuery(actionData, dataSourceConfig); diff --git a/server/node-service/src/plugins/firebase/index.ts b/server/node-service/src/plugins/firebase/index.ts index d7d03dc75..40834158d 100644 --- a/server/node-service/src/plugins/firebase/index.ts +++ b/server/node-service/src/plugins/firebase/index.ts @@ -2,6 +2,7 @@ import { DataSourcePlugin } from "lowcoder-sdk/dataSource"; import dataSourceConfig, { DataSourceDataType } from "./dataSourceConfig"; import queryConfig, { ActionDataType } from "./queryConfig"; import { runFirebasePlugin } from "./run"; +import { version2spec } from "../../common/util"; const specs = { "v1.0": queryConfig @@ -13,7 +14,7 @@ const firebasePlugin: DataSourcePlugin = { name: "Firebase", category: "api", queryConfig: async (data) => { - return specs[data.specVersion as keyof typeof specs] + return version2spec(specs, data.specVersion); }, dataSourceConfig, run: function (actionData, dataSourceConfig): Promise { diff --git a/server/node-service/src/plugins/front/index.ts b/server/node-service/src/plugins/front/index.ts index 3cd89da70..2ce6f68cc 100644 --- a/server/node-service/src/plugins/front/index.ts +++ b/server/node-service/src/plugins/front/index.ts @@ -5,7 +5,7 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./front.spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -47,7 +47,7 @@ const frontPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -65,7 +65,7 @@ const frontPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/github/index.ts b/server/node-service/src/plugins/github/index.ts index 5e6151d4d..1545f2b3c 100644 --- a/server/node-service/src/plugins/github/index.ts +++ b/server/node-service/src/plugins/github/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -57,7 +57,7 @@ const gitHubPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion), parseOptions); return { type: "query", label: "Action", @@ -75,7 +75,7 @@ const gitHubPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document, undefined, await deRefedSpec); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document, undefined, await deRefedSpec); }, }; diff --git a/server/node-service/src/plugins/googleCloudStorage/index.ts b/server/node-service/src/plugins/googleCloudStorage/index.ts index c7ddadff3..cf138b177 100644 --- a/server/node-service/src/plugins/googleCloudStorage/index.ts +++ b/server/node-service/src/plugins/googleCloudStorage/index.ts @@ -6,6 +6,7 @@ import queryConfig, { ActionDataType } from "./queryConfig"; import { DataSourceDataType } from "./dataSourceConfig"; import run, { validateDataSourceConfig } from "./run"; import { dataSourceConfig } from "./dataSourceConfig"; +import { version2spec } from "../../common/util"; const specs = { "v1.0": queryConfig @@ -17,7 +18,7 @@ const gcsPlugin = { category: "api", dataSourceConfig, queryConfig: async (data: any) => { - return specs[data.specVersion as keyof typeof specs]; + return version2spec(specs, data.specVersion); }, validateDataSourceConfig: async (dataSourceConfig: DataSourceDataType) => { diff --git a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts index d49f7d31b..dc1b3ef70 100644 --- a/server/node-service/src/plugins/huggingFaceEndpoint/index.ts +++ b/server/node-service/src/plugins/huggingFaceEndpoint/index.ts @@ -5,7 +5,7 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./huggingFace.spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -56,7 +56,7 @@ const huggingFacePlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, + version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions ); return { @@ -76,7 +76,7 @@ const huggingFacePlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as unknown as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/huggingFaceInference/index.ts b/server/node-service/src/plugins/huggingFaceInference/index.ts index d860b66b3..e5755a03d 100644 --- a/server/node-service/src/plugins/huggingFaceInference/index.ts +++ b/server/node-service/src/plugins/huggingFaceInference/index.ts @@ -1,6 +1,6 @@ import _ from "lodash"; import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const queryConfig = { type: "query", @@ -64,7 +64,7 @@ const huggingFaceInferencePlugin: DataSourcePlugin { - return specs[data.specVersion as keyof typeof specs]; + return version2spec(specs, data.specVersion); }, run: async (actionData, dataSourceConfig) => { const response = await fetch( diff --git a/server/node-service/src/plugins/jira/index.ts b/server/node-service/src/plugins/jira/index.ts index 35a9eba6f..ca485cab8 100644 --- a/server/node-service/src/plugins/jira/index.ts +++ b/server/node-service/src/plugins/jira/index.ts @@ -5,7 +5,7 @@ import { ConfigToType, DataSourcePlugin, QueryConfig } from "lowcoder-sdk/dataSo import path from "path"; import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specJson = readFileSync(path.join(__dirname, "./jira.spec.json")).toString(); const specs = { @@ -73,7 +73,7 @@ const jiraPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { - const { actions, categories } = await parseOpenApi(JSON.parse(specs[data.specVersion as keyof typeof specs]), parseOptions); + const { actions, categories } = await parseOpenApi(JSON.parse(version2spec(specs, data.specVersion)), parseOptions); queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", @@ -87,7 +87,7 @@ const jiraPlugin: DataSourcePlugin = { return queryConfig[data.specVersion as keyof typeof queryConfig]; }, run: function (actionData, dataSourceConfig): Promise { - const spec = JSON.parse(specs[dataSourceConfig.specVersion as keyof typeof specs]); + const spec = JSON.parse(version2spec(specs, dataSourceConfig.specVersion)); const runApiDsConfig = { url: "", serverURL: dataSourceConfig.serverUrl, diff --git a/server/node-service/src/plugins/lowcoder/index.ts b/server/node-service/src/plugins/lowcoder/index.ts index 0a0331657..fb929992c 100644 --- a/server/node-service/src/plugins/lowcoder/index.ts +++ b/server/node-service/src/plugins/lowcoder/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -60,7 +60,7 @@ const lowcoderPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -80,7 +80,7 @@ const lowcoderPlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/n8n/index.ts b/server/node-service/src/plugins/n8n/index.ts index 26876dd1a..6aac8dea0 100644 --- a/server/node-service/src/plugins/n8n/index.ts +++ b/server/node-service/src/plugins/n8n/index.ts @@ -4,7 +4,7 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -70,7 +70,7 @@ const n8nPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -91,7 +91,7 @@ const n8nPlugin: DataSourcePlugin = { }, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/notion/index.ts b/server/node-service/src/plugins/notion/index.ts index 9213d8efb..c166786fa 100644 --- a/server/node-service/src/plugins/notion/index.ts +++ b/server/node-service/src/plugins/notion/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -53,7 +53,7 @@ const notionPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion), parseOptions); return { type: "query", label: "Action", @@ -71,7 +71,7 @@ const notionPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document, { + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document, { "Notion-Version": dataSourceConfig.notionVersion, }); }, diff --git a/server/node-service/src/plugins/oneSignal/index.ts b/server/node-service/src/plugins/oneSignal/index.ts index c02292b4e..b971cbf2b 100644 --- a/server/node-service/src/plugins/oneSignal/index.ts +++ b/server/node-service/src/plugins/oneSignal/index.ts @@ -5,7 +5,7 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./oneSignal.spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -54,7 +54,7 @@ const oneSignalPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, + version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions ); return { @@ -74,7 +74,7 @@ const oneSignalPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/openAi/index.ts b/server/node-service/src/plugins/openAi/index.ts index a192189f6..b4cbf7f92 100644 --- a/server/node-service/src/plugins/openAi/index.ts +++ b/server/node-service/src/plugins/openAi/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -49,7 +49,7 @@ const openAiPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion), parseOptions); return { type: "query", label: "Action", @@ -67,7 +67,7 @@ const openAiPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/postmanEcho/index.ts b/server/node-service/src/plugins/postmanEcho/index.ts index 500f734e7..113680676 100644 --- a/server/node-service/src/plugins/postmanEcho/index.ts +++ b/server/node-service/src/plugins/postmanEcho/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -41,7 +41,7 @@ const postmanEchoPlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions); return { type: "query", label: "Action", @@ -59,7 +59,7 @@ const postmanEchoPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/sendGrid/index.ts b/server/node-service/src/plugins/sendGrid/index.ts index dec4ce044..bf5206a6d 100644 --- a/server/node-service/src/plugins/sendGrid/index.ts +++ b/server/node-service/src/plugins/sendGrid/index.ts @@ -5,7 +5,7 @@ import { runOpenApi } from "../openApi"; import { parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./sendGrid.spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -46,7 +46,7 @@ const sendGridPlugin: DataSourcePlugin = { dataSourceConfig, queryConfig: async (data) => { const { actions, categories } = await parseOpenApi( - specs[data.specVersion as keyof typeof specs] as unknown as OpenAPI.Document, + version2spec(specs, data.specVersion) as unknown as OpenAPI.Document, parseOptions ); return { @@ -69,7 +69,7 @@ const sendGridPlugin: DataSourcePlugin = { }, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV3.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as unknown as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/stripe/index.ts b/server/node-service/src/plugins/stripe/index.ts index 9d585ac21..0500a2d68 100644 --- a/server/node-service/src/plugins/stripe/index.ts +++ b/server/node-service/src/plugins/stripe/index.ts @@ -1,4 +1,4 @@ -import { readYaml, specsToOptions } from "../../common/util"; +import { readYaml, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPIV3, OpenAPI } from "openapi-types"; @@ -54,7 +54,7 @@ const stripePlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const spec = parse(specs[data.specVersion as keyof typeof specs]); + const spec = parse(version2spec(specs, data.specVersion)); const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions); return { type: "query", @@ -75,7 +75,7 @@ const stripePlugin: DataSourcePlugin = { }; // always use a new spec object // because of this bug: https://github.com/APIDevTools/json-schema-ref-parser/issues/271 - const spec = parse(specs[dataSourceConfig.specVersion as keyof typeof specs]); + const spec = parse(version2spec(specs, dataSourceConfig.specVersion)); return runOpenApi(actionData, runApiDsConfig, spec as OpenAPIV3.Document); }, }; diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index ab2e3c977..e0ba77b41 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -1,4 +1,4 @@ -import { dirToSpecList, specsToOptions } from "../../common/util"; +import { dirToSpecList, specsToOptions, version2spec } from "../../common/util"; import _ from "lodash"; import path from "path"; import { OpenAPI } from "openapi-types"; @@ -56,7 +56,7 @@ const twilioPlugin: DataSourcePlugin = { queryConfig: async (data) => { if (!queryConfig[data.specVersion as keyof typeof queryConfig]) { - const { actions, categories } = await parseMultiOpenApi(specs[data.specVersion as keyof typeof specs], parseOptions); + const { actions, categories } = await parseMultiOpenApi(version2spec(specs, data.specVersion), parseOptions); queryConfig[data.specVersion as keyof typeof queryConfig] = { type: "query", label: "Action", @@ -77,7 +77,7 @@ const twilioPlugin: DataSourcePlugin = { dynamicParamsConfig: dataSourceConfig, specVersion: dataSourceConfig.specVersion, }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs]); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion)); }, }; diff --git a/server/node-service/src/plugins/woocommerce/index.ts b/server/node-service/src/plugins/woocommerce/index.ts index 00b459228..c68622a8f 100644 --- a/server/node-service/src/plugins/woocommerce/index.ts +++ b/server/node-service/src/plugins/woocommerce/index.ts @@ -5,7 +5,7 @@ import { ConfigToType, DataSourcePlugin } from "lowcoder-sdk/dataSource"; import { runOpenApi } from "../openApi"; import { defaultParseOpenApiOptions, parseOpenApi, ParseOpenApiOptions } from "../openApi/parse"; import spec from "./woocommerce-spec.json"; -import { specsToOptions } from "../../common/util"; +import { specsToOptions, version2spec } from "../../common/util"; const specs = { "v1.0": spec, } @@ -78,7 +78,7 @@ const wooCommercePlugin: DataSourcePlugin = { category: "api", dataSourceConfig, queryConfig: async (data) => { - const { actions, categories } = await parseOpenApi(specs[data.specVersion as keyof typeof specs] as OpenAPI.Document, parseOptions); + const { actions, categories } = await parseOpenApi(version2spec(specs, data.specVersion) as OpenAPI.Document, parseOptions); return { type: "query", label: "Operation", @@ -97,7 +97,7 @@ const wooCommercePlugin: DataSourcePlugin = { dynamicParamsConfig: otherDataSourceConfig, specVersion: dataSourceConfig.specVersion }; - return runOpenApi(actionData, runApiDsConfig, specs[dataSourceConfig.specVersion as keyof typeof specs] as unknown as OpenAPIV2.Document); + return runOpenApi(actionData, runApiDsConfig, version2spec(specs, dataSourceConfig.specVersion) as unknown as OpenAPIV2.Document); }, }; From 21bf50492b9303eb4c84fa99b32ce4c5226926a6 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Tue, 6 Aug 2024 14:10:13 -0400 Subject: [PATCH 17/19] resolve test issue --- server/node-service/src/plugins/dynamodb/run.test.ts | 1 + server/node-service/src/plugins/firebase/run.test.ts | 1 + server/node-service/src/plugins/s3/run.test.ts | 1 + 3 files changed, 3 insertions(+) diff --git a/server/node-service/src/plugins/dynamodb/run.test.ts b/server/node-service/src/plugins/dynamodb/run.test.ts index 6ce0e2eaa..f02a73228 100644 --- a/server/node-service/src/plugins/dynamodb/run.test.ts +++ b/server/node-service/src/plugins/dynamodb/run.test.ts @@ -8,6 +8,7 @@ test.skip("run dynamodb query", async () => { accessKey: "", secretKey: "", endpointUrl: "http://localhost:6789", + specVersion: "", }; const createTableActionData: ActionDataType = { diff --git a/server/node-service/src/plugins/firebase/run.test.ts b/server/node-service/src/plugins/firebase/run.test.ts index bc11e4740..2355ac3d0 100644 --- a/server/node-service/src/plugins/firebase/run.test.ts +++ b/server/node-service/src/plugins/firebase/run.test.ts @@ -9,6 +9,7 @@ test.skip("realtime database", async () => { databaseUrl: "https://sarike-a3de9-default-rtdb.asia-southeast1.firebasedatabase.app/", privateKey, firestoreId: "", + specVersion: "", } ); console.info(res); diff --git a/server/node-service/src/plugins/s3/run.test.ts b/server/node-service/src/plugins/s3/run.test.ts index 60632fd46..a1c6089b2 100644 --- a/server/node-service/src/plugins/s3/run.test.ts +++ b/server/node-service/src/plugins/s3/run.test.ts @@ -6,6 +6,7 @@ const dataSourceConfig = { secretKey: "", endpointUrl: "", region: "us-west-2", + specVersion: "", }; const bucket = "lowcoder-demo"; From 03688bf09a27fefc8e750b76742d1e8846deb1c2 Mon Sep 17 00:00:00 2001 From: Thomasr Date: Wed, 7 Aug 2024 12:34:50 -0400 Subject: [PATCH 18/19] add test case --- server/node-service/src/common/util.test.ts | 112 ++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 server/node-service/src/common/util.test.ts diff --git a/server/node-service/src/common/util.test.ts b/server/node-service/src/common/util.test.ts new file mode 100644 index 000000000..d099a35de --- /dev/null +++ b/server/node-service/src/common/util.test.ts @@ -0,0 +1,112 @@ +import { specsToOptions, version2spec } from "./util"; + +describe('version2spec', () => { + test('should return the spec for the given version', () => { + const specs = { + v1: 'spec for version 1', + v2: 'spec for version 2', + v3: 'spec for version 3' + }; + + expect(version2spec(specs, 'v2')).toBe('spec for version 2'); + }); + + test('should return the first spec if version is undefined', () => { + const specs = { + v1: 'spec for version 1', + v2: 'spec for version 2', + v3: 'spec for version 3' + }; + + expect(version2spec(specs, undefined)).toBe('spec for version 1'); + }); + + test('should return the first spec if version is an empty string', () => { + const specs = { + v1: 'spec for version 1', + v2: 'spec for version 2', + v3: 'spec for version 3' + }; + + expect(version2spec(specs, "")).toBe('spec for version 1'); + }); + + test('should return undefined if specs is an empty object and version is undefined', () => { + const specs = {}; + + expect(version2spec(specs, undefined)).toBeUndefined(); + }); + + test('should return undefined if specs is an empty object and version is an empty string', () => { + const specs = {}; + + expect(version2spec(specs, "")).toBeUndefined(); + }); + + test('should return undefined if the specified version does not exist in specs', () => { + const specs = { + v1: 'spec for version 1', + v2: 'spec for version 2', + v3: 'spec for version 3' + }; + + expect(version2spec(specs, 'v4')).toBeUndefined(); + }); +}); + +describe('specsToOptions', () => { + test('should convert specs object to options array', () => { + const specs = { + color: 'red', + size: 'large', + weight: 'light' + }; + + const expectedOptions = [ + { value: 'color', label: 'color' }, + { value: 'size', label: 'size' }, + { value: 'weight', label: 'weight' } + ]; + + expect(specsToOptions(specs)).toEqual(expectedOptions); + }); + + test('should return an empty array if specs object is empty', () => { + const specs = {}; + const expectedOptions: any[] = []; + + expect(specsToOptions(specs)).toEqual(expectedOptions); + }); + + test('should handle specs object with non-string values', () => { + const specs = { + color: 'red', + size: 42, + available: true + }; + + const expectedOptions = [ + { value: 'color', label: 'color' }, + { value: 'size', label: 'size' }, + { value: 'available', label: 'available' } + ]; + + expect(specsToOptions(specs)).toEqual(expectedOptions); + }); + + test('should handle specs object with numeric keys', () => { + const specs = { + 1: 'one', + 2: 'two', + 3: 'three' + }; + + const expectedOptions = [ + { value: '1', label: '1' }, + { value: '2', label: '2' }, + { value: '3', label: '3' } + ]; + + expect(specsToOptions(specs)).toEqual(expectedOptions); + }); +}); \ No newline at end of file From b831451d4d907399d6747f7c9dcb58f6b62daa4a Mon Sep 17 00:00:00 2001 From: FalkWolsky Date: Sat, 10 Aug 2024 10:07:31 +0200 Subject: [PATCH 19/19] Sorting Twilio into Versions --- server/node-service/src/plugins/twilio/index.ts | 5 ++++- .../{twilio.spec => twilio.spec.v1}/twilio_accounts_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_autopilot_v1.yaml | 0 .../twilio_bulkexports_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_chat_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_content_v1.yaml | 0 .../twilio_conversations_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_events_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_flex_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_frontline_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_insights_v1.yaml | 0 .../twilio_ip_messaging_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_lookups_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_media_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_messaging_v1.yaml | 0 .../twilio_microvisor_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_monitor_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_notify_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_oauth_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_preview.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_pricing_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_proxy_v1.yaml | 0 .../twilio_serverless_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_studio_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_supersim_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_sync_v1.yaml | 0 .../twilio_taskrouter_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_trunking_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_trusthub_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_video_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_voice_v1.yaml | 0 .../{twilio.spec => twilio.spec.v1}/twilio_wireless_v1.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_chat_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_flex_v2.yaml | 0 .../twilio_ip_messaging_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_lookups_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_numbers_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_pricing_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_routes_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_studio_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2}/twilio_verify_v2.yaml | 0 .../{twilio.spec => twilio.spec.v2010}/twilio_api_v2010.yaml | 0 .../{twilio.spec => twilio.spec.v3}/twilio_chat_v3.yaml | 0 43 files changed, 4 insertions(+), 1 deletion(-) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_accounts_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_autopilot_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_bulkexports_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_chat_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_content_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_conversations_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_events_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_flex_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_frontline_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_insights_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_ip_messaging_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_lookups_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_media_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_messaging_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_microvisor_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_monitor_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_notify_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_oauth_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_preview.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_pricing_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_proxy_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_serverless_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_studio_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_supersim_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_sync_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_taskrouter_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_trunking_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_trusthub_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_video_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_voice_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v1}/twilio_wireless_v1.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_chat_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_flex_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_ip_messaging_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_lookups_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_numbers_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_pricing_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_routes_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_studio_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2}/twilio_verify_v2.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v2010}/twilio_api_v2010.yaml (100%) rename server/node-service/src/plugins/twilio/{twilio.spec => twilio.spec.v3}/twilio_chat_v3.yaml (100%) diff --git a/server/node-service/src/plugins/twilio/index.ts b/server/node-service/src/plugins/twilio/index.ts index e96b24d74..a134293aa 100644 --- a/server/node-service/src/plugins/twilio/index.ts +++ b/server/node-service/src/plugins/twilio/index.ts @@ -8,7 +8,10 @@ import { parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse"; const specs = { - "v1.0": dirToSpecList(path.join(__dirname, "./twilio.spec")), + "v1.0": dirToSpecList(path.join(__dirname, "./twilio.spec.v1")), + "v2.0": dirToSpecList(path.join(__dirname, "./twilio.spec.v2")), + "v3.0": dirToSpecList(path.join(__dirname, "./twilio.spec.v3")), + "v2010": dirToSpecList(path.join(__dirname, "./twilio.spec.v2010")), } const dataSourceConfig = { diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_accounts_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_accounts_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_accounts_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_accounts_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_autopilot_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_autopilot_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_autopilot_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_autopilot_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_bulkexports_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_bulkexports_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_bulkexports_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_bulkexports_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_chat_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_chat_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_content_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_content_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_content_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_content_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_conversations_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_conversations_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_conversations_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_conversations_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_events_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_events_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_events_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_events_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_flex_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_flex_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_flex_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_flex_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_frontline_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_frontline_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_frontline_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_frontline_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_insights_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_insights_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_insights_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_insights_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_ip_messaging_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_ip_messaging_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_ip_messaging_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_ip_messaging_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_lookups_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_lookups_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_lookups_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_lookups_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_media_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_media_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_media_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_media_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_messaging_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_messaging_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_messaging_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_messaging_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_microvisor_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_microvisor_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_microvisor_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_microvisor_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_monitor_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_monitor_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_monitor_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_monitor_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_notify_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_notify_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_notify_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_notify_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_oauth_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_oauth_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_oauth_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_oauth_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_preview.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_preview.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_preview.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_preview.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_pricing_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_pricing_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_pricing_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_pricing_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_proxy_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_proxy_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_proxy_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_proxy_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_serverless_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_serverless_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_serverless_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_serverless_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_studio_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_studio_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_studio_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_studio_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_supersim_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_supersim_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_supersim_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_supersim_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_sync_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_sync_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_sync_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_sync_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_taskrouter_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_taskrouter_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_taskrouter_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_taskrouter_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_trunking_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_trunking_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_trunking_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_trunking_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_trusthub_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_trusthub_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_trusthub_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_trusthub_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_video_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_video_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_video_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_video_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_voice_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_voice_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_voice_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_voice_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_wireless_v1.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_wireless_v1.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_wireless_v1.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v1/twilio_wireless_v1.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_chat_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_chat_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_flex_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_flex_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_flex_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_flex_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_ip_messaging_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_ip_messaging_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_ip_messaging_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_ip_messaging_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_lookups_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_lookups_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_lookups_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_lookups_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_numbers_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_numbers_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_numbers_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_numbers_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_pricing_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_pricing_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_pricing_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_pricing_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_routes_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_routes_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_routes_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_routes_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_studio_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_studio_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_studio_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_studio_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_verify_v2.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_verify_v2.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_verify_v2.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2/twilio_verify_v2.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_api_v2010.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v2010/twilio_api_v2010.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_api_v2010.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v2010/twilio_api_v2010.yaml diff --git a/server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v3.yaml b/server/node-service/src/plugins/twilio/twilio.spec.v3/twilio_chat_v3.yaml similarity index 100% rename from server/node-service/src/plugins/twilio/twilio.spec/twilio_chat_v3.yaml rename to server/node-service/src/plugins/twilio/twilio.spec.v3/twilio_chat_v3.yaml