Skip to content

Commit 3257e91

Browse files
author
sunlei
committed
twilio datasource
1 parent 5482579 commit 3257e91

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+122853
-25
lines changed

server/node-service/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"openapi-types": "^12.1.0",
5555
"openblocks-core": "^0.0.7",
5656
"openblocks-sdk": "^0.0.35",
57+
"pino": "^8.11.0",
5758
"stylis": "^4.1.3",
5859
"swagger-client": "^3.18.5",
5960
"typescript": "^4.9.3",

server/node-service/scripts/openApiDataSourceGen.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ async function gen(options: Options) {
2929
if (postMan) {
3030
console.info("is PostMan Collection start transforming...");
3131
const collection = postManCollectionFile ?? pluginDefaultCollectionFile;
32-
if (collection) {
33-
console.error("postman collection file path not got.");
34-
return;
35-
}
3632
await postManToOpenApi(collection, pluginSpecYamlFile, { defaultTag: "General" });
3733
}
3834

server/node-service/scripts/openApiDataSourceTemplate.tpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const <%=id %>Plugin: DataSourcePlugin<any, DataSourceConfigType> = {
3333
category: "api",
3434
dataSourceConfig,
3535
queryConfig: async () => {
36-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
36+
const { actions, categories } = await parseOpenApi(spec<% if (isJsonSpec) { %> as unknown<% } %> as OpenAPI.Document, parseOptions);
3737
return {
3838
type: "query",
3939
label: "Action",
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import pino from "pino";
2+
3+
global.logger = pino();

server/node-service/src/global.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Logger } from "pino";
2+
3+
declare global {
4+
var logger: Logger;
5+
}
6+
7+
export {};

server/node-service/src/plugins/circleCi/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ const circleCiPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
5858
category: "api",
5959
dataSourceConfig,
6060
queryConfig: async () => {
61-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
61+
const { actions, categories } = await parseOpenApi(
62+
spec as unknown as OpenAPI.Document,
63+
parseOptions
64+
);
6265
return {
6366
type: "query",
6467
label: "Action",

server/node-service/src/plugins/couchdb/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const couchdbPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
6060
category: "database",
6161
dataSourceConfig,
6262
queryConfig: async () => {
63-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
63+
const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions);
6464
return {
6565
type: "query",
6666
label: "Operation",

server/node-service/src/plugins/front/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const frontPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
3737
category: "api",
3838
dataSourceConfig,
3939
queryConfig: async () => {
40-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
40+
const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions);
4141
return {
4242
type: "query",
4343
label: "Action",

server/node-service/src/plugins/huggingFace/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ const huggingFacePlugin: DataSourcePlugin<any, DataSourceConfigType> = {
3939
category: "api",
4040
dataSourceConfig,
4141
queryConfig: async () => {
42-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
42+
const { actions, categories } = await parseOpenApi(
43+
spec as unknown as OpenAPI.Document,
44+
parseOptions
45+
);
4346
return {
4447
type: "query",
4548
label: "Action",

server/node-service/src/plugins/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import supabaseStoragePlugin from "./supabaseStorage";
2626
import cloudinaryPlugin from "./cloudinary";
2727
import notionPlugin from "./notion";
2828
import datadogPlugin from "./datadog";
29+
import twilioPlugin from "./twilio";
2930

3031
let plugins: (DataSourcePlugin | DataSourcePluginFactory)[] = [
3132
s3Plugin,
@@ -56,6 +57,7 @@ let plugins: (DataSourcePlugin | DataSourcePluginFactory)[] = [
5657
cloudinaryPlugin,
5758
notionPlugin,
5859
datadogPlugin,
60+
twilioPlugin,
5961
];
6062

6163
try {

server/node-service/src/plugins/jira/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ const jiraPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
4646
category: "api",
4747
dataSourceConfig,
4848
queryConfig: async () => {
49-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
49+
const { actions, categories } = await parseOpenApi(
50+
spec as unknown as OpenAPI.Document,
51+
parseOptions
52+
);
5053
return {
5154
type: "query",
5255
label: "Action",

server/node-service/src/plugins/n8n/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const n8nPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
5858
category: "api",
5959
dataSourceConfig,
6060
queryConfig: async () => {
61-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
61+
const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions);
6262
return {
6363
type: "query",
6464
label: "Operation",

server/node-service/src/plugins/oneSignal/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ const oneSignalPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
4747
category: "api",
4848
dataSourceConfig,
4949
queryConfig: async () => {
50-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
50+
const { actions, categories } = await parseOpenApi(spec as OpenAPI.Document, parseOptions);
5151
return {
5252
type: "query",
5353
label: "Action",

server/node-service/src/plugins/openApi/parse.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import {
1717
isOas3RefObject,
1818
isSwagger2HttpMethods,
1919
isValidHttpMethods,
20+
mergeCategories,
2021
specVersion,
2122
} from "./util";
2223

@@ -168,10 +169,32 @@ export const defaultParseOpenApiOptions: Required<ParseOpenApiOptions> = {
168169
},
169170
};
170171

172+
interface OpenAPIParseResult {
173+
actions: ActionConfig[];
174+
categories: ActionCategory[];
175+
}
176+
177+
export async function parseMultiOpenApi(
178+
spec: (OpenAPI.Document | string)[],
179+
options?: ParseOpenApiOptions
180+
): Promise<OpenAPIParseResult> {
181+
const results = await Promise.all(spec.map((i) => parseOpenApi(i, options)));
182+
const reducedResults = results.reduce(
183+
(a, b) => {
184+
return {
185+
actions: a.actions.concat(b.actions),
186+
categories: mergeCategories(a.categories, b.categories),
187+
};
188+
},
189+
{ actions: [], categories: [] }
190+
);
191+
return reducedResults;
192+
}
193+
171194
export async function parseOpenApi(
172-
specJsonOrObj: any,
195+
specJsonOrObj: OpenAPI.Document | string,
173196
options?: ParseOpenApiOptions
174-
): Promise<{ actions: ActionConfig[]; categories: ActionCategory[] }> {
197+
): Promise<OpenAPIParseResult> {
175198
let spec = specJsonOrObj;
176199
if (typeof specJsonOrObj === "string") {
177200
spec = JSON.parse(specJsonOrObj);

server/node-service/src/plugins/openApi/util.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,40 @@ function fixServers(server: OpenAPIV3.ServerObject, url: string) {
271271
}
272272
}
273273

274+
export function traversalOpenApiOperation(
275+
schema: OpenAPI.Document,
276+
fn: (operation: OpenAPI.Operation) => void
277+
) {
278+
Object.values(schema.paths || {}).forEach(
279+
(pathObj: OpenAPIV2.PathItemObject | OpenAPIV3.PathItemObject) => {
280+
Object.entries(pathObj).forEach(([key, value]) => {
281+
if (
282+
Object.values(OpenAPIV2.HttpMethods).includes(key as OpenAPIV2.HttpMethods) ||
283+
Object.values(OpenAPIV3.HttpMethods).includes(key as OpenAPIV3.HttpMethods)
284+
) {
285+
fn(value);
286+
}
287+
});
288+
}
289+
);
290+
}
291+
292+
export function appendTags(schema: OpenAPI.Document, tag: string) {
293+
if (!schema.tags) {
294+
schema.tags = [{ name: tag }];
295+
} else if (!schema.tags.find((i) => i.name === tag)) {
296+
schema.tags.push({ name: tag });
297+
}
298+
299+
traversalOpenApiOperation(schema, (op) => {
300+
if (!op.tags) {
301+
op.tags = [tag];
302+
} else if (!op.tags.includes(tag)) {
303+
op.tags.push(tag);
304+
}
305+
});
306+
}
307+
274308
export function replaceServersUrl(schema: OpenAPIV3.Document, url: string) {
275309
if (schema.servers) {
276310
// Root level servers array's fixup

server/node-service/src/plugins/sendGrid/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ const sendGridPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
2626
category: "api",
2727
dataSourceConfig,
2828
queryConfig: async () => {
29-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
29+
const { actions, categories } = await parseOpenApi(
30+
spec as unknown as OpenAPI.Document,
31+
parseOptions
32+
);
3033
return {
3134
type: "query",
3235
label: "Action",

server/node-service/src/plugins/slack/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ const slackPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
2626
category: "api",
2727
dataSourceConfig,
2828
queryConfig: async () => {
29-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
29+
const { actions, categories } = await parseOpenApi(
30+
spec as unknown as OpenAPI.Document,
31+
parseOptions
32+
);
3033
return {
3134
type: "query",
3235
label: "Action",

server/node-service/src/plugins/supabaseStorage/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,10 @@ const supabaseStoragePlugin: DataSourcePlugin<any, DataSourceConfigType> = {
2828
category: "api",
2929
dataSourceConfig,
3030
queryConfig: async () => {
31-
const { actions, categories } = await parseOpenApi(spec, parseOptions);
31+
const { actions, categories } = await parseOpenApi(
32+
spec as unknown as OpenAPI.Document,
33+
parseOptions
34+
);
3235
return {
3336
type: "query",
3437
label: "Action",
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { readYaml } from "../../common/util";
2+
import _ from "lodash";
3+
import fs from "fs";
4+
import path from "path";
5+
import { OpenAPI } from "openapi-types";
6+
import { ConfigToType, DataSourcePlugin } from "openblocks-sdk/dataSource";
7+
import { runOpenApi } from "../openApi";
8+
import { parseMultiOpenApi, ParseOpenApiOptions } from "../openApi/parse";
9+
import { appendTags } from "../openApi/util";
10+
11+
function genTagFromFileName(name: string) {
12+
const fileName = name.replace(/\.yaml|twilio_/g, "");
13+
const parts = fileName.split("_");
14+
return parts.reduce((a, b) => {
15+
if (/v\d+/.test(b)) {
16+
return `${a}(${b})`;
17+
}
18+
return a + _.upperFirst(b);
19+
}, "");
20+
}
21+
22+
const specList: OpenAPI.Document[] = [];
23+
24+
const start = performance.now();
25+
const specFiles = fs.readdirSync(path.join(__dirname, "./twilio.spec"));
26+
specFiles.forEach((specFile) => {
27+
const spec = readYaml(path.join(__dirname, "./twilio.spec", specFile));
28+
appendTags(spec, genTagFromFileName(specFile));
29+
specList.push(spec);
30+
});
31+
logger.info("twilio spec list loaded, duration: %d ms", performance.now() - start);
32+
33+
const dataSourceConfig = {
34+
type: "dataSource",
35+
params: [
36+
{
37+
type: "textInput",
38+
key: "accountSid_authToken.username",
39+
label: "SID",
40+
placeholder: "<SID>",
41+
},
42+
{
43+
type: "password",
44+
key: "accountSid_authToken.password",
45+
label: "Secret",
46+
placeholder: "<Secret>",
47+
},
48+
],
49+
} as const;
50+
51+
const parseOptions: ParseOpenApiOptions = {
52+
actionLabel: (method: string, path: string, operation: OpenAPI.Operation) => {
53+
return _.upperFirst(operation.operationId || "");
54+
},
55+
};
56+
57+
type DataSourceConfigType = ConfigToType<typeof dataSourceConfig>;
58+
59+
const twilioPlugin: DataSourcePlugin<any, DataSourceConfigType> = {
60+
id: "twilio",
61+
name: "Twilio",
62+
icon: "twilio.svg",
63+
category: "api",
64+
dataSourceConfig,
65+
queryConfig: async () => {
66+
const { actions, categories } = await parseMultiOpenApi(specList, parseOptions);
67+
return {
68+
type: "query",
69+
label: "Action",
70+
categories: {
71+
label: "Resources",
72+
items: categories,
73+
},
74+
actions,
75+
};
76+
},
77+
run: function (actionData, dataSourceConfig): Promise<any> {
78+
const runApiDsConfig = {
79+
url: "",
80+
serverURL: "",
81+
dynamicParamsConfig: dataSourceConfig,
82+
};
83+
return runOpenApi(actionData, runApiDsConfig, specList);
84+
},
85+
};
86+
87+
export default twilioPlugin;

0 commit comments

Comments
 (0)