UNPKG

@rxap/n8n-utilities

Version:

This package provides utility functions and classes for n8n nodes, including custom authentication methods (Bearer Auth, Oauth2 Proxy Auth, Base URL), a decorator for capturing execution errors, and base classes for creating nodes from OpenAPI specificati

933 lines 43 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OpenApiNode = void 0; exports.ResolveRef = ResolveRef; const tslib_1 = require("tslib"); const capture_execution_error_decorator_1 = require("./capture-execution-error.decorator"); const utilities_1 = require("@rxap/utilities"); const FormData = require("form-data"); const fs_1 = require("fs"); const n8n_workflow_1 = require("n8n-workflow"); const path_1 = require("path"); const uuid_1 = require("uuid"); function isParameterObject(parameter) { return (parameter === null || parameter === void 0 ? void 0 : parameter.in) !== undefined && (parameter === null || parameter === void 0 ? void 0 : parameter.name) !== undefined; } function isSchemaObject(schema) { return (schema === null || schema === void 0 ? void 0 : schema.type) !== undefined; } function isRequestBodyObject(requestBody) { return (requestBody === null || requestBody === void 0 ? void 0 : requestBody.content) !== undefined; } function hasQueryParameters(operation) { var _a, _b; return (_b = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).some((parameter) => parameter.in === 'query')) !== null && _b !== void 0 ? _b : false; } function hasPathParameters(operation) { var _a, _b; return (_b = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).some((parameter) => parameter.in === 'path')) !== null && _b !== void 0 ? _b : false; } function hasHeaderParameters(operation) { var _a, _b; return (_b = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).some((parameter) => parameter.in === 'header')) !== null && _b !== void 0 ? _b : false; } function ResolveRef(openApiSpec, node, parent, key) { var _a; if (typeof node !== 'object' || node === null) { return; } if (node['$ref']) { if (node.$ref.startsWith('#/components/schemas')) { const name = node.$ref.replace('#/components/schemas/', ''); if (parent && key && ((_a = openApiSpec.components) === null || _a === void 0 ? void 0 : _a.schemas)) { parent[key] = openApiSpec.components.schemas[name]; ResolveRef(openApiSpec, parent[key], parent, key); } } } else { for (const [k, v] of Object.entries(node)) { ResolveRef(openApiSpec, v, node, k); } } } class OpenApiNode { constructor(openApiFilePath, description = {}, nameSuffix = '') { var _a, _b, _c, _d; this.openApiFilePath = openApiFilePath; this.openapi = this.loadOpenApiFile(); ResolveRef(this.openapi, this.openapi.paths); this.operations = this.extractOperationList(this.openapi); this.tags = this.extractTags(this.operations); this.operationMethods = this.extractMethods(this.operations); // use || instead of ?? to ensure an empty string is also replaced let name = description.name || (0, utilities_1.dasherize)(((_a = this.openapi.info) === null || _a === void 0 ? void 0 : _a.title) || this.constructor.name); if (nameSuffix) { name += `-${nameSuffix}`; } this.description = Object.assign(Object.assign({ version: 1, // use || instead of ?? to ensure an empty string is also replaced description: ((_b = this.openapi.info) === null || _b === void 0 ? void 0 : _b.description) || (0, utilities_1.capitalize)(this.constructor.name), defaults: { name }, inputs: ["main" /* NodeConnectionType.Main */], outputs: ["main" /* NodeConnectionType.Main */], subtitle: '={{ "[" + $parameter["method"].toUpperCase() + "] " + $parameter["operation"] + ": " + $parameter["tag"] }}', // use || instead of ?? to ensure an empty string is also replaced displayName: ((_c = this.openapi.info) === null || _c === void 0 ? void 0 : _c.title) || (0, utilities_1.capitalize)(this.constructor.name), group: ['input'], credentials: [ { displayName: 'Bearer Auth', name: 'httpBearerAuth', required: false, displayOptions: { show: { authentication: ['httpBearerAuth'], }, }, }, { displayName: 'OAuth 2 Proxy Auth', name: 'oauth2ProxyAuth', required: false, displayOptions: { show: { authentication: ['oauth2ProxyAuth'], }, }, }, { displayName: 'Basic Auth', name: 'httpBasicAuth', required: false, displayOptions: { show: { authentication: ['httpBasicAuth'], }, }, }, { displayName: 'Custom Auth', name: 'httpCustomAuth', required: false, displayOptions: { show: { authentication: ['httpCustomAuth'], }, }, }, { displayName: 'Digest Auth', name: 'httpDigestAuth', required: false, displayOptions: { show: { authentication: ['httpDigestAuth'], }, }, }, { displayName: 'Header Auth', name: 'httpHeaderAuth', required: false, displayOptions: { show: { authentication: ['httpHeaderAuth'], }, }, }, ], icon: this.getIcon() }, (0, utilities_1.DeleteUndefinedProperties)(description)), { properties: (_d = description.properties) !== null && _d !== void 0 ? _d : [], name }); this.populateDescription(); } execute() { return tslib_1.__awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f; const items = this.getInputData(); const results = Array(items.length).fill(null); for (let i = 0; i < items.length; i++) { const item = items[i]; const skipAuthentication = this.getNodeParameter('skipAuthentication', i); // eslint-disable-next-line no-inner-declarations function isEmpty(value) { return !value && value !== 0 && value !== false; } const requestOptions = { baseURL: this.getNodeParameter('baseUrl', i), method: this.getNodeParameter('method', i).toUpperCase(), url: this.getNodeParameter('path', i), }; const operationParameters = this.getNodeParameter('parameterSchema', i, []); const operationRequestBody = this.getNodeParameter('requestBodySchema', i, {}); // region build parameters if (operationParameters === null || operationParameters === void 0 ? void 0 : operationParameters.some((p) => isParameterObject(p) && p.in === 'path')) { const pathParameters = this.getNodeParameter('pathParameters', i); requestOptions.url = requestOptions.url.replace(/{([^}]+)}/g, (_, name) => { if (isEmpty(pathParameters[name])) { throw new Error(`The path parameter "${name}" is missing.`); } return encodeURIComponent(pathParameters[name]); }); } if (operationParameters === null || operationParameters === void 0 ? void 0 : operationParameters.some((p) => isParameterObject(p) && p.in === 'query')) { (_a = requestOptions.qs) !== null && _a !== void 0 ? _a : (requestOptions.qs = {}); const queryParameters = this.getNodeParameter('queryParameters', i); for (const queryParam of operationParameters.filter(isParameterObject).filter((p) => p.in === 'query')) { if (isEmpty(queryParameters[queryParam.name])) { if (queryParam.required) { throw new Error(`The query parameter "${queryParam.name}" is missing.`); } } else { requestOptions.qs[queryParam.name] = encodeURIComponent(queryParameters[queryParam.name]); } } } if (operationParameters === null || operationParameters === void 0 ? void 0 : operationParameters.some((p) => isParameterObject(p) && p.in === 'header')) { (_b = requestOptions.headers) !== null && _b !== void 0 ? _b : (requestOptions.headers = {}); const headerParameters = this.getNodeParameter('headerParameters', i); for (const headerParam of operationParameters.filter(isParameterObject).filter((p) => p.in === 'header')) { if (isEmpty(headerParameters[headerParam.name])) { if (headerParam.required) { throw new Error(`The header parameter "${headerParam.name}" is missing.`); } } else { requestOptions.headers[headerParam.name] = headerParameters[headerParam.name]; } } } // endregion // region build request body if (isRequestBodyObject(operationRequestBody)) { const mediaType = this.getNodeParameter('mediaType', i); const requestBody = this.getNodeParameter('requestBody', i); switch (mediaType) { default: case 'application/json': requestOptions.body = requestBody; break; case 'plain/text': requestOptions.body = JSON.stringify(requestBody); break; case 'multipart/form-data': // eslint-disable-next-line no-case-declarations const schema = operationRequestBody.content['multipart/form-data'].schema; if (isSchemaObject(schema)) { const formData = requestOptions.formData = new FormData(); for (const key of Object.keys((_c = schema.properties) !== null && _c !== void 0 ? _c : {})) { const prop = (_d = schema.properties) === null || _d === void 0 ? void 0 : _d[key]; if (isSchemaObject(prop)) { if (isEmpty(requestBody[key])) { throw new Error(`The multipart form data parameter "${key}" is missing.`); } if (prop.format === 'binary') { const data = (_e = item.binary) === null || _e === void 0 ? void 0 : _e[requestBody[key]]; if (!data) { throw new Error(`The binary data for the multipart form data parameter "${key}" is missing.`); } const buffer = yield this.helpers.getBinaryDataBuffer(i, requestBody[key]); const options = (0, utilities_1.DeleteUndefinedProperties)({ filename: data.fileName, filepath: data.directory, contentType: data.mimeType }); if (!buffer) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No binary data found.'); } if (!options.filename) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `The filename for the binary data '${key}' is missing.`); } formData.append(key, buffer, options); } else { formData.append(key, requestBody[key]); } } } } else { requestOptions.formData = requestBody; } break; } (_f = requestOptions.headers) !== null && _f !== void 0 ? _f : (requestOptions.headers = {}); requestOptions.headers['Content-Type'] = mediaType; } // endregion let response; if (skipAuthentication) { response = yield this.helpers.request(requestOptions); } else { const authentication = this.getNodeParameter('authentication', i); if (authentication) { const credentials = yield this.getCredentials(authentication); if ('baseURL' in credentials && credentials['baseURL'] && typeof credentials['baseURL'] === 'string') { requestOptions.baseURL = credentials['baseURL']; } if ('baseUrl' in credentials && credentials['baseUrl'] && typeof credentials['baseUrl'] === 'string') { requestOptions.baseURL = credentials['baseUrl']; } this.logger.debug('Request options: ' + JSON.stringify(requestOptions, undefined, 2)); response = yield this.helpers.requestWithAuthentication.call(this, authentication, requestOptions, undefined, i); } else { throw new Error('No authentication method selected.'); } } let data = response instanceof Buffer ? JSON.parse(response.toString()) : response; let isJSON = false; try { data = JSON.parse(data); isJSON = true; } catch (e) { // ignore } if (isJSON) { const spread = this.getNodeParameter('spread', i, false); if (spread) { let rows = []; if (Array.isArray(data)) { rows = data.map(item => ({ json: item })); } else if (Array.isArray(data.rows)) { rows = data.rows.map((item) => ({ json: item })); } if (rows.length) { results[i] = rows.shift(); results.push(...rows); } } else { results[i] = { json: data }; } } else { results[i] = { json: { response: data } }; } } return [results.filter(Boolean)]; }); } populateDescription() { var _a; var _b; this.description.properties.unshift(...this.buildBaseUrlParameters()); (_a = (_b = this.description).credentials) !== null && _a !== void 0 ? _a : (_b.credentials = []); this.description.properties.unshift({ displayName: 'Authentication', name: 'authentication', type: this.description.credentials.length > 1 ? 'options' : 'hidden', options: this.description.credentials.map(credential => { var _a; return ({ value: credential.name, name: (_a = credential.displayName) !== null && _a !== void 0 ? _a : (0, utilities_1.classify)(credential.name), }); }), default: this.description.credentials[0].name, displayOptions: { hide: { skipAuthentication: [true], } }, }); this.description.properties.unshift({ displayName: 'Skip Authentication', name: 'skipAuthentication', type: 'boolean', default: false, }); this.description.properties.push(this.buildTagProperty(this.tags, this.operations.some(o => { var _a; return !((_a = o.tags) === null || _a === void 0 ? void 0 : _a.length); }))); this.description.properties.push(this.buildMethodProperty(this.operationMethods)); for (const tag of this.tags) { const property = this.buildOperationProperty(this.operations, tag); if (property) { this.description.properties.push(...property); } } const property = this.buildOperationProperty(this.operations.filter(o => { var _a; return !((_a = o.tags) === null || _a === void 0 ? void 0 : _a.length); })); if (property) { this.description.properties.push(...property); } for (const operation of this.operations) { if (hasQueryParameters(operation)) { this.description.properties.push(this.buildOperationQueryParameterProperties(operation)); } if (hasPathParameters(operation)) { this.description.properties.push(this.buildOperationPathParameterProperties(operation)); } if (hasHeaderParameters(operation)) { this.description.properties.push(this.buildOperationHeaderParameterProperties(operation)); } if (isRequestBodyObject(operation.requestBody)) { this.description.properties.push(...this.buildOperationRequestBodyProperties(operation)); } } this.buildArrayResponseHandlerProperty(this.operations); this.buildPagedResponseHandlerProperty(this.operations); } buildArrayResponseHandlerProperty(operationList) { // filter operation that have an array response operationList = operationList.filter(operation => { var _a, _b, _c, _d; return ((_d = (_c = (_b = (_a = operation.responses['200']) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b['application/json']) === null || _c === void 0 ? void 0 : _c.schema) === null || _d === void 0 ? void 0 : _d.type) === 'array'; }); return { name: 'spread', displayName: 'Spread Response', default: true, description: 'The items of the array response will be spread into individual items.', type: 'boolean', displayOptions: { show: { operation: operationList.map(o => o.operationId), }, }, }; } buildPagedResponseHandlerProperty(operationList) { // filter operation that have an array response operationList = operationList.filter(operation => { var _a, _b, _c, _d, _e; const schema = (_c = (_b = (_a = operation.responses['200']) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b['application/json']) === null || _c === void 0 ? void 0 : _c.schema; if ((schema === null || schema === void 0 ? void 0 : schema.type) === 'object') { return ((_e = (_d = schema.properties) === null || _d === void 0 ? void 0 : _d.rows) === null || _e === void 0 ? void 0 : _e.type) === 'array'; } return false; }); return { name: 'spread', displayName: 'Spread Response', default: true, description: 'The items of the rows array response will be spread into individual items.', type: 'boolean', displayOptions: { show: { operation: operationList.map(o => o.operationId), }, }, }; } buildBaseUrlParameters() { var _a, _b; const parameters = []; const options = (_b = (_a = this.openapi.servers) === null || _a === void 0 ? void 0 : _a.map(server => ({ name: server.description ? (0, utilities_1.capitalize)(server.description) : server.url, value: server.url, }))) !== null && _b !== void 0 ? _b : []; if (options.length) { parameters.push({ displayName: 'Base URL', name: 'baseUrl', type: 'options', options, default: options[0].value, validateType: 'string', }); } else { parameters.push({ displayName: 'Base URL', name: 'baseUrl', type: 'string', default: '', }); } return parameters; } getIcon() { const basePath = (0, path_1.dirname)(this.openApiFilePath); if ((0, fs_1.existsSync)((0, path_1.join)(basePath, `${this.constructor.name}.png`))) { return `file:${this.constructor.name}.png`; } if ((0, fs_1.existsSync)((0, path_1.join)(basePath, `${this.constructor.name}.svg`))) { if ((0, fs_1.existsSync)((0, path_1.join)(basePath, `${this.constructor.name}.dark.svg`))) { return { light: `file:${this.constructor.name}.svg`, dark: `file:${this.constructor.name}.dark.svg` }; } else { return `file:${this.constructor.name}.svg`; } } if (this.constructor.name.startsWith('Service')) { return { light: `file:${this.constructor.name}.png`, dark: `file:${this.constructor.name}.dark.png` }; } return undefined; } buildApplicationJsonProperty(operation) { const schema = operation.requestBody.content['application/json'].schema; return Object.assign(Object.assign({}, this.buildPropertyForSchema(null, schema)), { displayName: 'Request Body', name: 'requestBody', displayOptions: { show: { operation: [operation.operationId], mediaType: ['application/json'], }, } }); } buildPlainTextProperty(operation) { return { displayName: 'Request Body', name: 'requestBody', type: 'string', displayOptions: { show: { operation: [operation.operationId], mediaType: ['plain/text'], }, }, typeOptions: { rows: 4, }, default: '', }; } buildMultipartFormDataProperty(operation, mediaType) { var _a, _b, _c, _d; const options = []; const schema = mediaType.schema; let defaults = {}; if (isSchemaObject(schema)) { for (const [key, value] of Object.entries((_a = schema.properties) !== null && _a !== void 0 ? _a : {})) { if (isSchemaObject(value)) { options.push({ displayName: (0, utilities_1.capitalize)(key), name: key, type: this.schemaToNodePropertyType(value), default: '', }); } } if (Object.keys((_b = schema.properties) !== null && _b !== void 0 ? _b : {}).length === 1) { const propertyKey = Object.keys((_c = schema.properties) !== null && _c !== void 0 ? _c : {})[0]; defaults = { [Object.keys((_d = schema.properties) !== null && _d !== void 0 ? _d : {})[0]]: propertyKey === 'file' ? 'data' : '', }; } } return { displayName: 'Request Body', name: 'requestBody', type: 'collection', displayOptions: { show: { operation: [operation.operationId], mediaType: ['multipart/form-data'], }, }, default: defaults, options, }; } buildOperationRequestBodyProperties(operation) { const mediaTypes = Object.keys(operation.requestBody.content); const properties = [ { displayName: 'Media Type', name: 'mediaType', type: 'options', noDataExpression: true, displayOptions: { show: { operation: [operation.operationId], }, }, default: mediaTypes[0], options: mediaTypes.map(mediaType => ({ value: mediaType, name: mediaType, })), }, ]; for (const mediaType of mediaTypes) { switch (mediaType) { case 'application/json': properties.push(this.buildApplicationJsonProperty(operation)); break; case 'plain/text': properties.push(this.buildPlainTextProperty(operation)); break; case 'multipart/form-data': properties.push(this.buildMultipartFormDataProperty(operation, operation.requestBody.content['multipart/form-data'])); break; default: properties.push({ displayName: 'Request Body', name: 'requestBody', type: 'string', displayOptions: { show: { operation: [operation.operationId], mediaType: [mediaType], }, }, typeOptions: { rows: 4, }, default: '', }); break; } } return properties; } // region Query, Path, and Header Parameters schemaToNodePropertyType(schema) { switch (schema.type) { case 'boolean': return 'boolean'; case 'number': case 'integer': return 'number'; default: case 'string': return 'string'; } } buildOperationQueryParameterProperties(operation) { var _a, _b; const parameters = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).filter((p) => p.in === 'query'); return { displayName: 'Query Parameters', name: 'queryParameters', type: 'collection', default: parameters.filter(p => p.required).reduce((acc, p) => (Object.assign(Object.assign({}, acc), { [p.name]: null })), {}), displayOptions: { show: { operation: [operation.operationId], }, }, options: (_b = parameters.map(p => ({ displayName: (0, utilities_1.capitalize)(p.name), name: p.name, type: isSchemaObject(p.schema) ? this.schemaToNodePropertyType(p.schema) : 'string', default: '', }))) !== null && _b !== void 0 ? _b : [], }; } buildOperationPathParameterProperties(operation) { var _a, _b; const parameters = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).filter((p) => p.in === 'path'); return { displayName: 'Path Parameters', name: 'pathParameters', type: 'collection', default: parameters.filter(p => p.required).reduce((acc, p) => (Object.assign(Object.assign({}, acc), { [p.name]: null })), {}), displayOptions: { show: { operation: [operation.operationId], }, }, options: (_b = parameters.map(p => ({ displayName: (0, utilities_1.capitalize)(p.name), name: p.name, type: isSchemaObject(p.schema) ? this.schemaToNodePropertyType(p.schema) : 'string', default: '', }))) !== null && _b !== void 0 ? _b : [], }; } // endregion buildOperationHeaderParameterProperties(operation) { var _a, _b; const parameters = (_a = operation.parameters) === null || _a === void 0 ? void 0 : _a.filter(isParameterObject).filter((p) => p.in === 'header'); return { displayName: 'Header Parameters', name: 'headerParameters', type: 'collection', default: parameters.filter(p => p.required).reduce((acc, p) => (Object.assign(Object.assign({}, acc), { [p.name]: null })), {}), displayOptions: { show: { operation: [operation.operationId], }, }, options: (_b = parameters.map(p => ({ displayName: (0, utilities_1.capitalize)(p.name), name: p.name, type: isSchemaObject(p.schema) ? this.schemaToNodePropertyType(p.schema) : 'string', default: '', }))) !== null && _b !== void 0 ? _b : [], }; } buildOperationProperty(operationList, tag) { // Filter the operation list by the selected tag. If no tag is selected, return the full list. operationList = tag ? operationList.filter(operation => { var _a; return (_a = operation.tags) === null || _a === void 0 ? void 0 : _a.includes(tag); }) : operationList; tag !== null && tag !== void 0 ? tag : (tag = 'any'); if (operationList.length === 0) { return null; } const parameters = [ { displayName: 'Operation', name: 'operation', type: 'options', default: operationList[0].operationId, displayOptions: { show: { resource: [tag], }, }, options: operationList.map(operation => { var _a, _b, _c; return ({ name: (_a = operation.name) !== null && _a !== void 0 ? _a : operation.operationId, value: operation.operationId, description: operation.description, action: (_b = operation.summary) !== null && _b !== void 0 ? _b : operation.operationId, displayName: (_c = operation.summary) !== null && _c !== void 0 ? _c : operation.name, displayOptions: { show: { method: [operation.method], } }, }); }), } ]; for (const operation of operationList) { parameters.push({ displayOptions: { show: { operation: [operation.operationId], } }, displayName: 'Parameter Schema', name: 'parameterSchema', default: operation.parameters, type: 'hidden', }); parameters.push({ displayOptions: { show: { operation: [operation.operationId], } }, displayName: 'Request Body Schema', name: 'requestBodySchema', default: operation.requestBody, type: 'hidden', }); parameters.push({ displayOptions: { show: { operation: [operation.operationId], } }, displayName: 'Request Path', name: 'path', default: operation.path, type: 'hidden', }); } return parameters; } buildTagProperty(tags, withAnyTag) { const options = tags.map(tag => ({ name: tag.split('-').map(utilities_1.capitalize).join(' '), value: tag, })); if (withAnyTag) { options.unshift({ name: 'Any', value: 'any', }); } return { // The displayName and name must be 'resource' so that in the n8n UI the different operations are // shown in a grouped fashion displayName: 'Resource', name: 'resource', type: 'options', noDataExpression: true, options, default: withAnyTag ? 'any' : tags[0], }; } buildMethodProperty(methods) { return { displayName: 'Method', name: 'method', type: 'options', noDataExpression: true, options: methods.map(method => ({ name: method.toUpperCase(), value: method, })), default: methods[0], }; } extractMethods(operations) { return Array.from(new Set(operations.map(operation => operation.method))); } extractTags(operations) { return Array.from(new Set(operations.flatMap(operation => { var _a; return (_a = operation.tags) !== null && _a !== void 0 ? _a : []; }))); } extractOperationList(openapi) { const list = []; for (const [path, pathObj] of Object.entries(openapi.paths)) { for (const [method, operation] of Object.entries(pathObj)) { if (typeof operation === 'object') { list.push(Object.assign({ path, method }, operation)); } } } return list; } loadOpenApiFile() { const filePath = this.openApiFilePath; if (!(0, fs_1.existsSync)(filePath)) { throw new Error(`The OpenAPI file "${filePath}" does not exist.`); } return JSON.parse((0, fs_1.readFileSync)(filePath, 'utf8')); } // region schema to n8n node properties buildPropertyForSchema(propertyName, schema) { var _a, _b; switch (schema.type) { case 'string': case 'number': case 'boolean': return this.buildPropertyForSchemaPrimitive(propertyName, schema); case 'array': return this.buildPropertyForSchemaArray(propertyName, schema); case 'object': return this.buildPropertyForSchemaObject(propertyName, schema); default: if (Object.keys((_a = schema.properties) !== null && _a !== void 0 ? _a : {}).length) { return this.buildPropertyForSchemaObject(propertyName, schema); } if (schema.items) { return this.buildPropertyForSchemaArray(propertyName, schema); } return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_b = schema.title) !== null && _b !== void 0 ? _b : propertyName : 'Payload', type: 'string', default: '', description: schema.description, }; } } buildStringPropertyDefault(schema) { var _a; switch (schema.format) { case 'uuid': return (0, uuid_1.v4)(); default: return (_a = schema.default) !== null && _a !== void 0 ? _a : ''; } } buildPropertyForSchemaPrimitive(propertyName, schema) { var _a, _b, _c, _d, _e, _f, _g; switch (schema.type) { case 'string': if (schema.enum) { return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_a = schema.title) !== null && _a !== void 0 ? _a : propertyName : 'Payload', type: 'options', default: (_b = schema.default) !== null && _b !== void 0 ? _b : '', description: schema.description, options: schema.enum.map((value) => ({ name: value, value })), }; } return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_c = schema.title) !== null && _c !== void 0 ? _c : propertyName : 'Payload', type: 'string', default: this.buildStringPropertyDefault(schema), description: schema.description, }; case 'number': return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_d = schema.title) !== null && _d !== void 0 ? _d : propertyName : 'Payload', type: 'number', default: (_e = schema.default) !== null && _e !== void 0 ? _e : 0, description: schema.description, }; case 'boolean': return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_f = schema.title) !== null && _f !== void 0 ? _f : propertyName : 'Payload', type: 'boolean', default: (_g = schema.default) !== null && _g !== void 0 ? _g : false, description: schema.description, }; default: throw new Error(`Unsupported primitive schema type: ${schema.type}`); } } buildPropertyForSchemaArray(propertyName, schema) { var _a, _b, _c; const items = ((_a = schema.items) !== null && _a !== void 0 ? _a : {}); let options = []; if (Object.keys(items).length) { options = [this.buildPropertyForSchema('item', items)]; } else { options = [ { name: 'item', displayName: 'Item', type: 'json', default: '', } ]; } return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_b = schema.title) !== null && _b !== void 0 ? _b : propertyName : 'Payload', description: schema.description, type: 'fixedCollection', default: (_c = schema.default) !== null && _c !== void 0 ? _c : [], typeOptions: { multipleValues: true, }, options: [ { name: 'item', displayName: 'Item', values: options, } ] }; } buildPropertyDefault(schema) { var _a, _b, _c; const defaultObj = (_a = schema.default) !== null && _a !== void 0 ? _a : {}; for (const propertyName of (_b = schema.required) !== null && _b !== void 0 ? _b : []) { const property = (_c = schema.properties) === null || _c === void 0 ? void 0 : _c[propertyName]; switch (property === null || property === void 0 ? void 0 : property.type) { case 'string': case 'number': case 'boolean': if (defaultObj[propertyName] === undefined) { defaultObj[propertyName] = null; } break; case 'object': if (defaultObj[propertyName] === undefined) { defaultObj[propertyName] = {}; } break; } } // remove empty arrays from the default object for (const [key, value] of Object.entries(defaultObj)) { if (Array.isArray(value) && value.length === 0) { delete defaultObj[key]; } } return defaultObj; } buildPropertyForSchemaObject(propertyName, schema) { var _a, _b; return { name: propertyName ? propertyName : 'payload', displayName: propertyName ? (_a = schema.title) !== null && _a !== void 0 ? _a : propertyName : 'Payload', type: 'collection', default: this.buildPropertyDefault(schema), description: schema.description, options: Object.entries((_b = schema.properties) !== null && _b !== void 0 ? _b : {}).map(([propertyName, schema]) => this.buildPropertyForSchema(propertyName, schema)), }; } } exports.OpenApiNode = OpenApiNode; tslib_1.__decorate([ (0, capture_execution_error_decorator_1.CaptureExecutionError)(), tslib_1.__metadata("design:type", Function), tslib_1.__metadata("design:paramtypes", []), tslib_1.__metadata("design:returntype", Promise) ], OpenApiNode.prototype, "execute", null); //# sourceMappingURL=open-api-node.js.map