n8n-nodes-base 1.97.0 → 1.98.0

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.
Files changed (50) hide show
  1. package/dist/nodes/Aws/DynamoDB/AwsDynamoDB.node.js +5 -5
  2. package/dist/nodes/Aws/DynamoDB/AwsDynamoDB.node.js.map +1 -1
  3. package/dist/nodes/Aws/DynamoDB/ItemDescription.js +1 -1
  4. package/dist/nodes/Aws/DynamoDB/ItemDescription.js.map +1 -1
  5. package/dist/nodes/ExecuteWorkflow/ExecuteWorkflow/GenericFunctions.js +4 -1
  6. package/dist/nodes/ExecuteWorkflow/ExecuteWorkflow/GenericFunctions.js.map +1 -1
  7. package/dist/nodes/Form/Form.node.js +3 -3
  8. package/dist/nodes/Form/Form.node.js.map +1 -1
  9. package/dist/nodes/Form/utils/formCompletionUtils.js.map +1 -0
  10. package/dist/nodes/Form/utils/formNodeUtils.js.map +1 -0
  11. package/dist/nodes/Form/{utils.js → utils/utils.js} +21 -7
  12. package/dist/nodes/Form/utils/utils.js.map +1 -0
  13. package/dist/nodes/Form/v1/FormTriggerV1.node.js +1 -1
  14. package/dist/nodes/Form/v1/FormTriggerV1.node.js.map +1 -1
  15. package/dist/nodes/Form/v2/FormTriggerV2.node.js +1 -1
  16. package/dist/nodes/Form/v2/FormTriggerV2.node.js.map +1 -1
  17. package/dist/nodes/Github/Github.node.js +5 -4
  18. package/dist/nodes/Github/Github.node.js.map +1 -1
  19. package/dist/nodes/Google/Ads/CampaignDescription.js +3 -3
  20. package/dist/nodes/Google/Ads/CampaignDescription.js.map +1 -1
  21. package/dist/nodes/Google/Ads/GoogleAds.node.js +1 -1
  22. package/dist/nodes/Google/Ads/GoogleAds.node.js.map +1 -1
  23. package/dist/nodes/Google/GSuiteAdmin/DeviceDescription.js +1 -1
  24. package/dist/nodes/Google/GSuiteAdmin/DeviceDescription.js.map +1 -1
  25. package/dist/nodes/Notion/shared/GenericFunctions.js +1 -1
  26. package/dist/nodes/Notion/shared/GenericFunctions.js.map +1 -1
  27. package/dist/nodes/Strapi/GenericFunctions.js +3 -10
  28. package/dist/nodes/Strapi/GenericFunctions.js.map +1 -1
  29. package/dist/nodes/Strapi/Strapi.node.js +2 -1
  30. package/dist/nodes/Strapi/Strapi.node.js.map +1 -1
  31. package/dist/nodes/Stripe/StripeTrigger.node.js +12 -0
  32. package/dist/nodes/Stripe/StripeTrigger.node.js.map +1 -1
  33. package/dist/nodes/Telegram/Telegram.node.js +3 -0
  34. package/dist/nodes/Telegram/Telegram.node.js.map +1 -1
  35. package/dist/nodes/Telegram/tests/Workflow/apiResponses.js +39 -0
  36. package/dist/nodes/Telegram/tests/Workflow/apiResponses.js.map +1 -1
  37. package/dist/nodes/Wait/Wait.node.js +1 -1
  38. package/dist/nodes/Wait/Wait.node.js.map +1 -1
  39. package/dist/types/nodes.json +8 -8
  40. package/dist/utils/sendAndWait/utils.js +1 -1
  41. package/dist/utils/sendAndWait/utils.js.map +1 -1
  42. package/dist/utils/utilities.d.ts +2 -1
  43. package/dist/utils/utilities.js +8 -0
  44. package/dist/utils/utilities.js.map +1 -1
  45. package/package.json +4 -4
  46. package/dist/nodes/Form/formCompletionUtils.js.map +0 -1
  47. package/dist/nodes/Form/formNodeUtils.js.map +0 -1
  48. package/dist/nodes/Form/utils.js.map +0 -1
  49. /package/dist/nodes/Form/{formCompletionUtils.js → utils/formCompletionUtils.js} +0 -0
  50. /package/dist/nodes/Form/{formNodeUtils.js → utils/formNodeUtils.js} +0 -0
@@ -41,7 +41,7 @@ var import_descriptions = require("./descriptions");
41
41
  var import_email_templates = require("./email-templates");
42
42
  var import_cssVariables = require("../../nodes/Form/cssVariables");
43
43
  var import_Form = require("../../nodes/Form/Form.node");
44
- var import_utils = require("../../nodes/Form/utils");
44
+ var import_utils = require("../../nodes/Form/utils/utils");
45
45
  var import_utilities = require("../utilities");
46
46
  const INPUT_FIELD_IDENTIFIER = "field-0";
