UNPKG

n8n

Version:

n8n Workflow Automation Tool

336 lines 14.2 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CurlService = exports.flattenObject = void 0; const typedi_1 = require("typedi"); const curlconverter_1 = __importDefault(require("curlconverter")); const get_1 = __importDefault(require("lodash/get")); const n8n_workflow_1 = require("n8n-workflow"); var ContentTypes; (function (ContentTypes) { ContentTypes["applicationJson"] = "application/json"; ContentTypes["applicationFormUrlEncoded"] = "application/x-www-form-urlencoded"; ContentTypes["applicationMultipart"] = "multipart/form-data"; })(ContentTypes || (ContentTypes = {})); const SUPPORTED_CONTENT_TYPES = [ "application/json", "application/x-www-form-urlencoded", "multipart/form-data", ]; const CONTENT_TYPE_KEY = 'content-type'; const FOLLOW_REDIRECT_FLAGS = ['--location', '-L']; const MAX_REDIRECT_FLAG = '--max-redirs'; const PROXY_FLAGS = ['-x', '--proxy']; const INCLUDE_HEADERS_IN_OUTPUT_FLAGS = ['-i', '--include']; const REQUEST_FLAGS = ['-X', '--request']; const TIMEOUT_FLAGS = ['--connect-timeout']; const DOWNLOAD_FILE_FLAGS = ['-O', '-o']; const IGNORE_SSL_ISSUES_FLAGS = ['-k', '--insecure']; const isContentType = (headers, contentType) => { return (0, get_1.default)(headers, CONTENT_TYPE_KEY) === contentType; }; const isJsonRequest = (curlJson) => { if (isContentType(curlJson.headers, "application/json")) return true; if (curlJson.data) { const bodyKey = Object.keys(curlJson.data)[0]; try { JSON.parse(bodyKey); return true; } catch { return false; } } return false; }; const isFormUrlEncodedRequest = (curlJson) => { if (isContentType(curlJson.headers, "application/x-www-form-urlencoded")) return true; if (curlJson.data && !curlJson.files) return true; return false; }; const isMultipartRequest = (curlJson) => { if (isContentType(curlJson.headers, "multipart/form-data")) return true; if (curlJson.files) return true; return false; }; const isBinaryRequest = (curlJson) => { var _a, _b; if ((_a = curlJson === null || curlJson === void 0 ? void 0 : curlJson.headers) === null || _a === void 0 ? void 0 : _a[CONTENT_TYPE_KEY]) { const contentType = (_b = curlJson === null || curlJson === void 0 ? void 0 : curlJson.headers) === null || _b === void 0 ? void 0 : _b[CONTENT_TYPE_KEY]; return ['image', 'video', 'audio'].some((d) => contentType.includes(d)); } return false; }; const sanitizeCurlCommand = (curlCommand) => curlCommand .replace(/\r\n/g, ' ') .replace(/\n/g, ' ') .replace(/\\/g, ' ') .replace(/[ ]{2,}/g, ' '); const toKeyValueArray = ([key, value]) => ({ name: key, value }); const extractHeaders = (headers = {}) => { const emptyHeaders = !Object.keys(headers).length; const onlyContentTypeHeaderDefined = Object.keys(headers).length === 1 && headers[CONTENT_TYPE_KEY] !== undefined; if (emptyHeaders || onlyContentTypeHeaderDefined) return { sendHeaders: false }; return { sendHeaders: true, headerParameters: { parameters: Object.entries(headers) .map(toKeyValueArray) .filter((parameter) => parameter.name !== CONTENT_TYPE_KEY), }, }; }; const extractQueries = (queries = {}) => { const emptyQueries = !Object.keys(queries).length; if (emptyQueries) return { sendQuery: false }; return { sendQuery: true, queryParameters: { parameters: Object.entries(queries).map(toKeyValueArray), }, }; }; const extractJson = (body) => (0, n8n_workflow_1.jsonParse)(Object.keys(body)[0]); const jsonBodyToNodeParameters = (body = {}) => { const data = extractJson(body); return Object.entries(data).map(toKeyValueArray); }; const multipartToNodeParameters = (body = {}, files = {}) => { return [ ...Object.entries(body) .map(toKeyValueArray) .map((e) => ({ parameterType: 'formData', ...e })), ...Object.entries(files) .map(toKeyValueArray) .map((e) => ({ parameterType: 'formBinaryData', ...e })), ]; }; const keyValueBodyToNodeParameters = (body = {}) => { return Object.entries(body).map(toKeyValueArray); }; const lowerCaseContentTypeKey = (obj) => { const regex = new RegExp(CONTENT_TYPE_KEY, 'gi'); const contentTypeKey = Object.keys(obj).find((key) => { const group = Array.from(key.matchAll(regex)); if (group.length) return true; return false; }); if (!contentTypeKey) return; const value = obj[contentTypeKey]; delete obj[contentTypeKey]; obj[CONTENT_TYPE_KEY] = value; }; const encodeBasicAuthentication = (username, password) => Buffer.from(`${username}:${password}`).toString('base64'); const jsonHasNestedObjects = (json) => Object.values(json).some((e) => typeof e === 'object'); const extractGroup = (curlCommand, regex) => curlCommand.matchAll(regex); const mapCookies = (cookies) => { if (!cookies) return {}; const cookiesValues = Object.entries(cookies).reduce((accumulator, entry) => { accumulator += `${entry[0]}=${entry[1]};`; return accumulator; }, ''); if (!cookiesValues) return {}; return { cookie: cookiesValues, }; }; const flattenObject = (obj, prefix = '') => Object.keys(obj).reduce((acc, k) => { const pre = prefix.length ? prefix + '.' : ''; if (typeof obj[k] === 'object') Object.assign(acc, (0, exports.flattenObject)(obj[k], pre + k)); else acc[pre + k] = obj[k]; return acc; }, {}); exports.flattenObject = flattenObject; let CurlService = class CurlService { toHttpNodeParameters(curlCommand) { var _a, _b, _c, _d, _e, _f, _g; const curlJson = (0, n8n_workflow_1.jsonParse)(curlconverter_1.default.toJsonString(curlCommand)); if (!curlJson.headers) curlJson.headers = {}; lowerCaseContentTypeKey(curlJson.headers); if (curlJson.auth) { const { user, password: pass } = curlJson.auth; Object.assign(curlJson.headers, { authorization: `Basic ${encodeBasicAuthentication(user, pass)}`, }); } const httpNodeParameters = { url: curlJson.url, authentication: 'none', method: curlJson.method.toUpperCase(), ...extractHeaders({ ...curlJson.headers, ...mapCookies(curlJson.cookies) }), ...extractQueries(curlJson.queries), options: { redirect: { redirect: {}, }, response: { response: {}, }, }, }; const curl = sanitizeCurlCommand(curlCommand); if (FOLLOW_REDIRECT_FLAGS.some((flag) => curl.includes(` ${flag}`))) { Object.assign((_a = httpNodeParameters.options.redirect) === null || _a === void 0 ? void 0 : _a.redirect, { followRedirects: true }); if (curl.includes(` ${MAX_REDIRECT_FLAG}`)) { const extractedValue = Array.from(extractGroup(curl, new RegExp(` ${MAX_REDIRECT_FLAG} (\\d+)`, 'g'))); if (extractedValue.length) { const [_, maxRedirects] = extractedValue[0]; if (maxRedirects) { Object.assign((_b = httpNodeParameters.options.redirect) === null || _b === void 0 ? void 0 : _b.redirect, { maxRedirects }); } } } } if (PROXY_FLAGS.some((flag) => curl.includes(` ${flag}`))) { const foundFlag = PROXY_FLAGS.find((flag) => curl.includes(` ${flag}`)); if (foundFlag) { const extractedValue = Array.from(extractGroup(curl, new RegExp(` ${foundFlag} (\\S*)`, 'g'))); if (extractedValue.length) { const [_, proxy] = extractedValue[0]; Object.assign(httpNodeParameters.options, { proxy }); } } } if (INCLUDE_HEADERS_IN_OUTPUT_FLAGS.some((flag) => curl.includes(` ${flag}`))) { Object.assign((_d = (_c = httpNodeParameters.options) === null || _c === void 0 ? void 0 : _c.response) === null || _d === void 0 ? void 0 : _d.response, { fullResponse: true, responseFormat: 'autodetect', }); } if (REQUEST_FLAGS.some((flag) => curl.includes(` ${flag}`))) { const foundFlag = REQUEST_FLAGS.find((flag) => curl.includes(` ${flag}`)); if (foundFlag) { const extractedValue = Array.from(extractGroup(curl, new RegExp(` ${foundFlag} (\\w+)`, 'g'))); if (extractedValue.length) { const [_, request] = extractedValue[0]; httpNodeParameters.method = request.toUpperCase(); } } } if (TIMEOUT_FLAGS.some((flag) => curl.includes(` ${flag}`))) { const foundFlag = TIMEOUT_FLAGS.find((flag) => curl.includes(` ${flag}`)); if (foundFlag) { const extractedValue = Array.from(extractGroup(curl, new RegExp(` ${foundFlag} (\\d+)`, 'g'))); if (extractedValue.length) { const [_, timeout] = extractedValue[0]; Object.assign(httpNodeParameters.options, { timeout: parseInt(timeout, 10) * 1000, }); } } } if (DOWNLOAD_FILE_FLAGS.some((flag) => curl.includes(` ${flag}`))) { const foundFlag = DOWNLOAD_FILE_FLAGS.find((flag) => curl.includes(` ${flag}`)); if (foundFlag) { Object.assign(httpNodeParameters.options.response.response, { responseFormat: 'file', outputPropertyName: 'data', }); } } if (IGNORE_SSL_ISSUES_FLAGS.some((flag) => curl.includes(` ${flag}`))) { const foundFlag = IGNORE_SSL_ISSUES_FLAGS.find((flag) => curl.includes(` ${flag}`)); if (foundFlag) { Object.assign(httpNodeParameters.options, { allowUnauthorizedCerts: true, }); } } const contentType = (_e = curlJson === null || curlJson === void 0 ? void 0 : curlJson.headers) === null || _e === void 0 ? void 0 : _e[CONTENT_TYPE_KEY]; if (isBinaryRequest(curlJson)) { return Object.assign(httpNodeParameters, { contentType: 'binaryData', sendBody: true, }); } if (contentType && !SUPPORTED_CONTENT_TYPES.includes(contentType)) { return Object.assign(httpNodeParameters, { sendBody: true, contentType: 'raw', rawContentType: contentType, body: Object.keys((_f = curlJson === null || curlJson === void 0 ? void 0 : curlJson.data) !== null && _f !== void 0 ? _f : {})[0], }); } if (isJsonRequest(curlJson)) { Object.assign(httpNodeParameters, { contentType: 'json', sendBody: true, }); if (curlJson.data) { const json = extractJson(curlJson.data); if (jsonHasNestedObjects(json)) { Object.assign(httpNodeParameters, { specifyBody: 'json', jsonBody: JSON.stringify(json, null, 2), }); } else { Object.assign(httpNodeParameters, { specifyBody: 'keypair', bodyParameters: { parameters: jsonBodyToNodeParameters(curlJson.data), }, }); } } } else if (isFormUrlEncodedRequest(curlJson)) { Object.assign(httpNodeParameters, { contentType: 'form-urlencoded', sendBody: true, specifyBody: 'keypair', bodyParameters: { parameters: keyValueBodyToNodeParameters(curlJson.data), }, }); } else if (isMultipartRequest(curlJson)) { Object.assign(httpNodeParameters, { contentType: 'multipart-form-data', sendBody: true, bodyParameters: { parameters: multipartToNodeParameters(curlJson.data, curlJson.files), }, }); } else { Object.assign(httpNodeParameters, { sendBody: false, }); } if (!Object.keys((_g = httpNodeParameters.options) === null || _g === void 0 ? void 0 : _g.redirect.redirect).length) { delete httpNodeParameters.options.redirect; } if (!Object.keys(httpNodeParameters.options.response.response).length) { delete httpNodeParameters.options.response; } return httpNodeParameters; } }; exports.CurlService = CurlService; exports.CurlService = CurlService = __decorate([ (0, typedi_1.Service)() ], CurlService); //# sourceMappingURL=curl.service.js.map