@superblocksteam/cli 2.0.3-next.201 → 2.0.3-next.203
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.js +5 -5
- package/oclif.manifest.json +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ $ npm install -g @superblocksteam/cli
|
|
|
14
14
|
$ superblocks COMMAND
|
|
15
15
|
running command...
|
|
16
16
|
$ superblocks (--version)
|
|
17
|
-
@superblocksteam/cli/2.0.3-next.
|
|
17
|
+
@superblocksteam/cli/2.0.3-next.203 linux-x64 node-v20.19.0
|
|
18
18
|
$ superblocks --help [COMMAND]
|
|
19
19
|
USAGE
|
|
20
20
|
$ superblocks COMMAND
|
package/dist/index.js
CHANGED
|
@@ -292446,7 +292446,7 @@ var templates = {
|
|
|
292446
292446
|
"shim-loader.mjs": 'import path from "path";\nimport { pathToFileURL } from "url";\n\nconst overrideMap = {\n "@superblocksteam/library": "./dist/superblocks-library-shim/index.js",\n};\n\nexport async function resolve(specifier, context, nextResolve) {\n if (overrideMap[specifier]) {\n const fullPath = path.resolve(overrideMap[specifier]);\n return {\n shortCircuit: true,\n url: pathToFileURL(fullPath).href,\n };\n }\n\n return nextResolve(specifier, context);\n}\n',
|
|
292447
292447
|
"src/do-eval-to-sdk.ts": 'import fs from "fs";\nimport path from "path";\nimport { fileURLToPath } from "url";\n\n// finds all JavaScript files in the `dist/apis-to-transform` directory,\n// imports each module, converts its JSON representation to SDK,\n// and outputs a JSON map with filenames as keys and SDK content as values.\n\nasync function main() {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n\n const apisDir = path.resolve(__dirname, "./to-sdk");\n\n const files = fs.readdirSync(apisDir);\n\n const jsFiles = files.filter(\n (file) => file.endsWith(".js") && file !== "__template__.js",\n );\n\n const results: Record<string, string> = {};\n\n for (const jsFile of jsFiles) {\n const filePath = path.join(apisDir, jsFile);\n const absolutePath = path.resolve(filePath);\n\n try {\n const fileUrl = new URL(`file://${absolutePath}`);\n const module = await import(fileUrl.href);\n\n const defaultExport = module.default;\n\n if (defaultExport && typeof defaultExport.toSDK === "function") {\n const sdkData = await defaultExport.toSDK();\n\n results[jsFile] = sdkData;\n } else {\n console.warn(`${jsFile}: Default export doesn\'t have a toSDK method`);\n }\n } catch (error) {\n console.error(`Error processing ${jsFile}:`, error);\n }\n }\n\n console.log(JSON.stringify(results, null, 2));\n}\n\nmain().catch((error) => {\n console.error("Error:", error);\n process.exit(1);\n});\n',
|
|
292448
292448
|
"src/do-eval-to-yaml.ts": 'import fs from "fs";\nimport path from "path";\nimport { fileURLToPath } from "url";\nimport yaml from "yaml";\n\n// finds all JavaScript files in the `dist/apis-to-transform` directory,\n// imports each module, converts its JSON representation to YAML,\n// and outputs a JSON map with filenames as keys and YAML content as values.\n\nasync function main() {\n const __filename = fileURLToPath(import.meta.url);\n const __dirname = path.dirname(__filename);\n\n const apisDir = path.resolve(__dirname, "./to-yaml");\n\n const files = fs.readdirSync(apisDir);\n\n const jsFiles = files.filter((file) => file.endsWith(".js"));\n\n const results: Record<string, string> = {};\n\n for (const jsFile of jsFiles) {\n const filePath = path.join(apisDir, jsFile);\n const absolutePath = path.resolve(filePath);\n\n try {\n const fileUrl = new URL(`file://${absolutePath}`);\n const module = await import(fileUrl.href);\n\n const defaultExport = module.default;\n\n if (defaultExport && typeof defaultExport.toJSON === "function") {\n const jsonData = await defaultExport.toJSON();\n\n const yamlContent = yaml.stringify(jsonData);\n\n results[jsFile] = yamlContent;\n } else {\n console.warn(`${jsFile}: Default export doesn\'t have a toJSON method`);\n }\n } catch (error) {\n console.error(`Error processing ${jsFile}:`, error);\n }\n }\n\n console.log(JSON.stringify(results, null, 2));\n}\n\nmain().catch((error) => {\n console.error("Error:", error);\n process.exit(1);\n});\n',
|
|
292449
|
-
"src/superblocks-library-shim/index.ts": '/* eslint-disable */\nimport typescript_eslint_parser from "@typescript-eslint/parser";\nimport { CallExpression, ExpressionStatement, FunctionExpression, Node, parse, Program, UnaryExpression } from "acorn";\nimport { ESLint } from "eslint";\nimport { format } from "prettier";\n\nexport type JsonValue =\n | undefined\n | null\n | number\n | string\n | boolean\n | Array<JsonValue>\n | { [key: string]: JsonValue };\nexport type State = { [key: string]: JsonValue };\nexport type Binding<T> = T | ((state: State) => T);\n\n// DEPRECATED\nexport const code = (\n fn: string,\n options: { iife?: boolean } = { iife: false },\n): string => {\n // Parse the function string\n const ast = parse(fn, {\n ecmaVersion: "latest",\n sourceType: "script",\n });\n\n // Find the function declaration/expression\n let functionNode;\n\n // Walk through the AST to find the function\n if (ast.body[0].type === "FunctionDeclaration") {\n // Function declaration: function name() {}\n functionNode = ast.body[0];\n } else if (\n ast.body[0].type === "ExpressionStatement" &&\n (ast.body[0].expression.type === "FunctionExpression" ||\n ast.body[0].expression.type === "ArrowFunctionExpression")\n ) {\n // Function expression: const name = function() {} or const name = () => {}\n functionNode = ast.body[0].expression;\n } else if (\n ast.body[0].type === "VariableDeclaration" &&\n (ast.body[0].declarations[0]?.init?.type === "FunctionExpression" ||\n ast.body[0].declarations[0]?.init?.type === "ArrowFunctionExpression")\n ) {\n // Variable declaration: const name = function() {} or const name = () => {}\n functionNode = ast.body[0].declarations[0]?.init;\n }\n\n if (!functionNode) {\n throw new Error("Could not find a function in the provided string");\n }\n\n // Get the function body\n const body = functionNode.body;\n\n // Extract the source from the original string\n // For arrow functions with an expression body, we return the expression\n if (\n functionNode.type === "ArrowFunctionExpression" &&\n body.type !== "BlockStatement"\n ) {\n // Arrow function with expression body: () => 42\n const expressionCode = fn.substring(fn.indexOf("=>") + 2).trim();\n return options.iife\n ? `(() => ${expressionCode})()`\n : `return ${expressionCode}`;\n }\n\n // For functions with block bodies, extract content between braces\n const start = body.start + 1; // Skip the opening brace\n const end = body.end - 1; // Skip the closing brace\n\n // Get the raw body content\n const rawBodyLines = fn.substring(start, end).split("\\n");\n\n if (rawBodyLines.length <= 1) {\n // Single line body, just trim it\n const bodyCode = rawBodyLines[0].trim();\n\n if (options.iife) {\n const paramStart = fn.indexOf("(");\n const paramEnd = fn.indexOf(")", paramStart);\n const params = fn.substring(paramStart, paramEnd + 1);\n return `(${params} => { ${bodyCode} })()`;\n }\n\n return bodyCode;\n }\n\n // For multi-line bodies, normalize indentation\n // Find the minimum indentation level (ignoring empty lines)\n let minIndent = Infinity;\n for (const line of rawBodyLines) {\n const trimmedLine = line.trimStart();\n if (trimmedLine.length > 0) {\n const indent = line.length - trimmedLine.length;\n minIndent = Math.min(minIndent, indent);\n }\n }\n\n // Remove the common indentation from each line\n const normalizedLines = rawBodyLines.map((line) => {\n if (line.trimStart().length === 0) return "";\n return line.substring(minIndent);\n });\n\n // Join the normalized lines\n const bodyCode = normalizedLines\n .join(" ")\n .replace(/\\s{2,}/g, " ")\n .trim();\n\n if (options.iife) {\n const paramStart = fn.indexOf("(");\n const paramEnd = fn.indexOf(")", paramStart);\n const params = fn.substring(paramStart, paramEnd + 1);\n return `(${params} => { ${bodyCode} })()`;\n }\n\n return bodyCode;\n};\n\nasync function binding(binding: Binding<string>): Promise<string> {\n if (typeof binding === "function") {\n // (() => 5)() -> `${(() => 5)()}`\n return `\\`\\$\\{${await toJS(binding)}\\}\\``;\n }\n\n return `\\`${binding}\\``;\n}\n\ninterface Codec {\n toJSON(): Promise<JsonValue>;\n toSDK(entities: string[]): Promise<string>;\n}\n\nexport abstract class Block implements Codec {\n protected name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n public abstract toJSON(): Promise<JsonValue>;\n public abstract toSDK(entities: string[]): Promise<string>;\n\n public static fromJSON(json: any, entities: string[]): Block {\n if (json?.step) {\n return Integration.fromJSON(json, entities);\n }\n\n if ("conditional" in json) {\n return Conditional.fromJSON(json, entities);\n }\n\n if ("loop" in json) {\n return Loop.fromJSON(json, entities);\n }\n\n if ("parallel" in json) {\n return Parallel.fromJSON(json, entities);\n }\n\n if ("tryCatch" in json) {\n return TryCatch.fromJSON(json, entities);\n }\n\n if ("variables" in json) {\n return Variables.fromJSON(json, entities);\n }\n\n if ("throw" in json) {\n return Throw.fromJSON(json, entities);\n }\n\n if ("return" in json) {\n return Return.fromJSON(json, entities);\n }\n\n throw new Error("mysterious block");\n }\n}\n\nexport abstract class Integration extends Block {\n protected integration: string;\n\n constructor(name: string, integration: string) {\n super(name);\n\n this.integration = integration;\n }\n\n public abstract toJSON(): Promise<JsonValue>;\n public abstract toSDK(entities: string[]): Promise<string>;\n\n public static fromJSON(json: any, entities: string[]): Block {\n if ("javascript" in json?.step) {\n return JavaScript.fromJSON(json, entities);\n }\n\n if ("python" in json?.step) {\n return Python.fromJSON(json, entities);\n }\n\n if ("postgres" in json?.step) {\n return PostgreSQL.fromJSON(json, entities);\n }\n\n if ("databricks" in json?.step) {\n return Databricks.fromJSON(json, entities);\n }\n\n if ("email" in json?.step) {\n return Email.fromJSON(json, entities);\n }\n\n if ("restapi" in json?.step || "restapiintegration" in json?.step) {\n return RestApi.fromJSON(json, entities);\n }\n\n if ("jira" in json?.step) {\n return Jira.fromJSON(json, entities);\n }\n\n if ("github" in json?.step) {\n return GitHub.fromJSON(json, entities);\n }\n\n throw new Error("mysterious integration");\n }\n}\n\nexport class Python extends Integration {\n private fn: string;\n\n constructor(name: string, config: {\n fn: string;\n }) {\n super(name, "python");\n\n this.fn = config.fn;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "python",\n python: {\n body: this.fn,\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Python("${this.name}", { fn: ${this.fn} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Python {\n return new Python(json?.name, {\n fn: json?.step?.python?.body,\n });\n }\n}\n\nexport class JavaScript extends Integration {\n private fn: (_: State) => JsonValue;\n\n constructor(\n name: string,\n config: {\n fn: (_: State) => JsonValue;\n },\n ) {\n super(name, "javascript");\n\n this.fn = config.fn;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "javascript",\n javascript: {\n body: await toJSBody(this.fn, { block: false, function: true }),\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new JavaScript("${this.name}", { fn: ${signature(code(this.fn.toString()), entities)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): JavaScript {\n const args = [json?.step?.javascript?.body]\n const references = referenced(json?.step?.javascript?.body, entities)\n\n if (references.length > 0) {\n args.unshift(`{ ${references.join(", ")} }`)\n }\n\n return new JavaScript(json?.name, {\n fn: new Function(...args) as (_: State) => JsonValue,\n });\n }\n}\n\n// TODO(Frank): There is way too much in common between Snowflake and PostgreSQL. Need to add a parent class for these.\nexport class Snowflake extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n snowflake: {\n body: await binding(this.statement),\n usePreparedSql: false,\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Snowflake("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2(await toJSBody(this.statement), entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Snowflake {\n return new Snowflake(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.snowflake?.body as string | undefined,\n entities,\n ),\n });\n }\n}\n\nexport class PostgreSQL extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n postgres: {\n body: await binding(this.statement),\n usePreparedSql: false,\n operation: "run_sql",\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new PostgreSQL("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2(await toJSBody(this.statement), entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): PostgreSQL {\n return new PostgreSQL(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.postgres?.body as string | undefined,\n entities,\n ),\n });\n }\n}\n\nexport class RestApi extends Integration {\n private method: string;\n private url: Binding<string>;\n private headers?: { key: Binding<string>; value: Binding<string> }[];\n private params?: { key: Binding<string>; value: Binding<string> }[];\n private body?: Binding<string>;\n private openapi?: {\n path: string;\n }\n \n protected type: string;\n\n constructor(\n name: string,\n integration: string = "restapi",\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration);\n\n this.method = config.method;\n this.url = config.url;\n this.headers = config.headers;\n this.params = config.params;\n this.body = config.body;\n this.openapi = openapi;\n this.type = this.isIntegration() ? "restapiintegration" : "restapi"\n }\n\n public async toJSON(): Promise<JsonValue> {\n const openApiAction = (): string => {\n if (!this.isIntegration()) {\n return undefined;\n }\n\n if (this.openapi?.path) {\n let path: string = this.openapi.path.trim();\n\n if (path.startsWith("`") && path.endsWith("`")) {\n path = path.slice(1, -1);\n }\n\n return `${this.method} ${path}`;\n }\n\n return \'genericHttpRequest\';\n }\n\n return {\n name: this.name,\n step: {\n integration: this.integration,\n [this.type]: {\n httpMethod: this.method,\n openApiAction: openApiAction(),\n ...(this.url ? { [this.isIntegration() ? "urlPath" : "path"]: await binding(this.url) } : {}),\n ...(this.headers ? { headers: await Promise.all(this.headers.map(async (header) => ({ key: await binding(header.key), value: await binding(header.value) }))) } : {}),\n ...(this.params ? { params: await Promise.all(this.params.map(async (param) => ({ key: await binding(param.key), value: await binding(param.value) }))) } : {}),\n ...(this.body ? { body: await binding(this.body) } : {}),\n\n // Other params that I might need to add.\n responseType: "auto",\n bodyType: "jsonBody",\n },\n },\n };\n }\n\n private isIntegration(): boolean {\n return this.integration !== "restapi";\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new RestApi(${await this.constructorParametersString(entities)})`;\n }\n\n protected async constructorParametersString(entities: string[]): Promise<string> {\n const parts: string[] = [`method: "${this.method}"`];\n\n if (this.url) {\n parts.push(\n `url: ${\n typeof this.url === "function"\n ? signatureV2(await toJSBody(this.url), entities)\n : `"${this.url}"`\n }`,\n );\n }\n\n if (this.headers) {\n const headers = (\n await Promise.all(this.headers.map(async (h) =>\n `{ key: ${\n typeof h.key === "function"\n ? signatureV2(await toJSBody(h.key), entities)\n : `"${h.key}"`\n }, value: ${\n typeof h.value === "function"\n ? signatureV2(await toJSBody(h.value), entities)\n : `"${h.value}"`\n } }`,\n ))\n ).join(", ");\n parts.push(`headers: [${headers}]`);\n }\n\n if (this.params) {\n const params = (\n await Promise.all(this.params.map(async (p) =>\n `{ key: ${\n typeof p.key === "function"\n ? signatureV2(await toJSBody(p.key), entities)\n : `"${p.key}"`\n }, value: ${\n typeof p.value === "function"\n ? signatureV2(await toJSBody(p.value), entities)\n : `"${p.value}"`\n } }`,\n ))\n ).join(", ");\n parts.push(`params: [${params}]`);\n }\n\n if (this.body) {\n parts.push(\n `body: ${\n typeof this.body === "function"\n ? signatureV2(await toJSBody(this.body), entities)\n : JSON.stringify(this.body)\n }`,\n );\n }\n\n return `"${this.name}", "${this.integration}", { ${parts.join(", ")} }, ${JSON.stringify(this.openapi)}`\n }\n\n public static fromJSON(json: any, entities: string[]): RestApi {\n const config = json?.step?.[json?.step?.integration === "restapi" ? "restapi" : "restapiintegration"]\n\n if (json?.step?.integration === "restapiintegration") {\n return new RestApi(json?.name, json?.step?.integration, OpenApi.configFromJSON(config, entities), OpenApi.openapiFromJSON(config))\n }\n\n return new RestApi(json?.name, json?.step?.integration, {\n method: config?.httpMethod,\n url: fromBinding(config?.path, entities),\n headers: config?.headers?.map((header: any) => ({ key: fromBinding(header.key, entities), value: fromBinding(header.value, entities) })),\n params: config?.params?.map((param: any) => ({ key: fromBinding(param.key, entities), value: fromBinding(param.value, entities) })),\n body: fromBinding(config?.body, entities),\n }, OpenApi.openapiFromJSON(config));\n }\n}\n\nexport class OpenApi extends RestApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n }\n\n public static configFromJSON(json: any, entities: string[]): {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n } {\n return {\n method: json?.httpMethod,\n url: fromBinding(json?.urlPath, entities),\n headers: json?.headers?.map((header: any) => ({ key: fromBinding(header.key, entities), value: fromBinding(header.value, entities) })),\n params: json?.params?.map((param: any) => ({ key: fromBinding(param.key, entities), value: fromBinding(param.value, entities) })),\n body: fromBinding(json?.body, entities),\n }\n }\n\n public static openapiFromJSON(json: any): {\n path: string;\n } {\n return json?.openApiAction && json.openApiAction !== "" && json.openApiAction !== "genericHttpRequest" ? { path: json.openApiAction.split(" ")[1] } : undefined\n }\n}\n\nexport class Jira extends OpenApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n this.type = "jira"\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Jira(${await this.constructorParametersString(entities)})`;\n }\n\n public static fromJSON(json: any, entities: string[]): Jira {\n return new Jira(json?.name, json?.step?.integration, OpenApi.configFromJSON(json?.step?.jira, entities), OpenApi.openapiFromJSON(json?.step?.jira))\n }\n}\n\nexport class GitHub extends OpenApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n this.type = "github"\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new GitHub(${await this.constructorParametersString(entities)})`;\n }\n\n public static fromJSON(json: any, entities: string[]): GitHub {\n return new GitHub(json?.name, json?.step?.integration, OpenApi.configFromJSON(json?.step?.github, entities), OpenApi.openapiFromJSON(json?.step?.github))\n }\n}\n\nexport class Email extends Integration {\n private subject: Binding<string>;\n private from: Binding<string>; // comma separated list\n private to: Binding<string>; // comma separated list\n private cc?: Binding<string>; // comma separated list\n private bcc?: Binding<string>; // comma separated list\n private body: Binding<string>;\n\n constructor(\n name: string,\n config: {\n from: Binding<string>;\n to: Binding<string>;\n subject: Binding<string>;\n cc?: Binding<string>;\n bcc?: Binding<string>;\n body?: Binding<string>;\n },\n ) {\n super(name, "email");\n\n this.from = config.from;\n this.to = config.to;\n this.subject = config.subject;\n this.cc = config.cc;\n this.bcc = config.bcc;\n this.body = config.body;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "email",\n email: {\n ...(this.from ? { emailFrom: await binding(this.from) } : {}),\n ...(this.to ? { emailTo: await binding(this.to) } : {}),\n ...(this.cc ? { emailCc: await binding(this.cc) } : {}),\n ...(this.bcc ? { emailBcc: await binding(this.bcc) } : {}),\n ...(this.subject ? { emailSubject: await binding(this.subject) } : {}),\n ...(this.body ? { emailBody: await binding(this.body) } : {}),\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n const parts: string[] = [];\n\n if (this.from) {\n parts.push(\n `from: ${\n typeof this.from === "function"\n ? signatureV2(code(this.from.toString()), entities)\n : `"${this.from}"`\n }`,\n );\n }\n\n if (this.to) {\n parts.push(\n `to: ${\n typeof this.to === "function"\n ? signatureV2(code(this.to.toString()), entities)\n : `"${this.to}"`\n }`,\n );\n }\n\n if (this.cc) {\n parts.push(\n `cc: ${\n typeof this.cc === "function"\n ? signatureV2(code(this.cc.toString()), entities)\n : `"${this.cc}"`\n }`,\n );\n }\n\n if (this.bcc) {\n parts.push(\n `bcc: ${\n typeof this.bcc === "function"\n ? signatureV2(code(this.bcc.toString()), entities)\n : `"${this.bcc}"`\n }`,\n );\n }\n\n if (this.subject) {\n parts.push(\n `subject: ${\n typeof this.subject === "function"\n ? signatureV2(code(this.subject.toString()), entities)\n : `"${this.subject}"`\n }`,\n );\n }\n\n if (this.body) {\n parts.push(\n `body: ${\n typeof this.body === "function"\n ? signatureV2(code(this.body.toString()), entities)\n : `"${this.body}"`\n }`,\n );\n }\n\n return `new Email("${this.name}", { ${parts.join(", ")} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Email {\n return new Email(json?.name, {\n from: fromBinding(json?.step?.email?.emailFrom, entities),\n to: fromBinding(json?.step?.email?.emailTo, entities),\n subject: fromBinding(json?.step?.email?.emailSubject, entities),\n body: fromBinding(json?.step?.email?.emailBody, entities),\n cc: json?.step?.email?.emailCc ? fromBinding(json?.step?.email?.emailCc, entities) : undefined,\n bcc: json?.step?.email?.emailBcc ? fromBinding(json?.step?.email?.emailBcc, entities) : undefined,\n });\n }\n}\n\nexport class Databricks extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n databricks: {\n runSql: {\n sqlBody: await binding(this.statement),\n useParameterized: false,\n },\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Databricks("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2(await toJSBody(this.statement), entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Databricks {\n return new Databricks(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.databricks?.runSql?.sqlBody as string,\n entities,\n ),\n });\n }\n}\n\nexport type Condition = {\n when: Binding<boolean>;\n then: Block[];\n};\n\nasync function conditionToSDK(condition: Condition, entities: string[]): Promise<string> {\n return `{ when: ${typeof condition.when === "function" ? signatureV2(await toJSBody(condition.when), entities) : condition.when}, then: [${(await Promise.all(condition.then.map(async (block) => await block.toSDK(entities)))).join(",")}] }`\n}\n\nexport type Conditions = {\n if: Condition;\n elif?: Condition[];\n else?: Block[];\n};\n\nexport class Conditional extends Block {\n public conditions: Conditions;\n\n constructor(name: string, config: Conditions) {\n super(name);\n\n this.conditions = config;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n conditional: {\n if: {\n condition: await toJS<boolean>(this.conditions.if.when),\n blocks: await Promise.all(this.conditions.if.then.map(async (block) => await block.toJSON())),\n },\n ...await (async () =>\n this.conditions.elif\n ? {\n elseIf: await Promise.all(this.conditions.elif.map(async (condition) => ({\n condition: await toJS<boolean>(condition.when),\n blocks: await Promise.all(condition.then.map(async (block) => await block.toJSON())),\n }))),\n }\n : { elseIf: [] })(),\n else: this.conditions.else ? {\n blocks: await Promise.all(this.conditions.else.map(async (block) => await block.toJSON()))\n } : undefined,\n },\n };\n }\n\n public static fromJSON(json: any, entities: string[]): Conditional {\n return new Conditional(json?.name, {\n if: {\n when: fromJS<boolean>(json?.conditional?.if?.condition, entities),\n then: json?.conditional?.if?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n },\n elif: json?.conditional?.elseIf ? json?.conditional?.elseIf?.map((condition: any) => ({\n when: fromJS<boolean>(condition.condition, entities),\n then: condition.blocks.map((block: any) => Block.fromJSON(block, entities)),\n })) : [],\n else: json?.conditional?.else ? json?.conditional?.else?.blocks?.map((block: any) => Block.fromJSON(block, entities)) : [],\n });\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Conditional("${this.name}", { if: ${await conditionToSDK(this.conditions.if, entities)}, elif: [${this.conditions.elif ? (await Promise.all(this.conditions.elif?.map(async (condition) => await conditionToSDK(condition, entities)))).join(",") : \'\'}], else: ${this.conditions.else ? (await Promise.all(this.conditions.else?.map(async (block) => await block.toSDK(entities)))).join(",") : "undefined"} })`;\n }\n}\n\nexport class Parallel extends Block {\n private over: Binding<JsonValue[]>;\n private blocks: Block[];\n private variables: { item: string };\n\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: { item: string };\n blocks: Block[];\n },\n ) {\n super(name);\n\n this.over = config.over;\n this.blocks = config.blocks;\n this.variables = config.variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n parallel: {\n dynamic: {\n blocks: await Promise.all(this.blocks?.map(async (block) => await block.toJSON())),\n paths: await toJS<JsonValue[]>(this.over),\n variables: this.variables,\n },\n wait: "WAIT_ALL",\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Parallel("${this.name}", { over: ${typeof this.over === "function" ? signatureV2(await toJSBody(this.over), entities) : this.over}, variables: ${this.variables}, blocks: ${await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)).join(","))} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Parallel {\n return new Parallel(json?.name, {\n over: fromJS<JsonValue[]>(json?.parallel?.dynamic?.paths, entities),\n variables: {\n item: json?.parallel?.dynamic?.variables?.item,\n },\n blocks: json?.parallel?.dynamic?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n });\n }\n}\n\nexport class Loop extends Block {\n private over: Binding<JsonValue[]>; // NOTE(Frank): Only for each loops are supported at the moment.\n private blocks: Block[];\n private variables: { item: string; index: string };\n\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: { item: string; index: string };\n blocks: Block[];\n },\n ) {\n super(name);\n\n this.over = config.over;\n this.variables = config.variables;\n this.blocks = config.blocks;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n loop: {\n range: await toJS<JsonValue[]>(this.over),\n type: "TYPE_FOREACH",\n variables: this.variables,\n blocks: await Promise.all(this.blocks.map(async (block) => await block.toJSON())),\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Loop("${this.name}", { over: ${typeof this.over === "function" ? signatureV2(await toJSBody(this.over), entities) : this.over}, variables: ${this.variables}, blocks: ${await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)).join(","))} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Loop {\n return new Loop(json?.name, {\n over: fromJS<JsonValue[]>(json?.loop?.range, entities),\n variables: {\n item: json?.loop?.variables?.item,\n index: json?.loop?.variables?.index,\n },\n blocks: json?.loop?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n });\n }\n}\n\nexport class Variables extends Block {\n private variables: { key: string, value: Binding<JsonValue> }[];\n\n constructor(\n name: string,\n variables: { key: string, value: Binding<JsonValue> }[],\n ) {\n super(name);\n\n this.variables = variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n variables: {\n items: await Promise.all(this.variables.map(async (variable) => {\n return {\n key: variable.key,\n value: await toJS<JsonValue>(variable.value),\n type: "TYPE_SIMPLE",\n mode: "MODE_READWRITE",\n };\n }))\n },\n };\n }\n \n public async toSDK(entities: string[]): Promise<string> {\n return `new Variables("${this.name}", [${this.variables?.map((variable) => `{ key: "${variable.key}", value: ${typeof variable.value === "function" ? signature(code(variable.value.toString(), { iife: true }), entities) : variable.value} }`).join(",")}])`;\n }\n\n public static fromJSON(json: any, entities: string[]): Variables {\n return new Variables(json?.name, json?.variables?.items?.map((variable: any) => ({\n key: variable.key,\n value: fromBinding(variable.value, entities),\n })));\n }\n}\n\nexport class TryCatch extends Block {\n private try: Block[];\n private catch: Block[];\n private finally?: Block[];\n private variables: { error: string };\n\n constructor(\n name: string,\n config: {\n try: Block[];\n catch: Block[];\n finally?: Block[];\n variables: { error: string };\n },\n ) {\n super(name);\n\n this.try = config.try;\n this.catch = config.catch;\n this.finally = config.finally;\n this.variables = config.variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n tryCatch: {\n try: { blocks: await Promise.all(this.try.map(async (block) => await block.toJSON())) },\n catch: { blocks: await Promise.all(this.catch.map(async (block) => await block.toJSON())) },\n finally: { blocks: this.finally ? await Promise.all(this.finally.map(async (block) => await block.toJSON())) : [] },\n variables: this.variables,\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new TryCatch("${this.name}", { try: ${await Promise.all(this.try.map(async (block) => await block.toSDK(entities)).join(","))}, catch: ${await Promise.all(this.catch.map(async (block) => await block.toSDK(entities)).join(","))}, finally: ${this.finally?.map(async (block) => await block.toSDK(entities)).join(", ")} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): TryCatch {\n return new TryCatch(json?.name, {\n try: json?.tryCatch?.try.blocks.map((block: any) => Block.fromJSON(block, entities)),\n catch: json?.tryCatch?.catch.blocks.map((block: any) => Block.fromJSON(block, entities)),\n finally: json?.tryCatch?.finally?.blocks.map((block: any) => Block.fromJSON(block, entities)),\n variables: {\n error: json?.tryCatch?.variables?.error,\n },\n });\n }\n}\n\nexport class Throw extends Block {\n private error: Binding<JsonValue>;\n\n constructor(\n name: string,\n config: {\n error: Binding<JsonValue>;\n },\n ) {\n super(name);\n\n this.error = config.error;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n throw: {\n error: await toJS<JsonValue>(this.error),\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Throw("${this.name}", { error: ${typeof this.error === "function" ? signature(code(this.error.toString()), entities) : JSON.stringify(this.error)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Throw {\n return new Throw(json?.name, {\n error: fromJS(json?.throw?.error, entities),\n });\n }\n}\n\nexport class Return extends Block {\n private data: Binding<JsonValue>;\n\n constructor(\n name: string,\n config: {\n data: Binding<JsonValue>;\n },\n ) {\n super(name);\n\n this.data = config.data;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n return: {\n data: await toJS<JsonValue>(this.data),\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Return("${this.name}", { data: ${typeof this.data === "function" ? signature(code(this.data.toString()), entities) : JSON.stringify(this.data)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Return {\n return new Return(json?.name, {\n data: fromJS(json?.return?.data, entities),\n });\n }\n}\n\nexport class Api {\n private blocks: Block[];\n private name: string;\n\n constructor(name: string, blocks: Block[]) {\n this.name = name;\n this.blocks = blocks;\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n const imports =\n "import { Api, JavaScript, Python, PostgreSQL, Snowflake, RestApi, Databricks, Conditional, Parallel, Loop, TryCatch, Variables, Throw, Return } from \'@superblocksteam/library\'";\n return `${imports}\\n\\nexport default new Api("${this.name}", [${(await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)))).join(",")}])`;\n }\n\n public static fromJSON(json: any, entities: string[]): Api {\n // NOTE(Frank): Would probs unmarshal this into the protobuf types and then do the conversion.\n return new Api(\n json?.metadata?.name as string,\n (json.blocks as any[]).map((block) => Block.fromJSON(block, entities)),\n );\n }\n\n public async toJSON(): Promise<JsonValue> {\n const api: {\n metadata: {\n name: string;\n timestamps: {\n updated: string;\n };\n };\n trigger: {\n application: {};\n };\n blocks: JsonValue[];\n } = {\n metadata: {\n name: this.name,\n timestamps: {\n updated: new Date().toISOString(),\n },\n },\n trigger: {\n application: {},\n },\n blocks: [],\n };\n\n api.blocks = await Promise.all(this.blocks.map(async (block) => await block.toJSON()));\n\n return api;\n }\n}\n\nfunction referenced(data: string, entities: string[]): string[] {\n return entities.reduce((acc: string[], entity: string) => {\n if (data.includes(entity)) {\n acc.push(entity);\n }\n return acc;\n }, []);\n}\n\nfunction signature(data: string, entities: string[]): string {\n return `({ ${referenced(data, entities).join(", ")} }) => {${data}}`;\n}\n\nfunction signatureV2(data: string, entities: string[]): string {\n return `({ ${referenced(data, entities).join(", ")} }) => ${data}`;\n}\n\n/**\n * Converts a string binding, which comprise 99% of dynamic integration fields, into a function returning an interpolated string.\n *\n * fromBinding(`https://${ \'goo\' + \'gle\' }.com/${ Dropdown1.value }`, [\'Dropdown1\']) -> ({ Dropdown1 }) => `https://${\'goo\' + \'gle\'}.com/${Dropdown1.value}`\n *\n * @param value - The value to convert.\n * @param entities - The master list of possible entities that could be referenced in the binding.\n *\n * @returns The converted value.\n */\nexport function fromBinding(value: string, entities: string[]): Binding<string> {\n if (!value) {\n return "";\n }\n\n if (!value.startsWith("`") || !value.endsWith("`")) {\n return value;\n }\n\n const args: string[] = [`return ${value}`]\n const references: string[] = referenced(value, entities);\n\n if (references.length === 0) {\n try {\n return eval(value) as string;\n } catch (e) {\n console.error(`We couldn\'t tranform the binding ${value} to the SDK. Ensure the AI hasn\'t hallucinated a variable.`);\n throw e;\n }\n }\n\n // only add the arguments if we have references\n args.unshift(`{ ${references} }`);\n\n return new Function(...args) as (_: State) => string;\n}\n\nasync function beautifyAndOptionallyCondense<T extends JsonValue>(value: ((state: State) => T), node: Node, options: { condense?: boolean, block?: boolean } = { condense: true, block: true }) {\n let start: number = node.start;\n let end: number = node.end;\n\n if (!options.block) {\n start += 1;\n end -= 1;\n }\n \n const beautified = await beautify(value.toString().slice(start, end))\n\n if (options.condense) {\n return beautified.replace(/\\s*\\n\\s*/g, \' \').replace(/\\s+/g, \' \').trim();\n }\n\n return beautified\n}\n\nfunction createAst(value: string): Program {\n return parse(value, {\n ecmaVersion: "latest",\n sourceType: "script",\n preserveParens: false,\n });\n}\n\nasync function toJSBody<T extends JsonValue>(value: ((state: State) => T), options: { block?: boolean, condense?: boolean, function?: boolean } = { block: true, condense: true, function: false }): Promise<string> {\n if (typeof value !== "function") {\n return `\\`${JSON.stringify(value)}\\``\n }\n\n // parse the code\n const ast = createAst(value.toString());\n const program = ast.body[0];\n\n switch (program.type) {\n case "ExpressionStatement":\n const body = ((program as ExpressionStatement).expression as FunctionExpression).body;\n\n if (body.type === \'BlockStatement\') {\n return await beautifyAndOptionallyCondense(value, body, options)\n }\n\n return `${options.function ? "return " : ""}${value.toString().slice(body.start, body.end)}`\n case "FunctionDeclaration":\n let contents = value.toString().slice(program.body.start, program.body.end)\n\n if (program.body.type !== \'BlockStatement\') {\n return contents\n }\n \n if (!options.function && program.body.body.length === 1 && program.body.body[0].type === \'ReturnStatement\') {\n return value.toString().slice(program.body.body[0].argument.start, program.body.body[0].argument.end)\n }\n\n return await beautifyAndOptionallyCondense(value, program.body, options)\n\n default:\n throw new Error("you found a case we haven\'t handled yet")\n }\n}\n\nexport async function toJS<T extends JsonValue>(value: Binding<T>): Promise<string> {\n return `(() => ${typeof value === "function" ? await toJSBody(value) : JSON.stringify(value)})()`\n}\n\nexport function fromJS<T extends JsonValue>(\n value: string,\n entities: string[] = [],\n): Binding<T> {\n // determine if there are entities referenced in the value\n const refs = referenced(value, entities).join(", ")\n\n // remove any surrounding whitespace\n value = value.trim()\n\n let unaryOps: string[] = [];\n let call = (createAst(value).body[0] as ExpressionStatement).expression;\n\n while (call?.type === \'UnaryExpression\') {\n unaryOps.push((call as UnaryExpression).operator);\n call = (call as unknown as UnaryExpression).argument as CallExpression;\n }\n \n const fn = (call as CallExpression).callee;\n let body = value;\n let prefix = "return ";\n\n // handle iife\n if (fn?.type === "ArrowFunctionExpression") {\n // i\'m not happy with this but I don\'t see another immediate way to handle this.\n // this will result in a correct result but one that isn\'t idemopotent.\n if (unaryOps.length > 0) {\n return new Function(`{ ${refs} }`, `${prefix}${body}`) as (_: State) => T;\n }\n\n\n body = value.slice(fn.body.start, fn.body.end)\n\n if (fn.body.type === \'BlockStatement\') {\n // drop the opening "{" and closing "}"\n body = body.slice(1, -1)\n prefix = ""\n } \n } else if (refs.length === 0) {\n // we\'re not an iife nor do we have references.\n // we might have to revisit this implementation since this technically reduces to a static value down to it\'s most minimal form.\n return eval(value) as T\n }\n\n // we\'re either an iife or a static value with refs.\n return new Function(`{ ${refs} }`, `${prefix}${body}`) as (_: State) => T;\n}\n\nexport async function beautify(code: string): Promise<string> {\n const eslint = new ESLint({\n fix: true,\n overrideConfigFile: true,\n baseConfig: {\n languageOptions: {\n parser: typescript_eslint_parser,\n parserOptions: {\n ecmaVersion: 2020,\n sourceType: "module",\n },\n },\n rules: {\n "arrow-body-style": "error",\n },\n },\n });\n\n code = (await eslint.lintText(code))[0]?.output || code;\n\n return await format(code, {\n parser: "typescript",\n tabWidth: 2,\n // singleQuote: true,\n trailingComma: "none",\n semi: true,\n bracketSpacing: true,\n arrowParens: "always",\n bracketSameLine: false,\n embeddedLanguageFormatting: "auto",\n quoteProps: "as-needed",\n insertPragma: false,\n requirePragma: false,\n useTabs: false,\n endOfLine: "auto",\n arrowFunctionParentheses: "always",\n // plugins: ["prettier-plugin-organize-imports"],\n });\n}\n',
|
|
292449
|
+
"src/superblocks-library-shim/index.ts": '/* eslint-disable */\nimport typescript_eslint_parser from "@typescript-eslint/parser";\nimport { CallExpression, ExpressionStatement, FunctionExpression, Literal, Node, parse, Program, UnaryExpression } from "acorn";\nimport { ESLint } from "eslint";\nimport { format } from "prettier";\n\nexport type JsonValue =\n | undefined\n | null\n | number\n | string\n | boolean\n | Array<JsonValue>\n | { [key: string]: JsonValue };\nexport type State = { [key: string]: JsonValue };\nexport type Binding<T> = T | ((state: State) => T);\n\nasync function binding(binding: Binding<string>): Promise<string> {\n if (typeof binding === "function") {\n const { body, node } = await toJS(binding);\n\n if (node?.type === \'Literal\' && typeof (node as Literal).value === \'string\') {\n return `\\`${(node as Literal).value}\\``;\n }\n\n if (node?.type === \'TemplateLiteral\') {\n return body;\n }\n\n return `\\`\\$\\{${body}\\}\\``;\n }\n\n return `\\`${binding}\\``;\n}\n\ninterface Codec {\n toJSON(): Promise<JsonValue>;\n toSDK(entities: string[]): Promise<string>;\n}\n\nexport abstract class Block implements Codec {\n protected name: string;\n\n constructor(name: string) {\n this.name = name;\n }\n\n public abstract toJSON(): Promise<JsonValue>;\n public abstract toSDK(entities: string[]): Promise<string>;\n\n public static fromJSON(json: any, entities: string[]): Block {\n if (json?.step) {\n return Integration.fromJSON(json, entities);\n }\n\n if ("conditional" in json) {\n return Conditional.fromJSON(json, entities);\n }\n\n if ("loop" in json) {\n return Loop.fromJSON(json, entities);\n }\n\n if ("parallel" in json) {\n return Parallel.fromJSON(json, entities);\n }\n\n if ("tryCatch" in json) {\n return TryCatch.fromJSON(json, entities);\n }\n\n if ("variables" in json) {\n return Variables.fromJSON(json, entities);\n }\n\n if ("throw" in json) {\n return Throw.fromJSON(json, entities);\n }\n\n if ("return" in json) {\n return Return.fromJSON(json, entities);\n }\n\n throw new Error("mysterious block");\n }\n}\n\nexport abstract class Integration extends Block {\n protected integration: string;\n\n constructor(name: string, integration: string) {\n super(name);\n\n this.integration = integration;\n }\n\n public abstract toJSON(): Promise<JsonValue>;\n public abstract toSDK(entities: string[]): Promise<string>;\n\n public static fromJSON(json: any, entities: string[]): Block {\n if ("javascript" in json?.step) {\n return JavaScript.fromJSON(json, entities);\n }\n\n if ("python" in json?.step) {\n return Python.fromJSON(json, entities);\n }\n\n if ("postgres" in json?.step) {\n return PostgreSQL.fromJSON(json, entities);\n }\n\n if ("databricks" in json?.step) {\n return Databricks.fromJSON(json, entities);\n }\n\n if ("email" in json?.step) {\n return Email.fromJSON(json, entities);\n }\n\n if ("restapi" in json?.step || "restapiintegration" in json?.step) {\n return RestApi.fromJSON(json, entities);\n }\n\n if ("jira" in json?.step) {\n return Jira.fromJSON(json, entities);\n }\n\n if ("github" in json?.step) {\n return GitHub.fromJSON(json, entities);\n }\n\n throw new Error("mysterious integration");\n }\n}\n\nexport class Python extends Integration {\n private fn: string;\n\n constructor(name: string, config: {\n fn: string;\n }) {\n super(name, "python");\n\n this.fn = config.fn;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "python",\n python: {\n body: this.fn,\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Python("${this.name}", { fn: ${this.fn} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Python {\n return new Python(json?.name, {\n fn: json?.step?.python?.body,\n });\n }\n}\n\nexport class JavaScript extends Integration {\n private fn: (_: State) => JsonValue;\n\n constructor(\n name: string,\n config: {\n fn: (_: State) => JsonValue;\n },\n ) {\n super(name, "javascript");\n\n this.fn = config.fn;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "javascript",\n javascript: {\n body: (await toJSBody(this.fn, { block: false, function: true })).body,\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new JavaScript("${this.name}", { fn: ${signatureV2((await toJSBody(this.fn)).body, entities)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): JavaScript {\n const args = [json?.step?.javascript?.body]\n const references = referenced(json?.step?.javascript?.body, entities)\n\n if (references.length > 0) {\n args.unshift(`{ ${references.join(", ")} }`)\n }\n\n return new JavaScript(json?.name, {\n fn: new Function(...args) as (_: State) => JsonValue,\n });\n }\n}\n\n// TODO(Frank): There is way too much in common between Snowflake and PostgreSQL. Need to add a parent class for these.\nexport class Snowflake extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n snowflake: {\n body: await binding(this.statement),\n usePreparedSql: false,\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Snowflake("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2((await toJSBody(this.statement)).body, entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Snowflake {\n return new Snowflake(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.snowflake?.body as string | undefined,\n entities,\n ),\n });\n }\n}\n\nexport class PostgreSQL extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n postgres: {\n body: await binding(this.statement),\n usePreparedSql: false,\n operation: "run_sql",\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new PostgreSQL("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2((await toJSBody(this.statement)).body, entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): PostgreSQL {\n return new PostgreSQL(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.postgres?.body as string | undefined,\n entities,\n ),\n });\n }\n}\n\nexport class RestApi extends Integration {\n private method: string;\n private url: Binding<string>;\n private headers?: { key: Binding<string>; value: Binding<string> }[];\n private params?: { key: Binding<string>; value: Binding<string> }[];\n private body?: Binding<string>;\n private openapi?: {\n path: string;\n }\n \n protected type: string;\n\n constructor(\n name: string,\n integration: string = "restapi",\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration);\n\n this.method = config.method;\n this.url = config.url;\n this.headers = config.headers;\n this.params = config.params;\n this.body = config.body;\n this.openapi = openapi;\n this.type = this.isIntegration() ? "restapiintegration" : "restapi"\n }\n\n public async toJSON(): Promise<JsonValue> {\n const openApiAction = (): string => {\n if (!this.isIntegration()) {\n return undefined;\n }\n\n if (this.openapi?.path) {\n let path: string = this.openapi.path.trim();\n\n if (path.startsWith("`") && path.endsWith("`")) {\n path = path.slice(1, -1);\n }\n\n return `${this.method} ${path}`;\n }\n\n return \'genericHttpRequest\';\n }\n\n return {\n name: this.name,\n step: {\n integration: this.integration,\n [this.type]: {\n httpMethod: this.method,\n openApiAction: openApiAction(),\n ...(this.url ? { [this.isIntegration() ? "urlPath" : "path"]: await binding(this.url) } : {}),\n ...(this.headers ? { headers: await Promise.all(this.headers.map(async (header) => ({ key: await binding(header.key), value: await binding(header.value) }))) } : {}),\n ...(this.params ? { params: await Promise.all(this.params.map(async (param) => ({ key: await binding(param.key), value: await binding(param.value) }))) } : {}),\n ...(this.body ? { body: await binding(this.body) } : {}),\n\n // Other params that I might need to add.\n responseType: "auto",\n bodyType: "jsonBody",\n },\n },\n };\n }\n\n private isIntegration(): boolean {\n return this.integration !== "restapi";\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new RestApi(${await this.constructorParametersString(entities)})`;\n }\n\n protected async constructorParametersString(entities: string[]): Promise<string> {\n const parts: string[] = [`method: "${this.method}"`];\n\n if (this.url) {\n parts.push(\n `url: ${\n typeof this.url === "function"\n ? signatureV2((await toJSBody(this.url)).body, entities)\n : `"${this.url}"`\n }`,\n );\n }\n\n if (this.headers) {\n const headers = (\n await Promise.all(this.headers.map(async (h) =>\n `{ key: ${\n typeof h.key === "function"\n ? signatureV2((await toJSBody(h.key)).body, entities)\n : `"${h.key}"`\n }, value: ${\n typeof h.value === "function"\n ? signatureV2((await toJSBody(h.value)).body, entities)\n : `"${h.value}"`\n } }`,\n ))\n ).join(", ");\n parts.push(`headers: [${headers}]`);\n }\n\n if (this.params) {\n const params = (\n await Promise.all(this.params.map(async (p) =>\n `{ key: ${\n typeof p.key === "function"\n ? signatureV2((await toJSBody(p.key)).body, entities)\n : `"${p.key}"`\n }, value: ${\n typeof p.value === "function"\n ? signatureV2((await toJSBody(p.value)).body, entities)\n : `"${p.value}"`\n } }`,\n ))\n ).join(", ");\n parts.push(`params: [${params}]`);\n }\n\n if (this.body) {\n parts.push(\n `body: ${\n typeof this.body === "function"\n ? signatureV2((await toJSBody(this.body)).body, entities)\n : JSON.stringify(this.body)\n }`,\n );\n }\n\n return `"${this.name}", "${this.integration}", { ${parts.join(", ")} }, ${JSON.stringify(this.openapi)}`\n }\n\n public static fromJSON(json: any, entities: string[]): RestApi {\n const config = json?.step?.[json?.step?.integration === "restapi" ? "restapi" : "restapiintegration"]\n\n if (json?.step?.integration === "restapiintegration") {\n return new RestApi(json?.name, json?.step?.integration, OpenApi.configFromJSON(config, entities), OpenApi.openapiFromJSON(config))\n }\n\n return new RestApi(json?.name, json?.step?.integration, {\n method: config?.httpMethod,\n url: fromBinding(config?.path, entities),\n headers: config?.headers?.map((header: any) => ({ key: fromBinding(header.key, entities), value: fromBinding(header.value, entities) })),\n params: config?.params?.map((param: any) => ({ key: fromBinding(param.key, entities), value: fromBinding(param.value, entities) })),\n body: fromBinding(config?.body, entities),\n }, OpenApi.openapiFromJSON(config));\n }\n}\n\nexport class OpenApi extends RestApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n }\n\n public static configFromJSON(json: any, entities: string[]): {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n } {\n return {\n method: json?.httpMethod,\n url: fromBinding(json?.urlPath, entities),\n headers: json?.headers?.map((header: any) => ({ key: fromBinding(header.key, entities), value: fromBinding(header.value, entities) })),\n params: json?.params?.map((param: any) => ({ key: fromBinding(param.key, entities), value: fromBinding(param.value, entities) })),\n body: fromBinding(json?.body, entities),\n }\n }\n\n public static openapiFromJSON(json: any): {\n path: string;\n } {\n return json?.openApiAction && json.openApiAction !== "" && json.openApiAction !== "genericHttpRequest" ? { path: json.openApiAction.split(" ")[1] } : undefined\n }\n}\n\nexport class Jira extends OpenApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n this.type = "jira"\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Jira(${await this.constructorParametersString(entities)})`;\n }\n\n public static fromJSON(json: any, entities: string[]): Jira {\n return new Jira(json?.name, json?.step?.integration, OpenApi.configFromJSON(json?.step?.jira, entities), OpenApi.openapiFromJSON(json?.step?.jira))\n }\n}\n\nexport class GitHub extends OpenApi {\n constructor(\n name: string,\n integration: string,\n config: {\n method: string;\n url: Binding<string>;\n headers?: { key: Binding<string>; value: Binding<string> }[];\n params?: { key: Binding<string>; value: Binding<string> }[];\n body?: Binding<string>;\n },\n openapi?: {\n path: string;\n }\n ) {\n super(name, integration, config, openapi);\n this.type = "github"\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new GitHub(${await this.constructorParametersString(entities)})`;\n }\n\n public static fromJSON(json: any, entities: string[]): GitHub {\n return new GitHub(json?.name, json?.step?.integration, OpenApi.configFromJSON(json?.step?.github, entities), OpenApi.openapiFromJSON(json?.step?.github))\n }\n}\n\nexport class Email extends Integration {\n private subject: Binding<string>;\n private from: Binding<string>; // comma separated list\n private to: Binding<string>; // comma separated list\n private cc?: Binding<string>; // comma separated list\n private bcc?: Binding<string>; // comma separated list\n private body: Binding<string>;\n\n constructor(\n name: string,\n config: {\n from: Binding<string>;\n to: Binding<string>;\n subject: Binding<string>;\n cc?: Binding<string>;\n bcc?: Binding<string>;\n body?: Binding<string>;\n },\n ) {\n super(name, "email");\n\n this.from = config.from;\n this.to = config.to;\n this.subject = config.subject;\n this.cc = config.cc;\n this.bcc = config.bcc;\n this.body = config.body;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: "email",\n email: {\n ...(this.from ? { emailFrom: await binding(this.from) } : {}),\n ...(this.to ? { emailTo: await binding(this.to) } : {}),\n ...(this.cc ? { emailCc: await binding(this.cc) } : {}),\n ...(this.bcc ? { emailBcc: await binding(this.bcc) } : {}),\n ...(this.subject ? { emailSubject: await binding(this.subject) } : {}),\n ...(this.body ? { emailBody: await binding(this.body) } : {}),\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n const parts: string[] = [];\n\n if (this.from) {\n parts.push(\n `from: ${\n typeof this.from === "function"\n ? signatureV2((await toJSBody(this.from)).body, entities)\n : `"${this.from}"`\n }`,\n );\n }\n\n if (this.to) {\n parts.push(\n `to: ${\n typeof this.to === "function"\n ? signatureV2((await toJSBody(this.to)).body, entities)\n : `"${this.to}"`\n }`,\n );\n }\n\n if (this.cc) {\n parts.push(\n `cc: ${\n typeof this.cc === "function"\n ? signatureV2((await toJSBody(this.cc)).body, entities)\n : `"${this.cc}"`\n }`,\n );\n }\n\n if (this.bcc) {\n parts.push(\n `bcc: ${\n typeof this.bcc === "function"\n ? signatureV2((await toJSBody(this.bcc)).body, entities)\n : `"${this.bcc}"`\n }`,\n );\n }\n\n if (this.subject) {\n parts.push(\n `subject: ${\n typeof this.subject === "function"\n ? signatureV2((await toJSBody(this.subject)).body, entities)\n : `"${this.subject}"`\n }`,\n );\n }\n\n if (this.body) {\n parts.push(\n `body: ${\n typeof this.body === "function"\n ? signatureV2((await toJSBody(this.body)).body, entities)\n : `"${this.body}"`\n }`,\n );\n }\n\n return `new Email("${this.name}", { ${parts.join(", ")} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Email {\n return new Email(json?.name, {\n from: fromBinding(json?.step?.email?.emailFrom, entities),\n to: fromBinding(json?.step?.email?.emailTo, entities),\n subject: fromBinding(json?.step?.email?.emailSubject, entities),\n body: fromBinding(json?.step?.email?.emailBody, entities),\n cc: json?.step?.email?.emailCc ? fromBinding(json?.step?.email?.emailCc, entities) : undefined,\n bcc: json?.step?.email?.emailBcc ? fromBinding(json?.step?.email?.emailBcc, entities) : undefined,\n });\n }\n}\n\nexport class Databricks extends Integration {\n private statement: Binding<string>;\n\n constructor(\n name: string,\n integration: string,\n config: {\n statement: Binding<string>;\n },\n ) {\n super(name, integration);\n\n this.statement = config.statement;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n step: {\n integration: this.integration,\n databricks: {\n runSql: {\n sqlBody: await binding(this.statement),\n useParameterized: false,\n },\n },\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Databricks("${this.name}", "${this.integration}", { statement: ${typeof this.statement === "function" ? signatureV2((await toJSBody(this.statement)).body, entities) : `"${this.statement}"`} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Databricks {\n return new Databricks(json?.name, json?.step?.integration, {\n statement: fromBinding(\n json?.step?.databricks?.runSql?.sqlBody as string,\n entities,\n ),\n });\n }\n}\n\nexport type Condition = {\n when: Binding<boolean>;\n then: Block[];\n};\n\nasync function conditionToSDK(condition: Condition, entities: string[]): Promise<string> {\n return `{ when: ${typeof condition.when === "function" ? signatureV2((await toJSBody(condition.when)).body, entities) : condition.when}, then: [${(await Promise.all(condition.then.map(async (block) => await block.toSDK(entities)))).join(",")}] }`\n}\n\nexport type Conditions = {\n if: Condition;\n elif?: Condition[];\n else?: Block[];\n};\n\nexport class Conditional extends Block {\n public conditions: Conditions;\n\n constructor(name: string, config: Conditions) {\n super(name);\n\n this.conditions = config;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n conditional: {\n if: {\n condition: ensureIIFE((await toJS<boolean>(this.conditions.if.when)).body),\n blocks: await Promise.all(this.conditions.if.then.map(async (block) => await block.toJSON())),\n },\n ...await (async () =>\n this.conditions.elif\n ? {\n elseIf: await Promise.all(this.conditions.elif.map(async (condition) => ({\n condition: ensureIIFE((await toJS<boolean>(condition.when)).body),\n blocks: await Promise.all(condition.then.map(async (block) => await block.toJSON())),\n }))),\n }\n : { elseIf: [] })(),\n else: this.conditions.else ? {\n blocks: await Promise.all(this.conditions.else.map(async (block) => await block.toJSON()))\n } : undefined,\n },\n };\n }\n\n public static fromJSON(json: any, entities: string[]): Conditional {\n return new Conditional(json?.name, {\n if: {\n when: fromJS<boolean>(json?.conditional?.if?.condition, entities),\n then: json?.conditional?.if?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n },\n elif: json?.conditional?.elseIf ? json?.conditional?.elseIf?.map((condition: any) => ({\n when: fromJS<boolean>(condition.condition, entities),\n then: condition.blocks.map((block: any) => Block.fromJSON(block, entities)),\n })) : [],\n else: json?.conditional?.else ? json?.conditional?.else?.blocks?.map((block: any) => Block.fromJSON(block, entities)) : [],\n });\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Conditional("${this.name}", { if: ${await conditionToSDK(this.conditions.if, entities)}, elif: [${this.conditions.elif ? (await Promise.all(this.conditions.elif?.map(async (condition) => await conditionToSDK(condition, entities)))).join(",") : \'\'}], else: ${this.conditions.else ? (await Promise.all(this.conditions.else?.map(async (block) => await block.toSDK(entities)))).join(",") : "undefined"} })`;\n }\n}\n\nexport class Parallel extends Block {\n private over: Binding<JsonValue[]>;\n private blocks: Block[];\n private variables: { item: string };\n\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: { item: string };\n blocks: Block[];\n },\n ) {\n super(name);\n\n this.over = config.over;\n this.blocks = config.blocks;\n this.variables = config.variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n parallel: {\n dynamic: {\n blocks: await Promise.all(this.blocks?.map(async (block) => await block.toJSON())),\n paths: ensureIIFE((await toJS<JsonValue[]>(this.over)).body),\n variables: this.variables,\n },\n wait: "WAIT_ALL",\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Parallel("${this.name}", { over: ${typeof this.over === "function" ? signatureV2((await toJSBody(this.over)).body, entities) : this.over}, variables: ${this.variables}, blocks: ${await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)).join(","))} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Parallel {\n return new Parallel(json?.name, {\n over: fromJS<JsonValue[]>(json?.parallel?.dynamic?.paths, entities),\n variables: {\n item: json?.parallel?.dynamic?.variables?.item,\n },\n blocks: json?.parallel?.dynamic?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n });\n }\n}\n\nexport class Loop extends Block {\n private over: Binding<JsonValue[]>; // NOTE(Frank): Only for each loops are supported at the moment.\n private blocks: Block[];\n private variables: { item: string; index: string };\n\n constructor(\n name: string,\n config: {\n over: Binding<JsonValue[]>;\n variables: { item: string; index: string };\n blocks: Block[];\n },\n ) {\n super(name);\n\n this.over = config.over;\n this.variables = config.variables;\n this.blocks = config.blocks;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n loop: {\n range: ensureIIFE((await toJS<JsonValue[]>(this.over)).body),\n type: "TYPE_FOREACH",\n variables: this.variables,\n blocks: await Promise.all(this.blocks.map(async (block) => await block.toJSON())),\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Loop("${this.name}", { over: ${typeof this.over === "function" ? signatureV2((await toJSBody(this.over)).body, entities) : this.over}, variables: ${this.variables}, blocks: ${await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)).join(","))} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Loop {\n return new Loop(json?.name, {\n over: fromJS<JsonValue[]>(json?.loop?.range, entities),\n variables: {\n item: json?.loop?.variables?.item,\n index: json?.loop?.variables?.index,\n },\n blocks: json?.loop?.blocks.map((block: any) =>\n Block.fromJSON(block, entities),\n ),\n });\n }\n}\n\nexport class Variables extends Block {\n private variables: { key: string, value: Binding<JsonValue> }[];\n\n constructor(\n name: string,\n variables: { key: string, value: Binding<JsonValue> }[],\n ) {\n super(name);\n\n this.variables = variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n variables: {\n items: await Promise.all(this.variables.map(async (variable) => {\n return {\n key: variable.key,\n value: (await toJS<JsonValue>(variable.value)).body,\n type: "TYPE_SIMPLE",\n mode: "MODE_READWRITE",\n };\n }))\n },\n };\n }\n \n public async toSDK(entities: string[]): Promise<string> {\n return `new Variables("${this.name}", [${\n (await Promise.all(\n this.variables?.map(async (variable) => (\n `{ key: "${variable.key}", value: ${typeof variable.value === "function" ? signatureV2((await toJSBody(variable.value)).body, entities) : variable.value} }`\n ))\n )).join(",")}])`;\n }\n\n public static fromJSON(json: any, entities: string[]): Variables {\n return new Variables(json?.name, json?.variables?.items?.map((variable: any) => ({\n key: variable.key,\n value: fromBinding(variable.value, entities),\n })));\n }\n}\n\nexport class TryCatch extends Block {\n private try: Block[];\n private catch: Block[];\n private finally?: Block[];\n private variables: { error: string };\n\n constructor(\n name: string,\n config: {\n try: Block[];\n catch: Block[];\n finally?: Block[];\n variables: { error: string };\n },\n ) {\n super(name);\n\n this.try = config.try;\n this.catch = config.catch;\n this.finally = config.finally;\n this.variables = config.variables;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n tryCatch: {\n try: { blocks: await Promise.all(this.try.map(async (block) => await block.toJSON())) },\n catch: { blocks: await Promise.all(this.catch.map(async (block) => await block.toJSON())) },\n finally: { blocks: this.finally ? await Promise.all(this.finally.map(async (block) => await block.toJSON())) : [] },\n variables: this.variables,\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new TryCatch("${this.name}", { try: ${await Promise.all(this.try.map(async (block) => await block.toSDK(entities)).join(","))}, catch: ${await Promise.all(this.catch.map(async (block) => await block.toSDK(entities)).join(","))}, finally: ${this.finally?.map(async (block) => await block.toSDK(entities)).join(", ")} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): TryCatch {\n return new TryCatch(json?.name, {\n try: json?.tryCatch?.try.blocks.map((block: any) => Block.fromJSON(block, entities)),\n catch: json?.tryCatch?.catch.blocks.map((block: any) => Block.fromJSON(block, entities)),\n finally: json?.tryCatch?.finally?.blocks.map((block: any) => Block.fromJSON(block, entities)),\n variables: {\n error: json?.tryCatch?.variables?.error,\n },\n });\n }\n}\n\nexport class Throw extends Block {\n private error: Binding<JsonValue>;\n\n constructor(\n name: string,\n config: {\n error: Binding<JsonValue>;\n },\n ) {\n super(name);\n\n this.error = config.error;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n throw: {\n error: (await toJS<JsonValue>(this.error)).body,\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Throw("${this.name}", { error: ${typeof this.error === "function" ? signatureV2((await toJSBody(this.error)).body, entities) : JSON.stringify(this.error)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Throw {\n return new Throw(json?.name, {\n error: fromJS(json?.throw?.error, entities),\n });\n }\n}\n\nexport class Return extends Block {\n private data: Binding<JsonValue>;\n\n constructor(\n name: string,\n config: {\n data: Binding<JsonValue>;\n },\n ) {\n super(name);\n\n this.data = config.data;\n }\n\n public async toJSON(): Promise<JsonValue> {\n return {\n name: this.name,\n return: {\n data: (await toJS<JsonValue>(this.data)).body,\n },\n };\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n return `new Return("${this.name}", { data: ${typeof this.data === "function" ? signatureV2((await toJSBody(this.data)).body, entities) : JSON.stringify(this.data)} })`;\n }\n\n public static fromJSON(json: any, entities: string[]): Return {\n return new Return(json?.name, {\n data: fromJS(json?.return?.data, entities),\n });\n }\n}\n\nexport class Api {\n private blocks: Block[];\n private name: string;\n\n constructor(name: string, blocks: Block[]) {\n this.name = name;\n this.blocks = blocks;\n }\n\n public async toSDK(entities: string[]): Promise<string> {\n const imports =\n "import { Api, JavaScript, Python, PostgreSQL, Snowflake, RestApi, Databricks, Conditional, Parallel, Loop, TryCatch, Variables, Throw, Return } from \'@superblocksteam/library\'";\n return `${imports}\\n\\nexport default new Api("${this.name}", [${(await Promise.all(this.blocks.map(async (block) => await block.toSDK(entities)))).join(",")}])`;\n }\n\n public static fromJSON(json: any, entities: string[]): Api {\n // NOTE(Frank): Would probs unmarshal this into the protobuf types and then do the conversion.\n return new Api(\n json?.metadata?.name as string,\n (json.blocks as any[]).map((block) => Block.fromJSON(block, entities)),\n );\n }\n\n public async toJSON(): Promise<JsonValue> {\n const api: {\n metadata: {\n name: string;\n timestamps: {\n updated: string;\n };\n };\n trigger: {\n application: {};\n };\n blocks: JsonValue[];\n } = {\n metadata: {\n name: this.name,\n timestamps: {\n updated: new Date().toISOString(),\n },\n },\n trigger: {\n application: {},\n },\n blocks: [],\n };\n\n api.blocks = await Promise.all(this.blocks.map(async (block) => await block.toJSON()));\n\n return api;\n }\n}\n\nfunction referenced(data: string, entities: string[]): string[] {\n return entities.reduce((acc: string[], entity: string) => {\n if (data.includes(entity)) {\n acc.push(entity);\n }\n return acc;\n }, []);\n}\n\nexport function signatureV2(data: string, entities: string[] = []): string {\n return `({ ${referenced(data, entities).join(", ")} }) => ${data}`;\n}\n\n/**\n * Converts a string binding, which comprise 99% of dynamic integration fields, into a function returning an interpolated string.\n *\n * fromBinding(`https://${ \'goo\' + \'gle\' }.com/${ Dropdown1.value }`, [\'Dropdown1\']) -> ({ Dropdown1 }) => `https://${\'goo\' + \'gle\'}.com/${Dropdown1.value}`\n *\n * @param value - The value to convert.\n * @param entities - The master list of possible entities that could be referenced in the binding.\n *\n * @returns The converted value.\n */\nexport function fromBinding(value: string, entities: string[]): Binding<string> {\n if (!value) {\n return "";\n }\n\n if (!value.startsWith("`") || !value.endsWith("`")) {\n return value;\n }\n\n const args: string[] = [`return ${value}`]\n const references: string[] = referenced(value, entities);\n\n if (references.length === 0) {\n try {\n return eval(value) as string;\n } catch (e) {\n console.error(`We couldn\'t tranform the binding ${value} to the SDK. Ensure the AI hasn\'t hallucinated a variable.`);\n throw e;\n }\n }\n\n // only add the arguments if we have references\n args.unshift(`{ ${references} }`);\n\n return new Function(...args) as (_: State) => string;\n}\n\nasync function beautifyAndOptionallyCondense<T extends JsonValue>(value: ((state: State) => T), node: Node, options: { condense?: boolean, block?: boolean } = { condense: true, block: true }) {\n let start: number = node.start;\n let end: number = node.end;\n\n if (!options.block) {\n start += 1;\n end -= 1;\n }\n \n const beautified = await beautify(value.toString().slice(start, end))\n\n if (options.condense) {\n return beautified.replace(/\\s*\\n\\s*/g, \' \').replace(/\\s+/g, \' \').trim();\n }\n\n return beautified\n}\n\nfunction createAst(value: string): Program {\n return parse(value, {\n ecmaVersion: "latest",\n sourceType: "script",\n preserveParens: false,\n });\n}\n\nexport async function toJSBody<T extends JsonValue>(value: ((state: State) => T), options: { block?: boolean, condense?: boolean, function?: boolean } = { block: true, condense: true, function: false }): Promise<{body: string, iife: boolean, node?: Node}> {\n if (typeof value !== "function") {\n return {\n body: `\\`${JSON.stringify(value)}\\``,\n iife: true,\n }\n }\n\n // parse the code\n const ast = createAst(value.toString());\n const program = ast.body[0];\n\n switch (program.type) {\n case "ExpressionStatement":\n const body = ((program as ExpressionStatement).expression as FunctionExpression).body;\n\n if (body.type === \'BlockStatement\') {\n return {\n body: await beautifyAndOptionallyCondense(value, body, options),\n iife: true,\n node: body,\n }\n }\n\n return {\n body: `${options.function ? "return " : ""}${value.toString().slice(body.start, body.end)}`,\n iife: options.function,\n node: body,\n }\n case "FunctionDeclaration":\n let contents = value.toString().slice(program.body.start, program.body.end)\n\n if (program.body.type !== \'BlockStatement\') {\n return {\n body: contents,\n iife: false,\n node: program.body,\n }\n }\n \n if (!options.function && program.body.body.length === 1 && program.body.body[0].type === \'ReturnStatement\') {\n return {\n body: value.toString().slice(program.body.body[0].argument.start, program.body.body[0].argument.end),\n iife: false, // This should be false but we need to deal with the nested string template case.\n node: program.body.body[0].argument,\n }\n }\n\n return {\n body: await beautifyAndOptionallyCondense(value, program.body, options),\n iife: true,\n node: program.body,\n }\n default:\n throw new Error("you found a case we haven\'t handled yet")\n }\n}\n\nexport async function toJS<T extends JsonValue>(value: Binding<T>): Promise<{body: string, node?: Node}> {\n if (typeof value !== "function") {\n return {\n body: JSON.stringify(value),\n }\n }\n\n const { body, iife, node } = await toJSBody(value);\n\n if (iife) {\n return {\n body: `(() => ${body})()`,\n node,\n }\n }\n\n return { body, node }\n}\n\nexport function fromJS<T extends JsonValue>(\n value: string,\n entities: string[] = [],\n): Binding<T> {\n // determine if there are entities referenced in the value\n const refs = referenced(value, entities).join(", ")\n\n // remove any surrounding whitespace\n value = value.trim()\n\n let unaryOps: string[] = [];\n let call = (createAst(value).body[0] as ExpressionStatement).expression;\n\n while (call?.type === \'UnaryExpression\') {\n unaryOps.push((call as UnaryExpression).operator);\n call = (call as unknown as UnaryExpression).argument as CallExpression;\n }\n \n const fn = (call as CallExpression).callee;\n let body = value;\n let prefix = "return ";\n\n // handle iife\n if (fn?.type === "ArrowFunctionExpression") {\n // i\'m not happy with this but I don\'t see another immediate way to handle this.\n // this will result in a correct result but one that isn\'t idemopotent.\n if (unaryOps.length > 0) {\n return new Function(`{ ${refs} }`, `${prefix}${body}`) as (_: State) => T;\n }\n\n\n body = value.slice(fn.body.start, fn.body.end)\n\n if (fn.body.type === \'BlockStatement\') {\n // drop the opening "{" and closing "}"\n body = body.slice(1, -1)\n prefix = ""\n } \n } else if (refs.length === 0) {\n // we\'re not an iife nor do we have references.\n // we might have to revisit this implementation since this technically reduces to a static value down to it\'s most minimal form.\n return eval(value) as T\n }\n\n // we\'re either an iife or a static value with refs.\n return new Function(`{ ${refs} }`, `${prefix}${body}`) as (_: State) => T;\n}\n\nexport async function beautify(code: string): Promise<string> {\n const eslint = new ESLint({\n fix: true,\n overrideConfigFile: true,\n baseConfig: {\n languageOptions: {\n parser: typescript_eslint_parser,\n parserOptions: {\n ecmaVersion: 2020,\n sourceType: "module",\n },\n },\n rules: {\n "arrow-body-style": "error",\n },\n },\n });\n\n code = (await eslint.lintText(code))[0]?.output || code;\n\n return await format(code, {\n parser: "typescript",\n tabWidth: 2,\n // singleQuote: true,\n trailingComma: "none",\n semi: true,\n bracketSpacing: true,\n arrowParens: "always",\n bracketSameLine: false,\n embeddedLanguageFormatting: "auto",\n quoteProps: "as-needed",\n insertPragma: false,\n requirePragma: false,\n useTabs: false,\n endOfLine: "auto",\n arrowFunctionParentheses: "always",\n // plugins: ["prettier-plugin-organize-imports"],\n });\n}\n\nexport function ensureIIFE(value: string): string {\n // We write the IIFE so we can be loose with the fomratting here. \n // For example, we\'d never get ( ( ) =>)().\n if (value.startsWith("(() => ") && value.endsWith(")()")) {\n return value\n }\n\n return `(() => ${value})()`\n}',
|
|
292450
292450
|
"src/to-sdk/__template__.ts": 'import { Api } from "@superblocksteam/library";\n\nconst json = {};\n\nconst entities = [];\n\nconst api = Api.fromJSON(json, entities);\n\nexport default {\n toSDK: async () => await api.toSDK(entities),\n};\n',
|
|
292451
292451
|
"tsconfig.json": '{\n "compilerOptions": {\n "target": "ES2020",\n "module": "ESNext",\n "moduleResolution": "bundler",\n "baseUrl": ".",\n "outDir": "dist",\n "rootDir": "src",\n "esModuleInterop": true,\n "resolveJsonModule": true,\n "skipLibCheck": true,\n "types": [\n "node"\n ],\n "paths": {\n "@superblocksteam/library": [\n "src/superblocks-library-shim"\n ]\n }\n },\n "include": [\n "src"\n ],\n "exclude": [\n "node_modules",\n "dist",\n ]\n}'
|
|
292452
292452
|
}
|
|
@@ -321924,7 +321924,7 @@ var import_util28 = __toESM(require_dist3(), 1);
|
|
|
321924
321924
|
// ../sdk/package.json
|
|
321925
321925
|
var package_default = {
|
|
321926
321926
|
name: "@superblocksteam/sdk",
|
|
321927
|
-
version: "2.0.3-next.
|
|
321927
|
+
version: "2.0.3-next.203",
|
|
321928
321928
|
type: "module",
|
|
321929
321929
|
description: "Superblocks JS SDK",
|
|
321930
321930
|
homepage: "https://www.superblocks.com",
|
|
@@ -321966,8 +321966,8 @@ var package_default = {
|
|
|
321966
321966
|
"@rollup/wasm-node": "^4.35.0",
|
|
321967
321967
|
"@superblocksteam/bucketeer-sdk": "0.5.0",
|
|
321968
321968
|
"@superblocksteam/shared": "0.9160.0",
|
|
321969
|
-
"@superblocksteam/util": "2.0.3-next.
|
|
321970
|
-
"@superblocksteam/vite-plugin-file-sync": "2.0.3-next.
|
|
321969
|
+
"@superblocksteam/util": "2.0.3-next.203",
|
|
321970
|
+
"@superblocksteam/vite-plugin-file-sync": "2.0.3-next.203",
|
|
321971
321971
|
"@vitejs/plugin-react": "^4.3.4",
|
|
321972
321972
|
axios: "^1.4.0",
|
|
321973
321973
|
chokidar: "^4.0.3",
|
|
@@ -328941,7 +328941,7 @@ async function startVite({ app, httpServer: httpServer2, root: root2, mode, port
|
|
|
328941
328941
|
};
|
|
328942
328942
|
const isCustomBuildEnabled2 = await isCustomComponentsEnabled();
|
|
328943
328943
|
const customFolder = path34.join(root2, "custom");
|
|
328944
|
-
const cdnUrl = "https://assets-cdn.superblocks.com/library/2.0.3-next.
|
|
328944
|
+
const cdnUrl = "https://assets-cdn.superblocks.com/library/2.0.3-next.203";
|
|
328945
328945
|
const env3 = loadEnv(mode, root2, "");
|
|
328946
328946
|
const hmrPort = await getFreePort();
|
|
328947
328947
|
const hmrOptions = {
|
package/oclif.manifest.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@superblocksteam/cli",
|
|
3
|
-
"version": "2.0.3-next.
|
|
3
|
+
"version": "2.0.3-next.203",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Official Superblocks CLI",
|
|
6
6
|
"homepage": "https://www.superblocks.com",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@eslint/js": "^9.16.0",
|
|
44
44
|
"@oclif/test": "^4.1.11",
|
|
45
|
-
"@superblocksteam/sdk": "2.0.3-next.
|
|
45
|
+
"@superblocksteam/sdk": "2.0.3-next.203",
|
|
46
46
|
"@superblocksteam/shared": "0.9160.0",
|
|
47
|
-
"@superblocksteam/util": "2.0.3-next.
|
|
47
|
+
"@superblocksteam/util": "2.0.3-next.203",
|
|
48
48
|
"@types/babel__core": "^7.20.0",
|
|
49
49
|
"@types/chai": "^4",
|
|
50
50
|
"@types/fs-extra": "^11.0.1",
|