47
47
  const limitWaitTimeOption = {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../utils/sendAndWait/utils.ts"],"sourcesContent":["import isbot from 'isbot';\nimport {\n\tNodeOperationError,\n\tSEND_AND_WAIT_OPERATION,\n\ttryToParseJsonToFormFields,\n\tupdateDisplayOptions,\n} from 'n8n-workflow';\nimport type {\n\tINodeProperties,\n\tIExecuteFunctions,\n\tIWebhookFunctions,\n\tIDataObject,\n\tFormFieldsParameter,\n} from 'n8n-workflow';\n\nimport { limitWaitTimeProperties } from './descriptions';\nimport {\n\tACTION_RECORDED_PAGE,\n\tBUTTON_STYLE_PRIMARY,\n\tBUTTON_STYLE_SECONDARY,\n\tcreateEmailBodyWithN8nAttribution,\n\tcreateEmailBodyWithoutN8nAttribution,\n} from './email-templates';\nimport type { IEmail } from './interfaces';\nimport { cssVariables } from '../../nodes/Form/cssVariables';\nimport { formFieldsProperties } from '../../nodes/Form/Form.node';\nimport { prepareFormData, prepareFormReturnItem, resolveRawData } from '../../nodes/Form/utils';\nimport { escapeHtml } from '../utilities';\n\nexport type SendAndWaitConfig = {\n\ttitle: string;\n\tmessage: string;\n\turl: string;\n\toptions: Array<{ label: string; value: string; style: string }>;\n\tappendAttribution?: boolean;\n};\n\ntype FormResponseTypeOptions = {\n\tmessageButtonLabel?: string;\n\tresponseFormTitle?: string;\n\tresponseFormDescription?: string;\n\tresponseFormButtonLabel?: string;\n\tresponseFormCustomCss?: string;\n};\n\nconst INPUT_FIELD_IDENTIFIER = 'field-0';\n\nconst limitWaitTimeOption: INodeProperties = {\n\tdisplayName: 'Limit Wait Time',\n\tname: 'limitWaitTime',\n\ttype: 'fixedCollection',\n\tdescription:\n\t\t'Whether the workflow will automatically resume execution after the specified limit type',\n\tdefault: { values: { limitType: 'afterTimeInterval', resumeAmount: 45, resumeUnit: 'minutes' } },\n\toptions: [\n\t\t{\n\t\t\tdisplayName: 'Values',\n\t\t\tname: 'values',\n\t\t\tvalues: limitWaitTimeProperties,\n\t\t},\n\t],\n};\n\nconst appendAttributionOption: INodeProperties = {\n\tdisplayName: 'Append n8n Attribution',\n\tname: 'appendAttribution',\n\ttype: 'boolean',\n\tdefault: true,\n\tdescription:\n\t\t'Whether to include the phrase \"This message was sent automatically with n8n\" to the end of the message',\n};\n\n// Operation Properties ----------------------------------------------------------\nexport function getSendAndWaitProperties(\n\ttargetProperties: INodeProperties[],\n\tresource: string = 'message',\n\tadditionalProperties: INodeProperties[] = [],\n\toptions?: {\n\t\tnoButtonStyle?: boolean;\n\t\tdefaultApproveLabel?: string;\n\t\tdefaultDisapproveLabel?: string;\n\t},\n) {\n\tconst buttonStyle: INodeProperties = {\n\t\tdisplayName: 'Button Style',\n\t\tname: 'buttonStyle',\n\t\ttype: 'options',\n\t\tdefault: 'primary',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Primary',\n\t\t\t\tvalue: 'primary',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Secondary',\n\t\t\t\tvalue: 'secondary',\n\t\t\t},\n\t\t],\n\t};\n\tconst approvalOptionsValues = [\n\t\t{\n\t\t\tdisplayName: 'Type of Approval',\n\t\t\tname: 'approvalType',\n\t\t\ttype: 'options',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: 'single',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Approve Only',\n\t\t\t\t\tvalue: 'single',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Approve and Disapprove',\n\t\t\t\t\tvalue: 'double',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Approve Button Label',\n\t\t\tname: 'approveLabel',\n\t\t\ttype: 'string',\n\t\t\tdefault: options?.defaultApproveLabel || 'Approve',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tapprovalType: ['single', 'double'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...[\n\t\t\toptions?.noButtonStyle\n\t\t\t\t? ({} as INodeProperties)\n\t\t\t\t: {\n\t\t\t\t\t\t...buttonStyle,\n\t\t\t\t\t\tdisplayName: 'Approve Button Style',\n\t\t\t\t\t\tname: 'buttonApprovalStyle',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tapprovalType: ['single', 'double'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t],\n\t\t{\n\t\t\tdisplayName: 'Disapprove Button Label',\n\t\t\tname: 'disapproveLabel',\n\t\t\ttype: 'string',\n\t\t\tdefault: options?.defaultDisapproveLabel || 'Decline',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tapprovalType: ['double'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...[\n\t\t\toptions?.noButtonStyle\n\t\t\t\t? ({} as INodeProperties)\n\t\t\t\t: {\n\t\t\t\t\t\t...buttonStyle,\n\t\t\t\t\t\tdisplayName: 'Disapprove Button Style',\n\t\t\t\t\t\tname: 'buttonDisapprovalStyle',\n\t\t\t\t\t\tdefault: 'secondary',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tapprovalType: ['double'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t],\n\t].filter((p) => Object.keys(p).length) as INodeProperties[];\n\n\tconst sendAndWait: INodeProperties[] = [\n\t\t...targetProperties,\n\t\t{\n\t\t\tdisplayName: 'Subject',\n\t\t\tname: 'subject',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\trequired: true,\n\t\t\tplaceholder: 'e.g. Approval required',\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Message',\n\t\t\tname: 'message',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\trequired: true,\n\t\t\ttypeOptions: {\n\t\t\t\trows: 4,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Response Type',\n\t\t\tname: 'responseType',\n\t\t\ttype: 'options',\n\t\t\tdefault: 'approval',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Approval',\n\t\t\t\t\tvalue: 'approval',\n\t\t\t\t\tdescription: 'User can approve/disapprove from within the message',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Free Text',\n\t\t\t\t\tvalue: 'freeText',\n\t\t\t\t\tdescription: 'User can submit a response via a form',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Custom Form',\n\t\t\t\t\tvalue: 'customForm',\n\t\t\t\t\tdescription: 'User can submit a response via a custom form',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...updateDisplayOptions(\n\t\t\t{\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['customForm'],\n\t\t\t\t},\n\t\t\t},\n\t\t\tformFieldsProperties,\n\t\t),\n\n\t\t{\n\t\t\tdisplayName: 'Approval Options',\n\t\t\tname: 'approvalOptions',\n\t\t\ttype: 'fixedCollection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Values',\n\t\t\t\t\tname: 'values',\n\t\t\t\t\tvalues: approvalOptionsValues,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['approval'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Options',\n\t\t\tname: 'options',\n\t\t\ttype: 'collection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [limitWaitTimeOption, appendAttributionOption],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['approval'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Options',\n\t\t\tname: 'options',\n\t\t\ttype: 'collection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Message Button Label',\n\t\t\t\t\tname: 'messageButtonLabel',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: 'Respond',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Title',\n\t\t\t\t\tname: 'responseFormTitle',\n\t\t\t\t\tdescription: 'Title of the form that the user can access to provide their response',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Description',\n\t\t\t\t\tname: 'responseFormDescription',\n\t\t\t\t\tdescription: 'Description of the form that the user can access to provide their response',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Button Label',\n\t\t\t\t\tname: 'responseFormButtonLabel',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: 'Submit',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Custom Styling',\n\t\t\t\t\tname: 'responseFormCustomCss',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\trows: 10,\n\t\t\t\t\t\teditor: 'cssEditor',\n\t\t\t\t\t},\n\t\t\t\t\tdefault: cssVariables.trim(),\n\t\t\t\t\tdescription: 'Override default styling of the response form with CSS',\n\t\t\t\t},\n\t\t\t\tlimitWaitTimeOption,\n\t\t\t\tappendAttributionOption,\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['freeText', 'customForm'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...additionalProperties,\n\t];\n\n\treturn updateDisplayOptions(\n\t\t{\n\t\t\tshow: {\n\t\t\t\tresource: [resource],\n\t\t\t\toperation: [SEND_AND_WAIT_OPERATION],\n\t\t\t},\n\t\t},\n\t\tsendAndWait,\n\t);\n}\n\n// Webhook Function --------------------------------------------------------------\nconst getFormResponseCustomizations = (context: IWebhookFunctions) => {\n\tconst message = context.getNodeParameter('message', '') as string;\n\tconst options = context.getNodeParameter('options', {}) as FormResponseTypeOptions;\n\n\tlet formTitle = '';\n\tif (options.responseFormTitle) {\n\t\tformTitle = options.responseFormTitle;\n\t}\n\n\tlet formDescription = message;\n\tif (options.responseFormDescription) {\n\t\tformDescription = options.responseFormDescription;\n\t}\n\tformDescription = formDescription.replace(/\\\\n/g, '\\n').replace(/<br>/g, '\\n');\n\n\tlet buttonLabel = 'Submit';\n\tif (options.responseFormButtonLabel) {\n\t\tbuttonLabel = options.responseFormButtonLabel;\n\t}\n\n\treturn {\n\t\tformTitle,\n\t\tformDescription,\n\t\tbuttonLabel,\n\t\tcustomCss: options.responseFormCustomCss,\n\t};\n};\n\nexport async function sendAndWaitWebhook(this: IWebhookFunctions) {\n\tconst method = this.getRequestObject().method;\n\tconst res = this.getResponseObject();\n\tconst req = this.getRequestObject();\n\n\tconst responseType = this.getNodeParameter('responseType', 'approval') as\n\t\t| 'approval'\n\t\t| 'freeText'\n\t\t| 'customForm';\n\n\tif (responseType === 'approval' && isbot(req.headers['user-agent'])) {\n\t\tres.send('');\n\t\treturn { noWebhookResponse: true };\n\t}\n\n\tif (responseType === 'freeText') {\n\t\tif (method === 'GET') {\n\t\t\tconst { formTitle, formDescription, buttonLabel, customCss } =\n\t\t\t\tgetFormResponseCustomizations(this);\n\n\t\t\tconst data = prepareFormData({\n\t\t\t\tformTitle,\n\t\t\t\tformDescription,\n\t\t\t\tformSubmittedHeader: 'Got it, thanks',\n\t\t\t\tformSubmittedText: 'This page can be closed now',\n\t\t\t\tbuttonLabel,\n\t\t\t\tredirectUrl: undefined,\n\t\t\t\tformFields: [\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldLabel: 'Response',\n\t\t\t\t\t\tfieldType: 'textarea',\n\t\t\t\t\t\trequiredField: true,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttestRun: false,\n\t\t\t\tquery: {},\n\t\t\t\tcustomCss,\n\t\t\t});\n\n\t\t\tres.render('form-trigger', data);\n\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\t\tif (method === 'POST') {\n\t\t\tconst data = this.getBodyData().data as IDataObject;\n\n\t\t\treturn {\n\t\t\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\t\t\tworkflowData: [[{ json: { data: { text: data[INPUT_FIELD_IDENTIFIER] } } }]],\n\t\t\t};\n\t\t}\n\t}\n\n\tif (responseType === 'customForm') {\n\t\tconst defineForm = this.getNodeParameter('defineForm', 'fields') as 'fields' | 'json';\n\t\tlet fields: FormFieldsParameter = [];\n\n\t\tif (defineForm === 'json') {\n\t\t\ttry {\n\t\t\t\tconst jsonOutput = this.getNodeParameter('jsonOutput', '', {\n\t\t\t\t\trawExpressions: true,\n\t\t\t\t}) as string;\n\n\t\t\t\tfields = tryToParseJsonToFormFields(resolveRawData(this, jsonOutput));\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message, {\n\t\t\t\t\tdescription: error.message,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tfields = this.getNodeParameter('formFields.values', []) as FormFieldsParameter;\n\t\t}\n\n\t\tif (method === 'GET') {\n\t\t\tconst { formTitle, formDescription, buttonLabel, customCss } =\n\t\t\t\tgetFormResponseCustomizations(this);\n\n\t\t\tconst data = prepareFormData({\n\t\t\t\tformTitle,\n\t\t\t\tformDescription,\n\t\t\t\tformSubmittedHeader: 'Got it, thanks',\n\t\t\t\tformSubmittedText: 'This page can be closed now',\n\t\t\t\tbuttonLabel,\n\t\t\t\tredirectUrl: undefined,\n\t\t\t\tformFields: fields,\n\t\t\t\ttestRun: false,\n\t\t\t\tquery: {},\n\t\t\t\tcustomCss,\n\t\t\t});\n\n\t\t\tres.render('form-trigger', data);\n\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\t\tif (method === 'POST') {\n\t\t\tconst returnItem = await prepareFormReturnItem(this, fields, 'production', true);\n\t\t\tconst json = returnItem.json;\n\n\t\t\tdelete json.submittedAt;\n\t\t\tdelete json.formMode;\n\n\t\t\treturnItem.json = { data: json };\n\n\t\t\treturn {\n\t\t\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\t\t\tworkflowData: [[returnItem]],\n\t\t\t};\n\t\t}\n\t}\n\n\tconst query = req.query as { approved: 'false' | 'true' };\n\tconst approved = query.approved === 'true';\n\treturn {\n\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\tworkflowData: [[{ json: { data: { approved } } }]],\n\t};\n}\n\n// Send and Wait Config -----------------------------------------------------------\nexport function getSendAndWaitConfig(context: IExecuteFunctions): SendAndWaitConfig {\n\tconst message = escapeHtml((context.getNodeParameter('message', 0, '') as string).trim())\n\t\t.replace(/\\\\n/g, '\\n')\n\t\t.replace(/<br>/g, '\\n');\n\tconst subject = escapeHtml(context.getNodeParameter('subject', 0, '') as string);\n\tconst resumeUrl = context.evaluateExpression('{{ $execution?.resumeUrl }}', 0) as string;\n\tconst nodeId = context.evaluateExpression('{{ $nodeId }}', 0) as string;\n\tconst approvalOptions = context.getNodeParameter('approvalOptions.values', 0, {}) as {\n\t\tapprovalType?: 'single' | 'double';\n\t\tapproveLabel?: string;\n\t\tbuttonApprovalStyle?: string;\n\t\tdisapproveLabel?: string;\n\t\tbuttonDisapprovalStyle?: string;\n\t};\n\n\tconst options = context.getNodeParameter('options', 0, {});\n\n\tconst config: SendAndWaitConfig = {\n\t\ttitle: subject,\n\t\tmessage,\n\t\turl: `${resumeUrl}/${nodeId}`,\n\t\toptions: [],\n\t\tappendAttribution: options?.appendAttribution as boolean,\n\t};\n\n\tconst responseType = context.getNodeParameter('responseType', 0, 'approval') as string;\n\n\tif (responseType === 'freeText' || responseType === 'customForm') {\n\t\tconst label = context.getNodeParameter('options.messageButtonLabel', 0, 'Respond') as string;\n\t\tconfig.options.push({\n\t\t\tlabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle: 'primary',\n\t\t});\n\t} else if (approvalOptions.approvalType === 'double') {\n\t\tconst approveLabel = escapeHtml(approvalOptions.approveLabel || 'Approve');\n\t\tconst buttonApprovalStyle = approvalOptions.buttonApprovalStyle || 'primary';\n\t\tconst disapproveLabel = escapeHtml(approvalOptions.disapproveLabel || 'Disapprove');\n\t\tconst buttonDisapprovalStyle = approvalOptions.buttonDisapprovalStyle || 'secondary';\n\n\t\tconfig.options.push({\n\t\t\tlabel: disapproveLabel,\n\t\t\tvalue: 'false',\n\t\t\tstyle: buttonDisapprovalStyle,\n\t\t});\n\t\tconfig.options.push({\n\t\t\tlabel: approveLabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle: buttonApprovalStyle,\n\t\t});\n\t} else {\n\t\tconst label = escapeHtml(approvalOptions.approveLabel || 'Approve');\n\t\tconst style = approvalOptions.buttonApprovalStyle || 'primary';\n\t\tconfig.options.push({\n\t\t\tlabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle,\n\t\t});\n\t}\n\n\treturn config;\n}\n\nexport function createButton(url: string, label: string, approved: string, style: string) {\n\tlet buttonStyle = BUTTON_STYLE_PRIMARY;\n\tif (style === 'secondary') {\n\t\tbuttonStyle = BUTTON_STYLE_SECONDARY;\n\t}\n\treturn `<a href=\"${url}?approved=${approved}\" target=\"_blank\" style=\"${buttonStyle}\">${label}</a>`;\n}\n\nexport function createEmail(context: IExecuteFunctions) {\n\tconst to = (context.getNodeParameter('sendTo', 0, '') as string).trim();\n\tconst config = getSendAndWaitConfig(context);\n\n\tif (to.indexOf('@') === -1 || (to.match(/@/g) || []).length > 1) {\n\t\tconst description = `The email address '${to}' in the 'To' field isn't valid or contains multiple addresses. Please provide only a single email address.`;\n\t\tthrow new NodeOperationError(context.getNode(), 'Invalid email address', {\n\t\t\tdescription,\n\t\t\titemIndex: 0,\n\t\t});\n\t}\n\n\tconst buttons: string[] = [];\n\tfor (const option of config.options) {\n\t\tbuttons.push(createButton(config.url, option.label, option.value, option.style));\n\t}\n\tlet emailBody: string;\n\tif (config.appendAttribution !== false) {\n\t\tconst instanceId = context.getInstanceId();\n\t\temailBody = createEmailBodyWithN8nAttribution(config.message, buttons.join('\\n'), instanceId);\n\t} else {\n\t\temailBody = createEmailBodyWithoutN8nAttribution(config.message, buttons.join('\\n'));\n\t}\n\n\tconst email: IEmail = {\n\t\tto,\n\t\tsubject: config.title,\n\t\tbody: '',\n\t\thtmlBody: emailBody,\n\t};\n\n\treturn email;\n}\n"],"mappings":"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","names":["isbot"]}
1
+ {"version":3,"sources":["../../../utils/sendAndWait/utils.ts"],"sourcesContent":["import isbot from 'isbot';\nimport {\n\tNodeOperationError,\n\tSEND_AND_WAIT_OPERATION,\n\ttryToParseJsonToFormFields,\n\tupdateDisplayOptions,\n} from 'n8n-workflow';\nimport type {\n\tINodeProperties,\n\tIExecuteFunctions,\n\tIWebhookFunctions,\n\tIDataObject,\n\tFormFieldsParameter,\n} from 'n8n-workflow';\n\nimport { limitWaitTimeProperties } from './descriptions';\nimport {\n\tACTION_RECORDED_PAGE,\n\tBUTTON_STYLE_PRIMARY,\n\tBUTTON_STYLE_SECONDARY,\n\tcreateEmailBodyWithN8nAttribution,\n\tcreateEmailBodyWithoutN8nAttribution,\n} from './email-templates';\nimport type { IEmail } from './interfaces';\nimport { cssVariables } from '../../nodes/Form/cssVariables';\nimport { formFieldsProperties } from '../../nodes/Form/Form.node';\nimport {\n\tprepareFormData,\n\tprepareFormReturnItem,\n\tresolveRawData,\n} from '../../nodes/Form/utils/utils';\nimport { escapeHtml } from '../utilities';\n\nexport type SendAndWaitConfig = {\n\ttitle: string;\n\tmessage: string;\n\turl: string;\n\toptions: Array<{ label: string; value: string; style: string }>;\n\tappendAttribution?: boolean;\n};\n\ntype FormResponseTypeOptions = {\n\tmessageButtonLabel?: string;\n\tresponseFormTitle?: string;\n\tresponseFormDescription?: string;\n\tresponseFormButtonLabel?: string;\n\tresponseFormCustomCss?: string;\n};\n\nconst INPUT_FIELD_IDENTIFIER = 'field-0';\n\nconst limitWaitTimeOption: INodeProperties = {\n\tdisplayName: 'Limit Wait Time',\n\tname: 'limitWaitTime',\n\ttype: 'fixedCollection',\n\tdescription:\n\t\t'Whether the workflow will automatically resume execution after the specified limit type',\n\tdefault: { values: { limitType: 'afterTimeInterval', resumeAmount: 45, resumeUnit: 'minutes' } },\n\toptions: [\n\t\t{\n\t\t\tdisplayName: 'Values',\n\t\t\tname: 'values',\n\t\t\tvalues: limitWaitTimeProperties,\n\t\t},\n\t],\n};\n\nconst appendAttributionOption: INodeProperties = {\n\tdisplayName: 'Append n8n Attribution',\n\tname: 'appendAttribution',\n\ttype: 'boolean',\n\tdefault: true,\n\tdescription:\n\t\t'Whether to include the phrase \"This message was sent automatically with n8n\" to the end of the message',\n};\n\n// Operation Properties ----------------------------------------------------------\nexport function getSendAndWaitProperties(\n\ttargetProperties: INodeProperties[],\n\tresource: string = 'message',\n\tadditionalProperties: INodeProperties[] = [],\n\toptions?: {\n\t\tnoButtonStyle?: boolean;\n\t\tdefaultApproveLabel?: string;\n\t\tdefaultDisapproveLabel?: string;\n\t},\n) {\n\tconst buttonStyle: INodeProperties = {\n\t\tdisplayName: 'Button Style',\n\t\tname: 'buttonStyle',\n\t\ttype: 'options',\n\t\tdefault: 'primary',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Primary',\n\t\t\t\tvalue: 'primary',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Secondary',\n\t\t\t\tvalue: 'secondary',\n\t\t\t},\n\t\t],\n\t};\n\tconst approvalOptionsValues = [\n\t\t{\n\t\t\tdisplayName: 'Type of Approval',\n\t\t\tname: 'approvalType',\n\t\t\ttype: 'options',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: 'single',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Approve Only',\n\t\t\t\t\tvalue: 'single',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Approve and Disapprove',\n\t\t\t\t\tvalue: 'double',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Approve Button Label',\n\t\t\tname: 'approveLabel',\n\t\t\ttype: 'string',\n\t\t\tdefault: options?.defaultApproveLabel || 'Approve',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tapprovalType: ['single', 'double'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...[\n\t\t\toptions?.noButtonStyle\n\t\t\t\t? ({} as INodeProperties)\n\t\t\t\t: {\n\t\t\t\t\t\t...buttonStyle,\n\t\t\t\t\t\tdisplayName: 'Approve Button Style',\n\t\t\t\t\t\tname: 'buttonApprovalStyle',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tapprovalType: ['single', 'double'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t],\n\t\t{\n\t\t\tdisplayName: 'Disapprove Button Label',\n\t\t\tname: 'disapproveLabel',\n\t\t\ttype: 'string',\n\t\t\tdefault: options?.defaultDisapproveLabel || 'Decline',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tapprovalType: ['double'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...[\n\t\t\toptions?.noButtonStyle\n\t\t\t\t? ({} as INodeProperties)\n\t\t\t\t: {\n\t\t\t\t\t\t...buttonStyle,\n\t\t\t\t\t\tdisplayName: 'Disapprove Button Style',\n\t\t\t\t\t\tname: 'buttonDisapprovalStyle',\n\t\t\t\t\t\tdefault: 'secondary',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\tapprovalType: ['double'],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t],\n\t].filter((p) => Object.keys(p).length) as INodeProperties[];\n\n\tconst sendAndWait: INodeProperties[] = [\n\t\t...targetProperties,\n\t\t{\n\t\t\tdisplayName: 'Subject',\n\t\t\tname: 'subject',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\trequired: true,\n\t\t\tplaceholder: 'e.g. Approval required',\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Message',\n\t\t\tname: 'message',\n\t\t\ttype: 'string',\n\t\t\tdefault: '',\n\t\t\trequired: true,\n\t\t\ttypeOptions: {\n\t\t\t\trows: 4,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Response Type',\n\t\t\tname: 'responseType',\n\t\t\ttype: 'options',\n\t\t\tdefault: 'approval',\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tname: 'Approval',\n\t\t\t\t\tvalue: 'approval',\n\t\t\t\t\tdescription: 'User can approve/disapprove from within the message',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Free Text',\n\t\t\t\t\tvalue: 'freeText',\n\t\t\t\t\tdescription: 'User can submit a response via a form',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tname: 'Custom Form',\n\t\t\t\t\tvalue: 'customForm',\n\t\t\t\t\tdescription: 'User can submit a response via a custom form',\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t...updateDisplayOptions(\n\t\t\t{\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['customForm'],\n\t\t\t\t},\n\t\t\t},\n\t\t\tformFieldsProperties,\n\t\t),\n\n\t\t{\n\t\t\tdisplayName: 'Approval Options',\n\t\t\tname: 'approvalOptions',\n\t\t\ttype: 'fixedCollection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Values',\n\t\t\t\t\tname: 'values',\n\t\t\t\t\tvalues: approvalOptionsValues,\n\t\t\t\t},\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['approval'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Options',\n\t\t\tname: 'options',\n\t\t\ttype: 'collection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [limitWaitTimeOption, appendAttributionOption],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['approval'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Options',\n\t\t\tname: 'options',\n\t\t\ttype: 'collection',\n\t\t\tplaceholder: 'Add option',\n\t\t\tdefault: {},\n\t\t\toptions: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Message Button Label',\n\t\t\t\t\tname: 'messageButtonLabel',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: 'Respond',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Title',\n\t\t\t\t\tname: 'responseFormTitle',\n\t\t\t\t\tdescription: 'Title of the form that the user can access to provide their response',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Description',\n\t\t\t\t\tname: 'responseFormDescription',\n\t\t\t\t\tdescription: 'Description of the form that the user can access to provide their response',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: '',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Button Label',\n\t\t\t\t\tname: 'responseFormButtonLabel',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tdefault: 'Submit',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Response Form Custom Styling',\n\t\t\t\t\tname: 'responseFormCustomCss',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\trows: 10,\n\t\t\t\t\t\teditor: 'cssEditor',\n\t\t\t\t\t},\n\t\t\t\t\tdefault: cssVariables.trim(),\n\t\t\t\t\tdescription: 'Override default styling of the response form with CSS',\n\t\t\t\t},\n\t\t\t\tlimitWaitTimeOption,\n\t\t\t\tappendAttributionOption,\n\t\t\t],\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\tresponseType: ['freeText', 'customForm'],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t...additionalProperties,\n\t];\n\n\treturn updateDisplayOptions(\n\t\t{\n\t\t\tshow: {\n\t\t\t\tresource: [resource],\n\t\t\t\toperation: [SEND_AND_WAIT_OPERATION],\n\t\t\t},\n\t\t},\n\t\tsendAndWait,\n\t);\n}\n\n// Webhook Function --------------------------------------------------------------\nconst getFormResponseCustomizations = (context: IWebhookFunctions) => {\n\tconst message = context.getNodeParameter('message', '') as string;\n\tconst options = context.getNodeParameter('options', {}) as FormResponseTypeOptions;\n\n\tlet formTitle = '';\n\tif (options.responseFormTitle) {\n\t\tformTitle = options.responseFormTitle;\n\t}\n\n\tlet formDescription = message;\n\tif (options.responseFormDescription) {\n\t\tformDescription = options.responseFormDescription;\n\t}\n\tformDescription = formDescription.replace(/\\\\n/g, '\\n').replace(/<br>/g, '\\n');\n\n\tlet buttonLabel = 'Submit';\n\tif (options.responseFormButtonLabel) {\n\t\tbuttonLabel = options.responseFormButtonLabel;\n\t}\n\n\treturn {\n\t\tformTitle,\n\t\tformDescription,\n\t\tbuttonLabel,\n\t\tcustomCss: options.responseFormCustomCss,\n\t};\n};\n\nexport async function sendAndWaitWebhook(this: IWebhookFunctions) {\n\tconst method = this.getRequestObject().method;\n\tconst res = this.getResponseObject();\n\tconst req = this.getRequestObject();\n\n\tconst responseType = this.getNodeParameter('responseType', 'approval') as\n\t\t| 'approval'\n\t\t| 'freeText'\n\t\t| 'customForm';\n\n\tif (responseType === 'approval' && isbot(req.headers['user-agent'])) {\n\t\tres.send('');\n\t\treturn { noWebhookResponse: true };\n\t}\n\n\tif (responseType === 'freeText') {\n\t\tif (method === 'GET') {\n\t\t\tconst { formTitle, formDescription, buttonLabel, customCss } =\n\t\t\t\tgetFormResponseCustomizations(this);\n\n\t\t\tconst data = prepareFormData({\n\t\t\t\tformTitle,\n\t\t\t\tformDescription,\n\t\t\t\tformSubmittedHeader: 'Got it, thanks',\n\t\t\t\tformSubmittedText: 'This page can be closed now',\n\t\t\t\tbuttonLabel,\n\t\t\t\tredirectUrl: undefined,\n\t\t\t\tformFields: [\n\t\t\t\t\t{\n\t\t\t\t\t\tfieldLabel: 'Response',\n\t\t\t\t\t\tfieldType: 'textarea',\n\t\t\t\t\t\trequiredField: true,\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\ttestRun: false,\n\t\t\t\tquery: {},\n\t\t\t\tcustomCss,\n\t\t\t});\n\n\t\t\tres.render('form-trigger', data);\n\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\t\tif (method === 'POST') {\n\t\t\tconst data = this.getBodyData().data as IDataObject;\n\n\t\t\treturn {\n\t\t\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\t\t\tworkflowData: [[{ json: { data: { text: data[INPUT_FIELD_IDENTIFIER] } } }]],\n\t\t\t};\n\t\t}\n\t}\n\n\tif (responseType === 'customForm') {\n\t\tconst defineForm = this.getNodeParameter('defineForm', 'fields') as 'fields' | 'json';\n\t\tlet fields: FormFieldsParameter = [];\n\n\t\tif (defineForm === 'json') {\n\t\t\ttry {\n\t\t\t\tconst jsonOutput = this.getNodeParameter('jsonOutput', '', {\n\t\t\t\t\trawExpressions: true,\n\t\t\t\t}) as string;\n\n\t\t\t\tfields = tryToParseJsonToFormFields(resolveRawData(this, jsonOutput));\n\t\t\t} catch (error) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), error.message, {\n\t\t\t\t\tdescription: error.message,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tfields = this.getNodeParameter('formFields.values', []) as FormFieldsParameter;\n\t\t}\n\n\t\tif (method === 'GET') {\n\t\t\tconst { formTitle, formDescription, buttonLabel, customCss } =\n\t\t\t\tgetFormResponseCustomizations(this);\n\n\t\t\tconst data = prepareFormData({\n\t\t\t\tformTitle,\n\t\t\t\tformDescription,\n\t\t\t\tformSubmittedHeader: 'Got it, thanks',\n\t\t\t\tformSubmittedText: 'This page can be closed now',\n\t\t\t\tbuttonLabel,\n\t\t\t\tredirectUrl: undefined,\n\t\t\t\tformFields: fields,\n\t\t\t\ttestRun: false,\n\t\t\t\tquery: {},\n\t\t\t\tcustomCss,\n\t\t\t});\n\n\t\t\tres.render('form-trigger', data);\n\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\t\tif (method === 'POST') {\n\t\t\tconst returnItem = await prepareFormReturnItem(this, fields, 'production', true);\n\t\t\tconst json = returnItem.json;\n\n\t\t\tdelete json.submittedAt;\n\t\t\tdelete json.formMode;\n\n\t\t\treturnItem.json = { data: json };\n\n\t\t\treturn {\n\t\t\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\t\t\tworkflowData: [[returnItem]],\n\t\t\t};\n\t\t}\n\t}\n\n\tconst query = req.query as { approved: 'false' | 'true' };\n\tconst approved = query.approved === 'true';\n\treturn {\n\t\twebhookResponse: ACTION_RECORDED_PAGE,\n\t\tworkflowData: [[{ json: { data: { approved } } }]],\n\t};\n}\n\n// Send and Wait Config -----------------------------------------------------------\nexport function getSendAndWaitConfig(context: IExecuteFunctions): SendAndWaitConfig {\n\tconst message = escapeHtml((context.getNodeParameter('message', 0, '') as string).trim())\n\t\t.replace(/\\\\n/g, '\\n')\n\t\t.replace(/<br>/g, '\\n');\n\tconst subject = escapeHtml(context.getNodeParameter('subject', 0, '') as string);\n\tconst resumeUrl = context.evaluateExpression('{{ $execution?.resumeUrl }}', 0) as string;\n\tconst nodeId = context.evaluateExpression('{{ $nodeId }}', 0) as string;\n\tconst approvalOptions = context.getNodeParameter('approvalOptions.values', 0, {}) as {\n\t\tapprovalType?: 'single' | 'double';\n\t\tapproveLabel?: string;\n\t\tbuttonApprovalStyle?: string;\n\t\tdisapproveLabel?: string;\n\t\tbuttonDisapprovalStyle?: string;\n\t};\n\n\tconst options = context.getNodeParameter('options', 0, {});\n\n\tconst config: SendAndWaitConfig = {\n\t\ttitle: subject,\n\t\tmessage,\n\t\turl: `${resumeUrl}/${nodeId}`,\n\t\toptions: [],\n\t\tappendAttribution: options?.appendAttribution as boolean,\n\t};\n\n\tconst responseType = context.getNodeParameter('responseType', 0, 'approval') as string;\n\n\tif (responseType === 'freeText' || responseType === 'customForm') {\n\t\tconst label = context.getNodeParameter('options.messageButtonLabel', 0, 'Respond') as string;\n\t\tconfig.options.push({\n\t\t\tlabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle: 'primary',\n\t\t});\n\t} else if (approvalOptions.approvalType === 'double') {\n\t\tconst approveLabel = escapeHtml(approvalOptions.approveLabel || 'Approve');\n\t\tconst buttonApprovalStyle = approvalOptions.buttonApprovalStyle || 'primary';\n\t\tconst disapproveLabel = escapeHtml(approvalOptions.disapproveLabel || 'Disapprove');\n\t\tconst buttonDisapprovalStyle = approvalOptions.buttonDisapprovalStyle || 'secondary';\n\n\t\tconfig.options.push({\n\t\t\tlabel: disapproveLabel,\n\t\t\tvalue: 'false',\n\t\t\tstyle: buttonDisapprovalStyle,\n\t\t});\n\t\tconfig.options.push({\n\t\t\tlabel: approveLabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle: buttonApprovalStyle,\n\t\t});\n\t} else {\n\t\tconst label = escapeHtml(approvalOptions.approveLabel || 'Approve');\n\t\tconst style = approvalOptions.buttonApprovalStyle || 'primary';\n\t\tconfig.options.push({\n\t\t\tlabel,\n\t\t\tvalue: 'true',\n\t\t\tstyle,\n\t\t});\n\t}\n\n\treturn config;\n}\n\nexport function createButton(url: string, label: string, approved: string, style: string) {\n\tlet buttonStyle = BUTTON_STYLE_PRIMARY;\n\tif (style === 'secondary') {\n\t\tbuttonStyle = BUTTON_STYLE_SECONDARY;\n\t}\n\treturn `<a href=\"${url}?approved=${approved}\" target=\"_blank\" style=\"${buttonStyle}\">${label}</a>`;\n}\n\nexport function createEmail(context: IExecuteFunctions) {\n\tconst to = (context.getNodeParameter('sendTo', 0, '') as string).trim();\n\tconst config = getSendAndWaitConfig(context);\n\n\tif (to.indexOf('@') === -1 || (to.match(/@/g) || []).length > 1) {\n\t\tconst description = `The email address '${to}' in the 'To' field isn't valid or contains multiple addresses. Please provide only a single email address.`;\n\t\tthrow new NodeOperationError(context.getNode(), 'Invalid email address', {\n\t\t\tdescription,\n\t\t\titemIndex: 0,\n\t\t});\n\t}\n\n\tconst buttons: string[] = [];\n\tfor (const option of config.options) {\n\t\tbuttons.push(createButton(config.url, option.label, option.value, option.style));\n\t}\n\tlet emailBody: string;\n\tif (config.appendAttribution !== false) {\n\t\tconst instanceId = context.getInstanceId();\n\t\temailBody = createEmailBodyWithN8nAttribution(config.message, buttons.join('\\n'), instanceId);\n\t} else {\n\t\temailBody = createEmailBodyWithoutN8nAttribution(config.message, buttons.join('\\n'));\n\t}\n\n\tconst email: IEmail = {\n\t\tto,\n\t\tsubject: config.title,\n\t\tbody: '',\n\t\thtmlBody: emailBody,\n\t};\n\n\treturn email;\n}\n"],"mappings":"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","names":["isbot"]}
@@ -46,5 +46,6 @@ declare const sanitizeDataPathKey: (item: IDataObject, key: string) => string;
46
46
  declare function escapeHtml(text: string): string;
47
47
  declare function sortItemKeysByPriorityList(data: INodeExecutionData[], priorityList: string[]): INodeExecutionData[];
48
48
  declare function createUtmCampaignLink(nodeType: string, instanceId?: string): string;
49
+ declare const removeTrailingSlash: (url: string) => string;
49
50
 
50
- export { capitalize, chunk, compareItems, createUtmCampaignLink, escapeHtml, flatten, flattenKeys, flattenObject, formatPrivateKey, fuzzyCompare, generatePairedItemData, getResolvables, keysToLowercase, preparePairedItemDataArray, processJsonInput, sanitizeDataPathKey, shuffleArray, sortItemKeysByPriorityList, updateDisplayOptions, wrapData };
51
+ export { capitalize, chunk, compareItems, createUtmCampaignLink, escapeHtml, flatten, flattenKeys, flattenObject, formatPrivateKey, fuzzyCompare, generatePairedItemData, getResolvables, keysToLowercase, preparePairedItemDataArray, processJsonInput, removeTrailingSlash, sanitizeDataPathKey, shuffleArray, sortItemKeysByPriorityList, updateDisplayOptions, wrapData };
@@ -43,6 +43,7 @@ __export(utilities_exports, {
43
43
  keysToLowercase: () => keysToLowercase,
44
44
  preparePairedItemDataArray: () => preparePairedItemDataArray,
45
45
  processJsonInput: () => processJsonInput,
46
+ removeTrailingSlash: () => removeTrailingSlash,
46
47
  sanitizeDataPathKey: () => sanitizeDataPathKey,
47
48
  shuffleArray: () => shuffleArray,
48
49
  sortItemKeysByPriorityList: () => sortItemKeysByPriorityList,
@@ -358,6 +359,12 @@ function createUtmCampaignLink(nodeType, instanceId) {
358
359
  nodeType
359
360
  )}${instanceId ? "_" + instanceId : ""}`;
360
361
  }
362
+ const removeTrailingSlash = (url) => {
363
+ if (url.endsWith("/")) {
364
+ return url.slice(0, -1);
365
+ }
366
+ return url;
367
+ };
361
368
  // Annotate the CommonJS export names for ESM import in node:
362
369
  0 && (module.exports = {
363
370
  capitalize,
@@ -375,6 +382,7 @@ function createUtmCampaignLink(nodeType, instanceId) {
375
382
  keysToLowercase,
376
383
  preparePairedItemDataArray,
377
384
  processJsonInput,
385
+ removeTrailingSlash,
378
386
  sanitizeDataPathKey,
379
387
  shuffleArray,
380
388
  sortItemKeysByPriorityList,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../utils/utilities.ts"],"sourcesContent":["import get from 'lodash/get';\nimport isEqual from 'lodash/isEqual';\nimport isNull from 'lodash/isNull';\nimport isObject from 'lodash/isObject';\nimport merge from 'lodash/merge';\nimport reduce from 'lodash/reduce';\nimport type {\n\tIDataObject,\n\tIDisplayOptions,\n\tINodeExecutionData,\n\tINodeProperties,\n\tIPairedItemData,\n} from 'n8n-workflow';\nimport { ApplicationError, jsonParse, randomInt } from 'n8n-workflow';\n\n/**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @example\n *\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n */\n\nexport function chunk<T>(array: T[], size = 1) {\n\tconst length = array === null ? 0 : array.length;\n\tif (!length || size < 1) {\n\t\treturn [];\n\t}\n\tlet index = 0;\n\tlet resIndex = 0;\n\tconst result = new Array(Math.ceil(length / size));\n\n\twhile (index < length) {\n\t\tresult[resIndex++] = array.slice(index, (index += size));\n\t}\n\treturn result as T[][];\n}\n\n/**\n * Shuffles an array in place using the Fisher-Yates shuffle algorithm\n * @param {Array} array The array to shuffle.\n */\nexport const shuffleArray = <T>(array: T[]): void => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tconst j = randomInt(i + 1);\n\t\t[array[i], array[j]] = [array[j], array[i]];\n\t}\n};\n\n/**\n * Flattens an object with deep data\n * @param {IDataObject} data The object to flatten\n * @param {string[]} prefix The prefix to add to each key in the returned flat object\n */\nexport const flattenKeys = (obj: IDataObject, prefix: string[] = []): IDataObject => {\n\treturn !isObject(obj)\n\t\t? { [prefix.join('.')]: obj }\n\t\t: reduce(\n\t\t\t\tobj,\n\t\t\t\t(cum, next, key) => merge(cum, flattenKeys(next as IDataObject, [...prefix, key])),\n\t\t\t\t{},\n\t\t\t);\n};\n\n/**\n * Takes a multidimensional array and converts it to a one-dimensional array.\n *\n * @param {Array} nestedArray The array to be flattened.\n * @example\n *\n * flatten([['a', 'b'], ['c', 'd']])\n * // => ['a', 'b', 'c', 'd']\n *\n */\n\nexport function flatten<T>(nestedArray: T[][]) {\n\tconst result = [];\n\n\t(function loop(array: T[] | T[][]) {\n\t\tfor (let i = 0; i < array.length; i++) {\n\t\t\tif (Array.isArray(array[i])) {\n\t\t\t\tloop(array[i] as T[]);\n\t\t\t} else {\n\t\t\t\tresult.push(array[i]);\n\t\t\t}\n\t\t}\n\t})(nestedArray);\n\n\t//TODO: check logic in MicrosoftSql.node.ts\n\n\treturn result as any;\n}\n\n/**\n * Compares the values of specified keys in two objects.\n *\n * @param {T} obj1 - The first object to compare.\n * @param {T} obj2 - The second object to compare.\n * @param {string[]} keys - An array of keys to compare.\n * @param {boolean} disableDotNotation - Whether to use dot notation to access nested properties.\n * @returns {boolean} - Whether the values of the specified keys are equal in both objects.\n */\nexport const compareItems = <T extends { json: Record<string, unknown> }>(\n\tobj1: T,\n\tobj2: T,\n\tkeys: string[],\n\tdisableDotNotation: boolean = false,\n): boolean => {\n\tlet result = true;\n\tfor (const key of keys) {\n\t\tif (!disableDotNotation) {\n\t\t\tif (!isEqual(get(obj1.json, key), get(obj2.json, key))) {\n\t\t\t\tresult = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isEqual(obj1.json[key], obj2.json[key])) {\n\t\t\t\tresult = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n};\n\nexport function updateDisplayOptions(\n\tdisplayOptions: IDisplayOptions,\n\tproperties: INodeProperties[],\n) {\n\treturn properties.map((nodeProperty) => {\n\t\treturn {\n\t\t\t...nodeProperty,\n\t\t\tdisplayOptions: merge({}, nodeProperty.displayOptions, displayOptions),\n\t\t};\n\t});\n}\n\nexport function processJsonInput<T>(jsonData: T, inputName?: string) {\n\tlet values;\n\tconst input = inputName ? `'${inputName}' ` : '';\n\n\tif (typeof jsonData === 'string') {\n\t\ttry {\n\t\t\tvalues = jsonParse(jsonData);\n\t\t} catch (error) {\n\t\t\tthrow new ApplicationError(`Input ${input} must contain a valid JSON`, { level: 'warning' });\n\t\t}\n\t} else if (typeof jsonData === 'object') {\n\t\tvalues = jsonData;\n\t} else {\n\t\tthrow new ApplicationError(`Input ${input} must contain a valid JSON`, { level: 'warning' });\n\t}\n\n\treturn values;\n}\n\nfunction isFalsy<T>(value: T) {\n\tif (isNull(value)) return true;\n\tif (typeof value === 'string' && value === '') return true;\n\tif (Array.isArray(value) && value.length === 0) return true;\n\treturn false;\n}\n\nconst parseStringAndCompareToObject = (str: string, arr: IDataObject) => {\n\ttry {\n\t\tconst parsedArray = jsonParse(str);\n\t\treturn isEqual(parsedArray, arr);\n\t} catch (error) {\n\t\treturn false;\n\t}\n};\n\nexport const fuzzyCompare = (useFuzzyCompare: boolean, compareVersion = 1) => {\n\tif (!useFuzzyCompare) {\n\t\t//Fuzzy compare is false we do strict comparison\n\t\treturn <T, U>(item1: T, item2: U) => isEqual(item1, item2);\n\t}\n\n\treturn <T, U>(item1: T, item2: U) => {\n\t\t//Both types are the same, so we do strict comparison\n\t\tif (!isNull(item1) && !isNull(item2) && typeof item1 === typeof item2) {\n\t\t\treturn isEqual(item1, item2);\n\t\t}\n\n\t\tif (compareVersion >= 2) {\n\t\t\t//Null, 0 and \"0\" treated as equal\n\t\t\tif (isNull(item1) && (isNull(item2) || item2 === 0 || item2 === '0')) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (isNull(item2) && (isNull(item1) || item1 === 0 || item1 === '0')) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t//Null, empty strings, empty arrays all treated as the same\n\t\tif (isFalsy(item1) && isFalsy(item2)) return true;\n\n\t\t//When a field is missing in one branch and isFalsy() in another, treat them as matching\n\t\tif (isFalsy(item1) && item2 === undefined) return true;\n\t\tif (item1 === undefined && isFalsy(item2)) return true;\n\n\t\t//Compare numbers and strings representing that number\n\t\tif (typeof item1 === 'number' && typeof item2 === 'string') {\n\t\t\treturn item1.toString() === item2;\n\t\t}\n\n\t\tif (typeof item1 === 'string' && typeof item2 === 'number') {\n\t\t\treturn item1 === item2.toString();\n\t\t}\n\n\t\t//Compare objects/arrays and their stringified version\n\t\tif (!isNull(item1) && typeof item1 === 'object' && typeof item2 === 'string') {\n\t\t\treturn parseStringAndCompareToObject(item2, item1 as IDataObject);\n\t\t}\n\n\t\tif (!isNull(item2) && typeof item1 === 'string' && typeof item2 === 'object') {\n\t\t\treturn parseStringAndCompareToObject(item1, item2 as IDataObject);\n\t\t}\n\n\t\t//Compare booleans and strings representing the boolean (’true’, ‘True’, ‘TRUE’)\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'string') {\n\t\t\tif (item1 === true && item2.toLocaleLowerCase() === 'true') return true;\n\t\t\tif (item1 === false && item2.toLocaleLowerCase() === 'false') return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'string') {\n\t\t\tif (item2 === true && item1.toLocaleLowerCase() === 'true') return true;\n\t\t\tif (item2 === false && item1.toLocaleLowerCase() === 'false') return true;\n\t\t}\n\n\t\t//Compare booleans and the numbers/string 0 and 1\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'number') {\n\t\t\tif (item1 === true && item2 === 1) return true;\n\t\t\tif (item1 === false && item2 === 0) return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'number') {\n\t\t\tif (item2 === true && item1 === 1) return true;\n\t\t\tif (item2 === false && item1 === 0) return true;\n\t\t}\n\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'string') {\n\t\t\tif (item1 === true && item2 === '1') return true;\n\t\t\tif (item1 === false && item2 === '0') return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'string') {\n\t\t\tif (item2 === true && item1 === '1') return true;\n\t\t\tif (item2 === false && item1 === '0') return true;\n\t\t}\n\n\t\treturn isEqual(item1, item2);\n\t};\n};\n\nexport function wrapData(data: IDataObject | IDataObject[]): INodeExecutionData[] {\n\tif (!Array.isArray(data)) {\n\t\treturn [{ json: data }];\n\t}\n\treturn data.map((item) => ({\n\t\tjson: item,\n\t}));\n}\n\nexport const keysToLowercase = <T>(headers: T) => {\n\tif (typeof headers !== 'object' || Array.isArray(headers) || headers === null) return headers;\n\treturn Object.entries(headers).reduce((acc, [key, value]) => {\n\t\tacc[key.toLowerCase()] = value as IDataObject;\n\t\treturn acc;\n\t}, {} as IDataObject);\n};\n\n/**\n * Formats a private key by removing unnecessary whitespace and adding line breaks.\n * @param privateKey - The private key to format.\n * @returns The formatted private key.\n */\nexport function formatPrivateKey(privateKey: string, keyIsPublic = false): string {\n\tlet regex = /(PRIVATE KEY|CERTIFICATE)/;\n\tif (keyIsPublic) {\n\t\tregex = /(PUBLIC KEY)/;\n\t}\n\tif (!privateKey || /\\n/.test(privateKey)) {\n\t\treturn privateKey;\n\t}\n\tlet formattedPrivateKey = '';\n\tconst parts = privateKey.split('-----').filter((item) => item !== '');\n\tparts.forEach((part) => {\n\t\tif (regex.test(part)) {\n\t\t\tformattedPrivateKey += `-----${part}-----`;\n\t\t} else {\n\t\t\tconst passRegex = /Proc-Type|DEK-Info/;\n\t\t\tif (passRegex.test(part)) {\n\t\t\t\tpart = part.replace(/:\\s+/g, ':');\n\t\t\t\tformattedPrivateKey += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t} else {\n\t\t\t\tformattedPrivateKey += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t}\n\t\t}\n\t});\n\treturn formattedPrivateKey;\n}\n\n/**\n * @TECH_DEBT Explore replacing with handlebars\n */\nexport function getResolvables(expression: string) {\n\tif (!expression) return [];\n\n\tconst resolvables = [];\n\tconst resolvableRegex = /({{[\\s\\S]*?}})/g;\n\n\tlet match;\n\n\twhile ((match = resolvableRegex.exec(expression)) !== null) {\n\t\tif (match[1]) {\n\t\t\tresolvables.push(match[1]);\n\t\t}\n\t}\n\n\treturn resolvables;\n}\n\n/**\n * Flattens an object with deep data\n *\n * @param {IDataObject} data The object to flatten\n */\nexport function flattenObject(data: IDataObject) {\n\tconst returnData: IDataObject = {};\n\tfor (const key1 of Object.keys(data)) {\n\t\tif (data[key1] !== null && typeof data[key1] === 'object') {\n\t\t\tif (data[key1] instanceof Date) {\n\t\t\t\treturnData[key1] = data[key1]?.toString();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst flatObject = flattenObject(data[key1] as IDataObject);\n\t\t\tfor (const key2 in flatObject) {\n\t\t\t\tif (flatObject[key2] === undefined) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturnData[`${key1}.${key2}`] = flatObject[key2];\n\t\t\t}\n\t\t} else {\n\t\t\treturnData[key1] = data[key1];\n\t\t}\n\t}\n\treturn returnData;\n}\n\n/**\n * Capitalizes the first letter of a string\n *\n * @param {string} string The string to capitalize\n */\nexport function capitalize(str: string): string {\n\tif (!str) return str;\n\n\tconst chars = str.split('');\n\tchars[0] = chars[0].toUpperCase();\n\n\treturn chars.join('');\n}\n\nexport function generatePairedItemData(length: number): IPairedItemData[] {\n\treturn Array.from({ length }, (_, item) => ({\n\t\titem,\n\t}));\n}\n\n/**\n * Output Paired Item Data Array\n *\n * @param {number | IPairedItemData | IPairedItemData[] | undefined} pairedItem\n */\nexport function preparePairedItemDataArray(\n\tpairedItem: number | IPairedItemData | IPairedItemData[] | undefined,\n): IPairedItemData[] {\n\tif (pairedItem === undefined) return [];\n\tif (typeof pairedItem === 'number') return [{ item: pairedItem }];\n\tif (Array.isArray(pairedItem)) return pairedItem;\n\treturn [pairedItem];\n}\n\nexport const sanitizeDataPathKey = (item: IDataObject, key: string) => {\n\tif (item[key] !== undefined) {\n\t\treturn key;\n\t}\n\n\tif (\n\t\t(key.startsWith(\"['\") && key.endsWith(\"']\")) ||\n\t\t(key.startsWith('[\"') && key.endsWith('\"]'))\n\t) {\n\t\tkey = key.slice(2, -2);\n\t\tif (item[key] !== undefined) {\n\t\t\treturn key;\n\t\t}\n\t}\n\treturn key;\n};\n\n/**\n * Escape HTML\n *\n * @param {string} text The text to escape\n */\nexport function escapeHtml(text: string): string {\n\tif (!text) return '';\n\treturn text.replace(/&amp;|&lt;|&gt;|&#39;|&quot;/g, (match) => {\n\t\tswitch (match) {\n\t\t\tcase '&amp;':\n\t\t\t\treturn '&';\n\t\t\tcase '&lt;':\n\t\t\t\treturn '<';\n\t\t\tcase '&gt;':\n\t\t\t\treturn '>';\n\t\t\tcase '&#39;':\n\t\t\t\treturn \"'\";\n\t\t\tcase '&quot;':\n\t\t\t\treturn '\"';\n\t\t\tdefault:\n\t\t\t\treturn match;\n\t\t}\n\t});\n}\n\n/**\n * Sorts each item json's keys by a priority list\n *\n * @param {INodeExecutionData[]} data The array of items which keys will be sorted\n * @param {string[]} priorityList The priority list, keys of item.json will be sorted in this order first then alphabetically\n */\nexport function sortItemKeysByPriorityList(data: INodeExecutionData[], priorityList: string[]) {\n\treturn data.map((item) => {\n\t\tconst itemKeys = Object.keys(item.json);\n\n\t\tconst updatedKeysOrder = itemKeys.sort((a, b) => {\n\t\t\tconst indexA = priorityList.indexOf(a);\n\t\t\tconst indexB = priorityList.indexOf(b);\n\n\t\t\tif (indexA !== -1 && indexB !== -1) {\n\t\t\t\treturn indexA - indexB;\n\t\t\t} else if (indexA !== -1) {\n\t\t\t\treturn -1;\n\t\t\t} else if (indexB !== -1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn a.localeCompare(b);\n\t\t});\n\n\t\tconst updatedItem: IDataObject = {};\n\t\tfor (const key of updatedKeysOrder) {\n\t\t\tupdatedItem[key] = item.json[key];\n\t\t}\n\n\t\titem.json = updatedItem;\n\t\treturn item;\n\t});\n}\n\nexport function createUtmCampaignLink(nodeType: string, instanceId?: string) {\n\treturn `https://n8n.io/?utm_source=n8n-internal&utm_medium=powered_by&utm_campaign=${encodeURIComponent(\n\t\tnodeType,\n\t)}${instanceId ? '_' + instanceId : ''}`;\n}\n"],"mappings":"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","names":["isObject","reduce","merge","isEqual","get","isNull"]}
1
+ {"version":3,"sources":["../../utils/utilities.ts"],"sourcesContent":["import get from 'lodash/get';\nimport isEqual from 'lodash/isEqual';\nimport isNull from 'lodash/isNull';\nimport isObject from 'lodash/isObject';\nimport merge from 'lodash/merge';\nimport reduce from 'lodash/reduce';\nimport type {\n\tIDataObject,\n\tIDisplayOptions,\n\tINodeExecutionData,\n\tINodeProperties,\n\tIPairedItemData,\n} from 'n8n-workflow';\nimport { ApplicationError, jsonParse, randomInt } from 'n8n-workflow';\n\n/**\n * Creates an array of elements split into groups the length of `size`.\n * If `array` can't be split evenly, the final chunk will be the remaining\n * elements.\n *\n * @param {Array} array The array to process.\n * @param {number} [size=1] The length of each chunk\n * @example\n *\n * chunk(['a', 'b', 'c', 'd'], 2)\n * // => [['a', 'b'], ['c', 'd']]\n *\n * chunk(['a', 'b', 'c', 'd'], 3)\n * // => [['a', 'b', 'c'], ['d']]\n */\n\nexport function chunk<T>(array: T[], size = 1) {\n\tconst length = array === null ? 0 : array.length;\n\tif (!length || size < 1) {\n\t\treturn [];\n\t}\n\tlet index = 0;\n\tlet resIndex = 0;\n\tconst result = new Array(Math.ceil(length / size));\n\n\twhile (index < length) {\n\t\tresult[resIndex++] = array.slice(index, (index += size));\n\t}\n\treturn result as T[][];\n}\n\n/**\n * Shuffles an array in place using the Fisher-Yates shuffle algorithm\n * @param {Array} array The array to shuffle.\n */\nexport const shuffleArray = <T>(array: T[]): void => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tconst j = randomInt(i + 1);\n\t\t[array[i], array[j]] = [array[j], array[i]];\n\t}\n};\n\n/**\n * Flattens an object with deep data\n * @param {IDataObject} data The object to flatten\n * @param {string[]} prefix The prefix to add to each key in the returned flat object\n */\nexport const flattenKeys = (obj: IDataObject, prefix: string[] = []): IDataObject => {\n\treturn !isObject(obj)\n\t\t? { [prefix.join('.')]: obj }\n\t\t: reduce(\n\t\t\t\tobj,\n\t\t\t\t(cum, next, key) => merge(cum, flattenKeys(next as IDataObject, [...prefix, key])),\n\t\t\t\t{},\n\t\t\t);\n};\n\n/**\n * Takes a multidimensional array and converts it to a one-dimensional array.\n *\n * @param {Array} nestedArray The array to be flattened.\n * @example\n *\n * flatten([['a', 'b'], ['c', 'd']])\n * // => ['a', 'b', 'c', 'd']\n *\n */\n\nexport function flatten<T>(nestedArray: T[][]) {\n\tconst result = [];\n\n\t(function loop(array: T[] | T[][]) {\n\t\tfor (let i = 0; i < array.length; i++) {\n\t\t\tif (Array.isArray(array[i])) {\n\t\t\t\tloop(array[i] as T[]);\n\t\t\t} else {\n\t\t\t\tresult.push(array[i]);\n\t\t\t}\n\t\t}\n\t})(nestedArray);\n\n\t//TODO: check logic in MicrosoftSql.node.ts\n\n\treturn result as any;\n}\n\n/**\n * Compares the values of specified keys in two objects.\n *\n * @param {T} obj1 - The first object to compare.\n * @param {T} obj2 - The second object to compare.\n * @param {string[]} keys - An array of keys to compare.\n * @param {boolean} disableDotNotation - Whether to use dot notation to access nested properties.\n * @returns {boolean} - Whether the values of the specified keys are equal in both objects.\n */\nexport const compareItems = <T extends { json: Record<string, unknown> }>(\n\tobj1: T,\n\tobj2: T,\n\tkeys: string[],\n\tdisableDotNotation: boolean = false,\n): boolean => {\n\tlet result = true;\n\tfor (const key of keys) {\n\t\tif (!disableDotNotation) {\n\t\t\tif (!isEqual(get(obj1.json, key), get(obj2.json, key))) {\n\t\t\t\tresult = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tif (!isEqual(obj1.json[key], obj2.json[key])) {\n\t\t\t\tresult = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn result;\n};\n\nexport function updateDisplayOptions(\n\tdisplayOptions: IDisplayOptions,\n\tproperties: INodeProperties[],\n) {\n\treturn properties.map((nodeProperty) => {\n\t\treturn {\n\t\t\t...nodeProperty,\n\t\t\tdisplayOptions: merge({}, nodeProperty.displayOptions, displayOptions),\n\t\t};\n\t});\n}\n\nexport function processJsonInput<T>(jsonData: T, inputName?: string) {\n\tlet values;\n\tconst input = inputName ? `'${inputName}' ` : '';\n\n\tif (typeof jsonData === 'string') {\n\t\ttry {\n\t\t\tvalues = jsonParse(jsonData);\n\t\t} catch (error) {\n\t\t\tthrow new ApplicationError(`Input ${input} must contain a valid JSON`, { level: 'warning' });\n\t\t}\n\t} else if (typeof jsonData === 'object') {\n\t\tvalues = jsonData;\n\t} else {\n\t\tthrow new ApplicationError(`Input ${input} must contain a valid JSON`, { level: 'warning' });\n\t}\n\n\treturn values;\n}\n\nfunction isFalsy<T>(value: T) {\n\tif (isNull(value)) return true;\n\tif (typeof value === 'string' && value === '') return true;\n\tif (Array.isArray(value) && value.length === 0) return true;\n\treturn false;\n}\n\nconst parseStringAndCompareToObject = (str: string, arr: IDataObject) => {\n\ttry {\n\t\tconst parsedArray = jsonParse(str);\n\t\treturn isEqual(parsedArray, arr);\n\t} catch (error) {\n\t\treturn false;\n\t}\n};\n\nexport const fuzzyCompare = (useFuzzyCompare: boolean, compareVersion = 1) => {\n\tif (!useFuzzyCompare) {\n\t\t//Fuzzy compare is false we do strict comparison\n\t\treturn <T, U>(item1: T, item2: U) => isEqual(item1, item2);\n\t}\n\n\treturn <T, U>(item1: T, item2: U) => {\n\t\t//Both types are the same, so we do strict comparison\n\t\tif (!isNull(item1) && !isNull(item2) && typeof item1 === typeof item2) {\n\t\t\treturn isEqual(item1, item2);\n\t\t}\n\n\t\tif (compareVersion >= 2) {\n\t\t\t//Null, 0 and \"0\" treated as equal\n\t\t\tif (isNull(item1) && (isNull(item2) || item2 === 0 || item2 === '0')) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (isNull(item2) && (isNull(item1) || item1 === 0 || item1 === '0')) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t//Null, empty strings, empty arrays all treated as the same\n\t\tif (isFalsy(item1) && isFalsy(item2)) return true;\n\n\t\t//When a field is missing in one branch and isFalsy() in another, treat them as matching\n\t\tif (isFalsy(item1) && item2 === undefined) return true;\n\t\tif (item1 === undefined && isFalsy(item2)) return true;\n\n\t\t//Compare numbers and strings representing that number\n\t\tif (typeof item1 === 'number' && typeof item2 === 'string') {\n\t\t\treturn item1.toString() === item2;\n\t\t}\n\n\t\tif (typeof item1 === 'string' && typeof item2 === 'number') {\n\t\t\treturn item1 === item2.toString();\n\t\t}\n\n\t\t//Compare objects/arrays and their stringified version\n\t\tif (!isNull(item1) && typeof item1 === 'object' && typeof item2 === 'string') {\n\t\t\treturn parseStringAndCompareToObject(item2, item1 as IDataObject);\n\t\t}\n\n\t\tif (!isNull(item2) && typeof item1 === 'string' && typeof item2 === 'object') {\n\t\t\treturn parseStringAndCompareToObject(item1, item2 as IDataObject);\n\t\t}\n\n\t\t//Compare booleans and strings representing the boolean (’true’, ‘True’, ‘TRUE’)\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'string') {\n\t\t\tif (item1 === true && item2.toLocaleLowerCase() === 'true') return true;\n\t\t\tif (item1 === false && item2.toLocaleLowerCase() === 'false') return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'string') {\n\t\t\tif (item2 === true && item1.toLocaleLowerCase() === 'true') return true;\n\t\t\tif (item2 === false && item1.toLocaleLowerCase() === 'false') return true;\n\t\t}\n\n\t\t//Compare booleans and the numbers/string 0 and 1\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'number') {\n\t\t\tif (item1 === true && item2 === 1) return true;\n\t\t\tif (item1 === false && item2 === 0) return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'number') {\n\t\t\tif (item2 === true && item1 === 1) return true;\n\t\t\tif (item2 === false && item1 === 0) return true;\n\t\t}\n\n\t\tif (typeof item1 === 'boolean' && typeof item2 === 'string') {\n\t\t\tif (item1 === true && item2 === '1') return true;\n\t\t\tif (item1 === false && item2 === '0') return true;\n\t\t}\n\n\t\tif (typeof item2 === 'boolean' && typeof item1 === 'string') {\n\t\t\tif (item2 === true && item1 === '1') return true;\n\t\t\tif (item2 === false && item1 === '0') return true;\n\t\t}\n\n\t\treturn isEqual(item1, item2);\n\t};\n};\n\nexport function wrapData(data: IDataObject | IDataObject[]): INodeExecutionData[] {\n\tif (!Array.isArray(data)) {\n\t\treturn [{ json: data }];\n\t}\n\treturn data.map((item) => ({\n\t\tjson: item,\n\t}));\n}\n\nexport const keysToLowercase = <T>(headers: T) => {\n\tif (typeof headers !== 'object' || Array.isArray(headers) || headers === null) return headers;\n\treturn Object.entries(headers).reduce((acc, [key, value]) => {\n\t\tacc[key.toLowerCase()] = value as IDataObject;\n\t\treturn acc;\n\t}, {} as IDataObject);\n};\n\n/**\n * Formats a private key by removing unnecessary whitespace and adding line breaks.\n * @param privateKey - The private key to format.\n * @returns The formatted private key.\n */\nexport function formatPrivateKey(privateKey: string, keyIsPublic = false): string {\n\tlet regex = /(PRIVATE KEY|CERTIFICATE)/;\n\tif (keyIsPublic) {\n\t\tregex = /(PUBLIC KEY)/;\n\t}\n\tif (!privateKey || /\\n/.test(privateKey)) {\n\t\treturn privateKey;\n\t}\n\tlet formattedPrivateKey = '';\n\tconst parts = privateKey.split('-----').filter((item) => item !== '');\n\tparts.forEach((part) => {\n\t\tif (regex.test(part)) {\n\t\t\tformattedPrivateKey += `-----${part}-----`;\n\t\t} else {\n\t\t\tconst passRegex = /Proc-Type|DEK-Info/;\n\t\t\tif (passRegex.test(part)) {\n\t\t\t\tpart = part.replace(/:\\s+/g, ':');\n\t\t\t\tformattedPrivateKey += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t} else {\n\t\t\t\tformattedPrivateKey += part.replace(/\\\\n/g, '\\n').replace(/\\s+/g, '\\n');\n\t\t\t}\n\t\t}\n\t});\n\treturn formattedPrivateKey;\n}\n\n/**\n * @TECH_DEBT Explore replacing with handlebars\n */\nexport function getResolvables(expression: string) {\n\tif (!expression) return [];\n\n\tconst resolvables = [];\n\tconst resolvableRegex = /({{[\\s\\S]*?}})/g;\n\n\tlet match;\n\n\twhile ((match = resolvableRegex.exec(expression)) !== null) {\n\t\tif (match[1]) {\n\t\t\tresolvables.push(match[1]);\n\t\t}\n\t}\n\n\treturn resolvables;\n}\n\n/**\n * Flattens an object with deep data\n *\n * @param {IDataObject} data The object to flatten\n */\nexport function flattenObject(data: IDataObject) {\n\tconst returnData: IDataObject = {};\n\tfor (const key1 of Object.keys(data)) {\n\t\tif (data[key1] !== null && typeof data[key1] === 'object') {\n\t\t\tif (data[key1] instanceof Date) {\n\t\t\t\treturnData[key1] = data[key1]?.toString();\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst flatObject = flattenObject(data[key1] as IDataObject);\n\t\t\tfor (const key2 in flatObject) {\n\t\t\t\tif (flatObject[key2] === undefined) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\treturnData[`${key1}.${key2}`] = flatObject[key2];\n\t\t\t}\n\t\t} else {\n\t\t\treturnData[key1] = data[key1];\n\t\t}\n\t}\n\treturn returnData;\n}\n\n/**\n * Capitalizes the first letter of a string\n *\n * @param {string} string The string to capitalize\n */\nexport function capitalize(str: string): string {\n\tif (!str) return str;\n\n\tconst chars = str.split('');\n\tchars[0] = chars[0].toUpperCase();\n\n\treturn chars.join('');\n}\n\nexport function generatePairedItemData(length: number): IPairedItemData[] {\n\treturn Array.from({ length }, (_, item) => ({\n\t\titem,\n\t}));\n}\n\n/**\n * Output Paired Item Data Array\n *\n * @param {number | IPairedItemData | IPairedItemData[] | undefined} pairedItem\n */\nexport function preparePairedItemDataArray(\n\tpairedItem: number | IPairedItemData | IPairedItemData[] | undefined,\n): IPairedItemData[] {\n\tif (pairedItem === undefined) return [];\n\tif (typeof pairedItem === 'number') return [{ item: pairedItem }];\n\tif (Array.isArray(pairedItem)) return pairedItem;\n\treturn [pairedItem];\n}\n\nexport const sanitizeDataPathKey = (item: IDataObject, key: string) => {\n\tif (item[key] !== undefined) {\n\t\treturn key;\n\t}\n\n\tif (\n\t\t(key.startsWith(\"['\") && key.endsWith(\"']\")) ||\n\t\t(key.startsWith('[\"') && key.endsWith('\"]'))\n\t) {\n\t\tkey = key.slice(2, -2);\n\t\tif (item[key] !== undefined) {\n\t\t\treturn key;\n\t\t}\n\t}\n\treturn key;\n};\n\n/**\n * Escape HTML\n *\n * @param {string} text The text to escape\n */\nexport function escapeHtml(text: string): string {\n\tif (!text) return '';\n\treturn text.replace(/&amp;|&lt;|&gt;|&#39;|&quot;/g, (match) => {\n\t\tswitch (match) {\n\t\t\tcase '&amp;':\n\t\t\t\treturn '&';\n\t\t\tcase '&lt;':\n\t\t\t\treturn '<';\n\t\t\tcase '&gt;':\n\t\t\t\treturn '>';\n\t\t\tcase '&#39;':\n\t\t\t\treturn \"'\";\n\t\t\tcase '&quot;':\n\t\t\t\treturn '\"';\n\t\t\tdefault:\n\t\t\t\treturn match;\n\t\t}\n\t});\n}\n\n/**\n * Sorts each item json's keys by a priority list\n *\n * @param {INodeExecutionData[]} data The array of items which keys will be sorted\n * @param {string[]} priorityList The priority list, keys of item.json will be sorted in this order first then alphabetically\n */\nexport function sortItemKeysByPriorityList(data: INodeExecutionData[], priorityList: string[]) {\n\treturn data.map((item) => {\n\t\tconst itemKeys = Object.keys(item.json);\n\n\t\tconst updatedKeysOrder = itemKeys.sort((a, b) => {\n\t\t\tconst indexA = priorityList.indexOf(a);\n\t\t\tconst indexB = priorityList.indexOf(b);\n\n\t\t\tif (indexA !== -1 && indexB !== -1) {\n\t\t\t\treturn indexA - indexB;\n\t\t\t} else if (indexA !== -1) {\n\t\t\t\treturn -1;\n\t\t\t} else if (indexB !== -1) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn a.localeCompare(b);\n\t\t});\n\n\t\tconst updatedItem: IDataObject = {};\n\t\tfor (const key of updatedKeysOrder) {\n\t\t\tupdatedItem[key] = item.json[key];\n\t\t}\n\n\t\titem.json = updatedItem;\n\t\treturn item;\n\t});\n}\n\nexport function createUtmCampaignLink(nodeType: string, instanceId?: string) {\n\treturn `https://n8n.io/?utm_source=n8n-internal&utm_medium=powered_by&utm_campaign=${encodeURIComponent(\n\t\tnodeType,\n\t)}${instanceId ? '_' + instanceId : ''}`;\n}\n\nexport const removeTrailingSlash = (url: string) => {\n\tif (url.endsWith('/')) {\n\t\treturn url.slice(0, -1);\n\t}\n\treturn url;\n};\n"],"mappings":"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","names":["isObject","reduce","merge","isEqual","get","isNull"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n8n-nodes-base",
3
- "version": "1.97.0",
3
+ "version": "1.98.0",
4
4
  "description": "Base nodes of n8n",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -861,7 +861,7 @@
861
861
  "@types/xml2js": "^0.4.14",
862
862
  "eslint-plugin-n8n-nodes-base": "^1.16.3",
863
863
  "@n8n/typescript-config": "1.2.0",
864
- "n8n-core": "1.98.0"
864
+ "n8n-core": "1.99.0"
865
865
  },
866
866
  "dependencies": {
867
867
  "@aws-sdk/client-sso-oidc": "3.808.0",
@@ -930,10 +930,10 @@
930
930
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz",
931
931
  "xml2js": "0.6.2",
932
932
  "xmlhttprequest-ssl": "3.1.0",
933
- "@n8n/config": "1.43.0",
934
933
  "@n8n/di": "0.6.0",
934
+ "@n8n/config": "1.43.0",
935
935
  "@n8n/imap": "0.10.0",
936
- "n8n-workflow": "1.96.0"
936
+ "n8n-workflow": "1.97.0"
937
937
  },
938
938
  "license": "SEE LICENSE IN LICENSE.md",
939
939
  "homepage": "https://n8n.io",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../nodes/Form/formCompletionUtils.ts"],"sourcesContent":["import { type Response } from 'express';\nimport {\n\ttype NodeTypeAndVersion,\n\ttype IWebhookFunctions,\n\ttype IWebhookResponseData,\n\ttype IBinaryData,\n\ttype IDataObject,\n\tOperationalError,\n} from 'n8n-workflow';\n\nimport { sanitizeCustomCss, sanitizeHtml } from './utils';\n\nconst getBinaryDataFromNode = (context: IWebhookFunctions, nodeName: string): IDataObject => {\n\treturn context.evaluateExpression(`{{ $('${nodeName}').first().binary }}`) as IDataObject;\n};\n\nexport const binaryResponse = async (\n\tcontext: IWebhookFunctions,\n): Promise<{ data: string | Buffer; fileName: string; type: string }> => {\n\tconst inputDataFieldName = context.getNodeParameter('inputDataFieldName', '') as string;\n\tconst parentNodes = context.getParentNodes(context.getNode().name);\n\tconst binaryNode = parentNodes\n\t\t.reverse()\n\t\t.find((node) => getBinaryDataFromNode(context, node?.name)?.hasOwnProperty(inputDataFieldName));\n\tif (!binaryNode) {\n\t\tthrow new OperationalError(`No binary data with field ${inputDataFieldName} found.`);\n\t}\n\tconst binaryData = getBinaryDataFromNode(context, binaryNode?.name)[\n\t\tinputDataFieldName\n\t] as IBinaryData;\n\n\treturn {\n\t\t// If a binaryData has an id, the following field is set:\n\t\t// N8N_DEFAULT_BINARY_DATA_MODE=filesystem\n\t\tdata: binaryData.id\n\t\t\t? await context.helpers.binaryToBuffer(await context.helpers.getBinaryStream(binaryData.id))\n\t\t\t: atob(binaryData.data),\n\t\tfileName: binaryData.fileName ?? 'file',\n\t\ttype: binaryData.mimeType,\n\t};\n};\n\nexport const renderFormCompletion = async (\n\tcontext: IWebhookFunctions,\n\tres: Response,\n\ttrigger: NodeTypeAndVersion,\n): Promise<IWebhookResponseData> => {\n\tconst completionTitle = context.getNodeParameter('completionTitle', '') as string;\n\tconst completionMessage = context.getNodeParameter('completionMessage', '') as string;\n\tconst redirectUrl = context.getNodeParameter('redirectUrl', '') as string;\n\tconst options = context.getNodeParameter('options', {}) as {\n\t\tformTitle: string;\n\t\tcustomCss?: string;\n\t};\n\tconst responseText = context.getNodeParameter('responseText', '') as string;\n\tconst binary =\n\t\tcontext.getNodeParameter('respondWith', '') === 'returnBinary'\n\t\t\t? await binaryResponse(context)\n\t\t\t: '';\n\n\tlet title = options.formTitle;\n\tif (!title) {\n\t\ttitle = context.evaluateExpression(`{{ $('${trigger?.name}').params.formTitle }}`) as string;\n\t}\n\tconst appendAttribution = context.evaluateExpression(\n\t\t`{{ $('${trigger?.name}').params.options?.appendAttribution === false ? false : true }}`,\n\t) as boolean;\n\n\tres.render('form-trigger-completion', {\n\t\ttitle: completionTitle,\n\t\tmessage: completionMessage,\n\t\tformTitle: title,\n\t\tappendAttribution,\n\t\tresponseText: sanitizeHtml(responseText),\n\t\tresponseBinary: encodeURIComponent(JSON.stringify(binary)),\n\t\tdangerousCustomCss: sanitizeCustomCss(options.customCss),\n\t\tredirectUrl,\n\t});\n\n\treturn { noWebhookResponse: true };\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAOO;AAEP,mBAAgD;AAEhD,MAAM,wBAAwB,CAAC,SAA4B,aAAkC;AAC5F,SAAO,QAAQ,mBAAmB,SAAS,QAAQ,sBAAsB;AAC1E;AAEO,MAAM,iBAAiB,OAC7B,YACwE;AACxE,QAAM,qBAAqB,QAAQ,iBAAiB,sBAAsB,EAAE;AAC5E,QAAM,cAAc,QAAQ,eAAe,QAAQ,QAAQ,EAAE,IAAI;AACjE,QAAM,aAAa,YACjB,QAAQ,EACR,KAAK,CAAC,SAAS,sBAAsB,SAAS,MAAM,IAAI,GAAG,eAAe,kBAAkB,CAAC;AAC/F,MAAI,CAAC,YAAY;AAChB,UAAM,IAAI,qCAAiB,6BAA6B,kBAAkB,SAAS;AAAA,EACpF;AACA,QAAM,aAAa,sBAAsB,SAAS,YAAY,IAAI,EACjE,kBACD;AAEA,SAAO;AAAA;AAAA;AAAA,IAGN,MAAM,WAAW,KACd,MAAM,QAAQ,QAAQ,eAAe,MAAM,QAAQ,QAAQ,gBAAgB,WAAW,EAAE,CAAC,IACzF,KAAK,WAAW,IAAI;AAAA,IACvB,UAAU,WAAW,YAAY;AAAA,IACjC,MAAM,WAAW;AAAA,EAClB;AACD;AAEO,MAAM,uBAAuB,OACnC,SACA,KACA,YACmC;AACnC,QAAM,kBAAkB,QAAQ,iBAAiB,mBAAmB,EAAE;AACtE,QAAM,oBAAoB,QAAQ,iBAAiB,qBAAqB,EAAE;AAC1E,QAAM,cAAc,QAAQ,iBAAiB,eAAe,EAAE;AAC9D,QAAM,UAAU,QAAQ,iBAAiB,WAAW,CAAC,CAAC;AAItD,QAAM,eAAe,QAAQ,iBAAiB,gBAAgB,EAAE;AAChE,QAAM,SACL,QAAQ,iBAAiB,eAAe,EAAE,MAAM,iBAC7C,MAAM,eAAe,OAAO,IAC5B;AAEJ,MAAI,QAAQ,QAAQ;AACpB,MAAI,CAAC,OAAO;AACX,YAAQ,QAAQ,mBAAmB,SAAS,SAAS,IAAI,wBAAwB;AAAA,EAClF;AACA,QAAM,oBAAoB,QAAQ;AAAA,IACjC,SAAS,SAAS,IAAI;AAAA,EACvB;AAEA,MAAI,OAAO,2BAA2B;AAAA,IACrC,OAAO;AAAA,IACP,SAAS;AAAA,IACT,WAAW;AAAA,IACX;AAAA,IACA,kBAAc,2BAAa,YAAY;AAAA,IACvC,gBAAgB,mBAAmB,KAAK,UAAU,MAAM,CAAC;AAAA,IACzD,wBAAoB,gCAAkB,QAAQ,SAAS;AAAA,IACvD;AAAA,EACD,CAAC;AAED,SAAO,EAAE,mBAAmB,KAAK;AAClC;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../nodes/Form/formNodeUtils.ts"],"sourcesContent":["import { type Response } from 'express';\nimport {\n\ttype NodeTypeAndVersion,\n\ttype IWebhookFunctions,\n\ttype FormFieldsParameter,\n\ttype IWebhookResponseData,\n} from 'n8n-workflow';\n\nimport { renderForm } from './utils';\n\nexport const renderFormNode = async (\n\tcontext: IWebhookFunctions,\n\tres: Response,\n\ttrigger: NodeTypeAndVersion,\n\tfields: FormFieldsParameter,\n\tmode: 'test' | 'production',\n): Promise<IWebhookResponseData> => {\n\tconst options = context.getNodeParameter('options', {}) as {\n\t\tformTitle: string;\n\t\tformDescription: string;\n\t\tbuttonLabel: string;\n\t\tcustomCss?: string;\n\t};\n\n\tlet title = options.formTitle;\n\tif (!title) {\n\t\ttitle = context.evaluateExpression(`{{ $('${trigger?.name}').params.formTitle }}`) as string;\n\t}\n\n\tlet buttonLabel = options.buttonLabel;\n\tif (!buttonLabel) {\n\t\tbuttonLabel =\n\t\t\t(context.evaluateExpression(\n\t\t\t\t`{{ $('${trigger?.name}').params.options?.buttonLabel }}`,\n\t\t\t) as string) || 'Submit';\n\t}\n\n\tconst appendAttribution = context.evaluateExpression(\n\t\t`{{ $('${trigger?.name}').params.options?.appendAttribution === false ? false : true }}`,\n\t) as boolean;\n\n\trenderForm({\n\t\tcontext,\n\t\tres,\n\t\tformTitle: title,\n\t\tformDescription: options.formDescription,\n\t\tformFields: fields,\n\t\tresponseMode: 'responseNode',\n\t\tmode,\n\t\tredirectUrl: undefined,\n\t\tappendAttribution,\n\t\tbuttonLabel,\n\t\tcustomCss: options.customCss,\n\t});\n\n\treturn {\n\t\tnoWebhookResponse: true,\n\t};\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,mBAA2B;AAEpB,MAAM,iBAAiB,OAC7B,SACA,KACA,SACA,QACA,SACmC;AACnC,QAAM,UAAU,QAAQ,iBAAiB,WAAW,CAAC,CAAC;AAOtD,MAAI,QAAQ,QAAQ;AACpB,MAAI,CAAC,OAAO;AACX,YAAQ,QAAQ,mBAAmB,SAAS,SAAS,IAAI,wBAAwB;AAAA,EAClF;AAEA,MAAI,cAAc,QAAQ;AAC1B,MAAI,CAAC,aAAa;AACjB,kBACE,QAAQ;AAAA,MACR,SAAS,SAAS,IAAI;AAAA,IACvB,KAAgB;AAAA,EAClB;AAEA,QAAM,oBAAoB,QAAQ;AAAA,IACjC,SAAS,SAAS,IAAI;AAAA,EACvB;AAEA,+BAAW;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,iBAAiB,QAAQ;AAAA,IACzB,YAAY;AAAA,IACZ,cAAc;AAAA,IACd;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;AAAA,IACA,WAAW,QAAQ;AAAA,EACpB,CAAC;AAED,SAAO;AAAA,IACN,mBAAmB;AAAA,EACpB;AACD;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../nodes/Form/utils.ts"],"sourcesContent":["import type { Response } from 'express';\nimport isbot from 'isbot';\nimport { DateTime } from 'luxon';\nimport type {\n\tINodeExecutionData,\n\tMultiPartFormData,\n\tIDataObject,\n\tIWebhookFunctions,\n\tFormFieldsParameter,\n\tNodeTypeAndVersion,\n} from 'n8n-workflow';\nimport {\n\tFORM_NODE_TYPE,\n\tFORM_TRIGGER_NODE_TYPE,\n\tNodeOperationError,\n\tWAIT_NODE_TYPE,\n\tjsonParse,\n} from 'n8n-workflow';\nimport sanitize from 'sanitize-html';\n\nimport type { FormTriggerData, FormTriggerInput } from './interfaces';\nimport { FORM_TRIGGER_AUTHENTICATION_PROPERTY } from './interfaces';\nimport { getResolvables } from '../../utils/utilities';\nimport { WebhookAuthorizationError } from '../Webhook/error';\nimport { validateWebhookAuthentication } from '../Webhook/utils';\n\nexport function sanitizeHtml(text: string) {\n\treturn sanitize(text, {\n\t\tallowedTags: [\n\t\t\t'b',\n\t\t\t'div',\n\t\t\t'i',\n\t\t\t'iframe',\n\t\t\t'img',\n\t\t\t'video',\n\t\t\t'source',\n\t\t\t'em',\n\t\t\t'strong',\n\t\t\t'a',\n\t\t\t'h1',\n\t\t\t'h2',\n\t\t\t'h3',\n\t\t\t'h4',\n\t\t\t'h5',\n\t\t\t'h6',\n\t\t\t'u',\n\t\t\t'sub',\n\t\t\t'sup',\n\t\t\t'code',\n\t\t\t'pre',\n\t\t\t'span',\n\t\t\t'br',\n\t\t\t'ul',\n\t\t\t'ol',\n\t\t\t'li',\n\t\t\t'p',\n\t\t],\n\t\tallowedAttributes: {\n\t\t\ta: ['href', 'target', 'rel'],\n\t\t\timg: ['src', 'alt', 'width', 'height'],\n\t\t\tvideo: ['*'],\n\t\t\tiframe: ['*'],\n\t\t\tsource: ['*'],\n\t\t},\n\t\ttransformTags: {\n\t\t\tiframe: sanitize.simpleTransform('iframe', {\n\t\t\t\tsandbox: '',\n\t\t\t\treferrerpolicy: 'strict-origin-when-cross-origin',\n\t\t\t\tallow: 'fullscreen; autoplay; encrypted-media',\n\t\t\t}),\n\t\t},\n\t});\n}\n\nexport const prepareFormFields = (context: IWebhookFunctions, fields: FormFieldsParameter) => {\n\treturn fields.map((field) => {\n\t\tif (field.fieldType === 'html') {\n\t\t\tlet { html } = field;\n\n\t\t\tif (!html) return field;\n\n\t\t\tfor (const resolvable of getResolvables(html)) {\n\t\t\t\thtml = html.replace(resolvable, context.evaluateExpression(resolvable) as string);\n\t\t\t}\n\n\t\t\tfield.html = sanitizeHtml(html);\n\t\t}\n\n\t\tif (field.fieldType === 'hiddenField') {\n\t\t\tfield.fieldLabel = field.fieldName as string;\n\t\t}\n\n\t\treturn field;\n\t});\n};\n\nexport function sanitizeCustomCss(css: string | undefined): string | undefined {\n\tif (!css) return undefined;\n\n\t// Use sanitize-html with custom settings for CSS\n\treturn sanitize(css, {\n\t\tallowedTags: [], // No HTML tags allowed\n\t\tallowedAttributes: {}, // No attributes allowed\n\t\t// This ensures we're only keeping the text content\n\t\t// which should be the CSS, while removing any HTML/script tags\n\t});\n}\n\nexport function createDescriptionMetadata(description: string) {\n\treturn description === ''\n\t\t? 'n8n form'\n\t\t: description.replace(/^\\s*\\n+|<\\/?[^>]+(>|$)/g, '').slice(0, 150);\n}\n\nexport function prepareFormData({\n\tformTitle,\n\tformDescription,\n\tformSubmittedHeader,\n\tformSubmittedText,\n\tredirectUrl,\n\tformFields,\n\ttestRun,\n\tquery,\n\tinstanceId,\n\tuseResponseData,\n\tappendAttribution = true,\n\tbuttonLabel,\n\tcustomCss,\n}: {\n\tformTitle: string;\n\tformDescription: string;\n\tformSubmittedText: string | undefined;\n\tredirectUrl: string | undefined;\n\tformFields: FormFieldsParameter;\n\ttestRun: boolean;\n\tquery: IDataObject;\n\tinstanceId?: string;\n\tuseResponseData?: boolean;\n\tappendAttribution?: boolean;\n\tbuttonLabel?: string;\n\tformSubmittedHeader?: string;\n\tcustomCss?: string;\n}) {\n\tconst utm_campaign = instanceId ? `&utm_campaign=${instanceId}` : '';\n\tconst n8nWebsiteLink = `https://n8n.io/?utm_source=n8n-internal&utm_medium=form-trigger${utm_campaign}`;\n\n\tif (formSubmittedText === undefined) {\n\t\tformSubmittedText = 'Your response has been recorded';\n\t}\n\n\tconst formData: FormTriggerData = {\n\t\ttestRun,\n\t\tformTitle,\n\t\tformDescription,\n\t\tformDescriptionMetadata: createDescriptionMetadata(formDescription),\n\t\tformSubmittedHeader,\n\t\tformSubmittedText,\n\t\tn8nWebsiteLink,\n\t\tformFields: [],\n\t\tuseResponseData,\n\t\tappendAttribution,\n\t\tbuttonLabel,\n\t\tdangerousCustomCss: sanitizeCustomCss(customCss),\n\t};\n\n\tif (redirectUrl) {\n\t\tif (!redirectUrl.includes('://')) {\n\t\t\tredirectUrl = `http://${redirectUrl}`;\n\t\t}\n\t\tformData.redirectUrl = redirectUrl;\n\t}\n\n\tfor (const [index, field] of formFields.entries()) {\n\t\tconst { fieldType, requiredField, multiselect, placeholder } = field;\n\n\t\tconst input: IDataObject = {\n\t\t\tid: `field-${index}`,\n\t\t\terrorId: `error-field-${index}`,\n\t\t\tlabel: field.fieldLabel,\n\t\t\tinputRequired: requiredField ? 'form-required' : '',\n\t\t\tdefaultValue: query[field.fieldLabel] ?? '',\n\t\t\tplaceholder,\n\t\t};\n\n\t\tif (multiselect) {\n\t\t\tinput.isMultiSelect = true;\n\t\t\tinput.multiSelectOptions =\n\t\t\t\tfield.fieldOptions?.values.map((e, i) => ({\n\t\t\t\t\tid: `option${i}_${input.id}`,\n\t\t\t\t\tlabel: e.option,\n\t\t\t\t})) ?? [];\n\t\t} else if (fieldType === 'file') {\n\t\t\tinput.isFileInput = true;\n\t\t\tinput.acceptFileTypes = field.acceptFileTypes;\n\t\t\tinput.multipleFiles = field.multipleFiles ? 'multiple' : '';\n\t\t} else if (fieldType === 'dropdown') {\n\t\t\tinput.isSelect = true;\n\t\t\tconst fieldOptions = field.fieldOptions?.values ?? [];\n\t\t\tinput.selectOptions = fieldOptions.map((e) => e.option);\n\t\t} else if (fieldType === 'textarea') {\n\t\t\tinput.isTextarea = true;\n\t\t} else if (fieldType === 'html') {\n\t\t\tinput.isHtml = true;\n\t\t\tinput.html = field.html as string;\n\t\t} else if (fieldType === 'hiddenField') {\n\t\t\tinput.isHidden = true;\n\t\t\tinput.hiddenName = field.fieldName as string;\n\t\t\tinput.hiddenValue =\n\t\t\t\tinput.defaultValue === '' ? (field.fieldValue as string) : input.defaultValue;\n\t\t} else {\n\t\t\tinput.isInput = true;\n\t\t\tinput.type = fieldType as 'text' | 'number' | 'date' | 'email';\n\t\t}\n\n\t\tformData.formFields.push(input as FormTriggerInput);\n\t}\n\n\treturn formData;\n}\n\nexport const validateResponseModeConfiguration = (context: IWebhookFunctions) => {\n\tconst responseMode = context.getNodeParameter('responseMode', 'onReceived') as string;\n\tconst connectedNodes = context.getChildNodes(context.getNode().name);\n\tconst nodeVersion = context.getNode().typeVersion;\n\n\tconst isRespondToWebhookConnected = connectedNodes.some(\n\t\t(node) => node.type === 'n8n-nodes-base.respondToWebhook',\n\t);\n\n\tif (!isRespondToWebhookConnected && responseMode === 'responseNode') {\n\t\tthrow new NodeOperationError(\n\t\t\tcontext.getNode(),\n\t\t\tnew Error('No Respond to Webhook node found in the workflow'),\n\t\t\t{\n\t\t\t\tdescription:\n\t\t\t\t\t'Insert a Respond to Webhook node to your workflow to respond to the form submission or choose another option for the “Respond When” parameter',\n\t\t\t},\n\t\t);\n\t}\n\n\tif (isRespondToWebhookConnected && responseMode !== 'responseNode' && nodeVersion <= 2.1) {\n\t\tthrow new NodeOperationError(\n\t\t\tcontext.getNode(),\n\t\t\tnew Error(`${context.getNode().name} node not correctly configured`),\n\t\t\t{\n\t\t\t\tdescription:\n\t\t\t\t\t'Set the “Respond When” parameter to “Using Respond to Webhook Node” or remove the Respond to Webhook node',\n\t\t\t},\n\t\t);\n\t}\n\n\tif (isRespondToWebhookConnected && nodeVersion > 2.1) {\n\t\tthrow new NodeOperationError(\n\t\t\tcontext.getNode(),\n\t\t\tnew Error(\n\t\t\t\t'The \"Respond to Webhook\" node is not supported in workflows initiated by the \"n8n Form Trigger\"',\n\t\t\t),\n\t\t\t{\n\t\t\t\tdescription:\n\t\t\t\t\t'To configure your response, add an \"n8n Form\" node and set the \"Page Type\" to \"Form Ending\"',\n\t\t\t},\n\t\t);\n\t}\n};\n\nexport function addFormResponseDataToReturnItem(\n\treturnItem: INodeExecutionData,\n\tformFields: FormFieldsParameter,\n\tbodyData: IDataObject,\n) {\n\tfor (const [index, field] of formFields.entries()) {\n\t\tconst key = `field-${index}`;\n\t\tconst name = field.fieldLabel ?? field.fieldName;\n\t\tlet value = bodyData[key] ?? null;\n\n\t\tif (value === null) {\n\t\t\treturnItem.json[name] = null;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (field.fieldType === 'html') {\n\t\t\tif (field.elementName) {\n\t\t\t\treturnItem.json[field.elementName] = value;\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (field.fieldType === 'number') {\n\t\t\tvalue = Number(value);\n\t\t}\n\t\tif (field.fieldType === 'text') {\n\t\t\tvalue = String(value).trim();\n\t\t}\n\t\tif (field.multiselect && typeof value === 'string') {\n\t\t\tvalue = jsonParse(value);\n\t\t}\n\t\tif (field.fieldType === 'date' && value && field.formatDate !== '') {\n\t\t\tvalue = DateTime.fromFormat(String(value), 'yyyy-mm-dd').toFormat(field.formatDate as string);\n\t\t}\n\t\tif (field.fieldType === 'file' && field.multipleFiles && !Array.isArray(value)) {\n\t\t\tvalue = [value];\n\t\t}\n\n\t\treturnItem.json[name] = value;\n\t}\n}\n\nexport async function prepareFormReturnItem(\n\tcontext: IWebhookFunctions,\n\tformFields: FormFieldsParameter,\n\tmode: 'test' | 'production',\n\tuseWorkflowTimezone: boolean = false,\n) {\n\tconst bodyData = (context.getBodyData().data as IDataObject) ?? {};\n\tconst files = (context.getBodyData().files as IDataObject) ?? {};\n\n\tconst returnItem: INodeExecutionData = {\n\t\tjson: {},\n\t};\n\tif (files && Object.keys(files).length) {\n\t\treturnItem.binary = {};\n\t}\n\n\tfor (const key of Object.keys(files)) {\n\t\tconst processFiles: MultiPartFormData.File[] = [];\n\t\tlet multiFile = false;\n\t\tconst filesInput = files[key] as MultiPartFormData.File[] | MultiPartFormData.File;\n\n\t\tif (Array.isArray(filesInput)) {\n\t\t\tbodyData[key] = filesInput.map((file) => ({\n\t\t\t\tfilename: file.originalFilename,\n\t\t\t\tmimetype: file.mimetype,\n\t\t\t\tsize: file.size,\n\t\t\t}));\n\t\t\tprocessFiles.push(...filesInput);\n\t\t\tmultiFile = true;\n\t\t} else {\n\t\t\tbodyData[key] = {\n\t\t\t\tfilename: filesInput.originalFilename,\n\t\t\t\tmimetype: filesInput.mimetype,\n\t\t\t\tsize: filesInput.size,\n\t\t\t};\n\t\t\tprocessFiles.push(filesInput);\n\t\t}\n\n\t\tconst entryIndex = Number(key.replace(/field-/g, ''));\n\t\tconst fieldLabel = isNaN(entryIndex) ? key : formFields[entryIndex].fieldLabel;\n\n\t\tlet fileCount = 0;\n\t\tfor (const file of processFiles) {\n\t\t\tlet binaryPropertyName = fieldLabel.replace(/\\W/g, '_');\n\n\t\t\tif (multiFile) {\n\t\t\t\tbinaryPropertyName += `_${fileCount++}`;\n\t\t\t}\n\n\t\t\treturnItem.binary![binaryPropertyName] = await context.nodeHelpers.copyBinaryFile(\n\t\t\t\tfile.filepath,\n\t\t\t\tfile.originalFilename ?? file.newFilename,\n\t\t\t\tfile.mimetype,\n\t\t\t);\n\t\t}\n\t}\n\n\taddFormResponseDataToReturnItem(returnItem, formFields, bodyData);\n\n\tconst timezone = useWorkflowTimezone ? context.getTimezone() : 'UTC';\n\treturnItem.json.submittedAt = DateTime.now().setZone(timezone).toISO();\n\n\treturnItem.json.formMode = mode;\n\n\tif (\n\t\tcontext.getNode().type === FORM_TRIGGER_NODE_TYPE &&\n\t\tObject.keys(context.getRequestObject().query || {}).length\n\t) {\n\t\treturnItem.json.formQueryParameters = context.getRequestObject().query;\n\t}\n\n\treturn returnItem;\n}\n\nexport function renderForm({\n\tcontext,\n\tres,\n\tformTitle,\n\tformDescription,\n\tformFields,\n\tresponseMode,\n\tmode,\n\tformSubmittedText,\n\tredirectUrl,\n\tappendAttribution,\n\tbuttonLabel,\n\tcustomCss,\n}: {\n\tcontext: IWebhookFunctions;\n\tres: Response;\n\tformTitle: string;\n\tformDescription: string;\n\tformFields: FormFieldsParameter;\n\tresponseMode: string;\n\tmode: 'test' | 'production';\n\tformSubmittedText?: string;\n\tredirectUrl?: string;\n\tappendAttribution?: boolean;\n\tbuttonLabel?: string;\n\tcustomCss?: string;\n}) {\n\tformDescription = (formDescription || '').replace(/\\\\n/g, '\\n').replace(/<br>/g, '\\n');\n\tconst instanceId = context.getInstanceId();\n\n\tconst useResponseData = responseMode === 'responseNode';\n\n\tlet query: IDataObject = {};\n\n\tif (context.getNode().type === FORM_TRIGGER_NODE_TYPE) {\n\t\tquery = context.getRequestObject().query as IDataObject;\n\t} else if (context.getNode().type === FORM_NODE_TYPE) {\n\t\tconst parentNodes = context.getParentNodes(context.getNode().name);\n\t\tconst trigger = parentNodes.find(\n\t\t\t(node) => node.type === FORM_TRIGGER_NODE_TYPE,\n\t\t) as NodeTypeAndVersion;\n\t\ttry {\n\t\t\tconst triggerQueryParameters = context.evaluateExpression(\n\t\t\t\t`{{ $('${trigger?.name}').first().json.formQueryParameters }}`,\n\t\t\t) as IDataObject;\n\n\t\t\tif (triggerQueryParameters) {\n\t\t\t\tquery = triggerQueryParameters;\n\t\t\t}\n\t\t} catch (error) {}\n\t}\n\n\tformFields = prepareFormFields(context, formFields);\n\n\tconst data = prepareFormData({\n\t\tformTitle,\n\t\tformDescription,\n\t\tformSubmittedText,\n\t\tredirectUrl,\n\t\tformFields,\n\t\ttestRun: mode === 'test',\n\t\tquery,\n\t\tinstanceId,\n\t\tuseResponseData,\n\t\tappendAttribution,\n\t\tbuttonLabel,\n\t\tcustomCss,\n\t});\n\n\tres.render('form-trigger', data);\n}\n\nexport const isFormConnected = (nodes: NodeTypeAndVersion[]) => {\n\treturn nodes.some(\n\t\t(n) =>\n\t\t\tn.type === FORM_NODE_TYPE || (n.type === WAIT_NODE_TYPE && n.parameters?.resume === 'form'),\n\t);\n};\n\nexport async function formWebhook(\n\tcontext: IWebhookFunctions,\n\tauthProperty = FORM_TRIGGER_AUTHENTICATION_PROPERTY,\n) {\n\tconst node = context.getNode();\n\tconst options = context.getNodeParameter('options', {}) as {\n\t\tignoreBots?: boolean;\n\t\trespondWithOptions?: {\n\t\t\tvalues: {\n\t\t\t\trespondWith: 'text' | 'redirect';\n\t\t\t\tformSubmittedText: string;\n\t\t\t\tredirectUrl: string;\n\t\t\t};\n\t\t};\n\t\tformSubmittedText?: string;\n\t\tuseWorkflowTimezone?: boolean;\n\t\tappendAttribution?: boolean;\n\t\tbuttonLabel?: string;\n\t\tcustomCss?: string;\n\t};\n\tconst res = context.getResponseObject();\n\tconst req = context.getRequestObject();\n\n\ttry {\n\t\tif (options.ignoreBots && isbot(req.headers['user-agent'])) {\n\t\t\tthrow new WebhookAuthorizationError(403);\n\t\t}\n\t\tif (node.typeVersion > 1) {\n\t\t\tawait validateWebhookAuthentication(context, authProperty);\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof WebhookAuthorizationError) {\n\t\t\tres.setHeader('WWW-Authenticate', 'Basic realm=\"Enter credentials\"');\n\t\t\tres.status(401).send();\n\t\t\treturn { noWebhookResponse: true };\n\t\t}\n\t\tthrow error;\n\t}\n\n\tconst mode = context.getMode() === 'manual' ? 'test' : 'production';\n\tconst formFields = context.getNodeParameter('formFields.values', []) as FormFieldsParameter;\n\n\tconst method = context.getRequestObject().method;\n\n\tvalidateResponseModeConfiguration(context);\n\n\t//Show the form on GET request\n\tif (method === 'GET') {\n\t\tconst formTitle = context.getNodeParameter('formTitle', '') as string;\n\t\tconst formDescription = sanitizeHtml(context.getNodeParameter('formDescription', '') as string);\n\t\tlet responseMode = context.getNodeParameter('responseMode', '') as string;\n\n\t\tlet formSubmittedText;\n\t\tlet redirectUrl;\n\t\tlet appendAttribution = true;\n\n\t\tif (options.respondWithOptions) {\n\t\t\tconst values = (options.respondWithOptions as IDataObject).values as IDataObject;\n\t\t\tif (values.respondWith === 'text') {\n\t\t\t\tformSubmittedText = values.formSubmittedText as string;\n\t\t\t}\n\t\t\tif (values.respondWith === 'redirect') {\n\t\t\t\tredirectUrl = values.redirectUrl as string;\n\t\t\t}\n\t\t} else {\n\t\t\tformSubmittedText = options.formSubmittedText as string;\n\t\t}\n\n\t\tif (options.appendAttribution === false) {\n\t\t\tappendAttribution = false;\n\t\t}\n\n\t\tlet buttonLabel = 'Submit';\n\n\t\tif (options.buttonLabel) {\n\t\t\tbuttonLabel = options.buttonLabel;\n\t\t}\n\n\t\tconst connectedNodes = context.getChildNodes(context.getNode().name, {\n\t\t\tincludeNodeParameters: true,\n\t\t});\n\t\tconst hasNextPage = isFormConnected(connectedNodes);\n\n\t\tif (hasNextPage) {\n\t\t\tredirectUrl = undefined;\n\t\t\tresponseMode = 'responseNode';\n\t\t}\n\n\t\trenderForm({\n\t\t\tcontext,\n\t\t\tres,\n\t\t\tformTitle,\n\t\t\tformDescription,\n\t\t\tformFields,\n\t\t\tresponseMode,\n\t\t\tmode,\n\t\t\tformSubmittedText,\n\t\t\tredirectUrl,\n\t\t\tappendAttribution,\n\t\t\tbuttonLabel,\n\t\t\tcustomCss: options.customCss,\n\t\t});\n\n\t\treturn {\n\t\t\tnoWebhookResponse: true,\n\t\t};\n\t}\n\n\tlet { useWorkflowTimezone } = options;\n\n\tif (useWorkflowTimezone === undefined && node.typeVersion > 2) {\n\t\tuseWorkflowTimezone = true;\n\t}\n\n\tconst returnItem = await prepareFormReturnItem(context, formFields, mode, useWorkflowTimezone);\n\n\treturn {\n\t\twebhookResponse: { status: 200 },\n\t\tworkflowData: [[returnItem]],\n\t};\n}\n\nexport function resolveRawData(context: IWebhookFunctions, rawData: string) {\n\tconst resolvables = getResolvables(rawData);\n\tlet returnData: string = rawData;\n\n\tif (returnData.startsWith('=')) {\n\t\treturnData = returnData.replace(/^=+/, '');\n\t} else {\n\t\treturn returnData;\n\t}\n\n\tif (resolvables.length) {\n\t\tfor (const resolvable of resolvables) {\n\t\t\tconst resolvedValue = context.evaluateExpression(`${resolvable}`);\n\n\t\t\tif (typeof resolvedValue === 'object' && resolvedValue !== null) {\n\t\t\t\treturnData = returnData.replace(resolvable, JSON.stringify(resolvedValue));\n\t\t\t} else {\n\t\t\t\treturnData = returnData.replace(resolvable, resolvedValue as string);\n\t\t\t}\n\t\t}\n\t}\n\treturn returnData;\n}\n"],"mappings":"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","names":["sanitize","isbot"]}