UNPKG

n8n

Version:

n8n Workflow Automation Tool

222 lines • 9.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildInstanceAiRunPinDataPlan = buildInstanceAiRunPinDataPlan; exports.sdkPinDataToRuntime = sdkPinDataToRuntime; exports.pruneUnreachedVerificationPinData = pruneUnreachedVerificationPinData; exports.getPrunedVerificationPinData = getPrunedVerificationPinData; const di_1 = require("@n8n/di"); const n8n_workflow_1 = require("n8n-workflow"); const execution_persistence_1 = require("../../executions/execution-persistence"); const trigger_run_data_1 = require("./trigger-run-data"); function buildInstanceAiRunPinDataPlan(args) { const workflowPinData = args.workflowPinData; const verificationPinData = sdkPinDataToRuntime(args.verificationPinData); const basePinData = { ...workflowPinData, ...verificationPinData }; let nonVerificationPinData = { ...workflowPinData }; const mockDataSources = []; if (args.inputData && args.triggerNode) { mockDataSources.push('trigger_input'); } if (Object.keys(verificationPinData).length > 0) { mockDataSources.push('verification_pin_data'); } if (Object.keys(workflowPinData).length > 0) { mockDataSources.push('workflow_pin_data'); } if (args.inputData && args.triggerNode) { const triggerPinData = getPinDataForTrigger(args.triggerNode, args.inputData); const runPinData = { ...basePinData, ...triggerPinData }; nonVerificationPinData = { ...nonVerificationPinData, ...triggerPinData }; const triggerItems = triggerPinData[args.triggerNode.name]; return { runPinData, nonVerificationPinData, verificationPinData, mockDataSources, startNodeName: args.triggerNode.name, triggerItems, triggerExecutionData: (0, trigger_run_data_1.createTriggerExecutionData)({ triggerNode: args.triggerNode, pinData: runPinData, triggerItems, }), }; } const runPinData = Object.keys(basePinData).length > 0 ? basePinData : undefined; return { runPinData, nonVerificationPinData, verificationPinData, mockDataSources, triggerExecutionData: args.triggerNode ? (0, trigger_run_data_1.createTriggerExecutionData)({ triggerNode: args.triggerNode, pinData: runPinData }) : undefined, }; } function sdkPinDataToRuntime(pinData) { const result = {}; if (!pinData) return result; for (const [nodeName, items] of Object.entries(pinData)) { result[nodeName] = items.map((item) => ({ json: (item ?? {}) })); } return result; } async function pruneUnreachedVerificationPinData(args) { const { executionId, verificationPinData, nonVerificationPinData, executedNodeNames } = args; const verificationNodeNames = Object.keys(verificationPinData); if (verificationNodeNames.length === 0) return; const executionPersistence = di_1.Container.get(execution_persistence_1.ExecutionPersistence); const execution = await executionPersistence.findSingleExecution(executionId, { includeData: true, unflattenData: true, }); const executionData = execution?.data; const resultData = executionData?.resultData; const persistedPinData = resultData?.pinData; if (!executionData || !resultData || !persistedPinData) return; const nextPinData = getPrunedVerificationPinData({ persistedPinData, verificationPinData, nonVerificationPinData, reachedNodeNames: executedNodeNames ?? Object.keys(resultData.runData ?? {}), }); if (!nextPinData) return; const nextExecutionData = { ...executionData, resultData: { ...resultData, pinData: nextPinData, }, }; await executionPersistence.updateExistingExecution(executionId, { data: nextExecutionData, }); } function getPrunedVerificationPinData(args) { const reachedNodeNames = new Set(args.reachedNodeNames); let nextPinData; for (const nodeName of Object.keys(args.verificationPinData)) { if (reachedNodeNames.has(nodeName) || args.persistedPinData[nodeName] === undefined) continue; nextPinData ??= { ...args.persistedPinData }; const preservedPinData = args.nonVerificationPinData[nodeName]; if (preservedPinData) { nextPinData[nodeName] = preservedPinData; } else { delete nextPinData[nodeName]; } } return nextPinData; } function validateInputDataShape(node, inputData) { if (node.type !== n8n_workflow_1.FORM_TRIGGER_NODE_TYPE) return; const formFieldsValue = inputData.formFields; const looksWrapped = typeof formFieldsValue === 'object' && formFieldsValue !== null; if (looksWrapped) { throw new Error('verify-built-workflow: inputData for a Form Trigger must be a flat field map ' + '(e.g. {name: "Alice", email: "a@b.c"}), NOT wrapped in `formFields`. ' + 'The production Form Trigger emits fields directly on $json, so downstream ' + 'expressions like $json.name are correct. Re-run with the flat shape.'); } } function toWorkflowJsonValue(value) { if (value === null || value === undefined) return value; switch (typeof value) { case 'string': case 'number': case 'boolean': case 'object': return value; default: return String(value); } } function getPinDataForTrigger(node, inputData) { validateInputDataShape(node, inputData); switch (node.type) { case n8n_workflow_1.CHAT_TRIGGER_NODE_TYPE: return { [node.name]: [ { json: { sessionId: `instance-ai-${Date.now()}`, action: 'sendMessage', chatInput: typeof inputData.chatInput === 'string' ? inputData.chatInput : JSON.stringify(inputData), }, }, ], }; case n8n_workflow_1.FORM_TRIGGER_NODE_TYPE: return { [node.name]: [ { json: { submittedAt: new Date().toISOString(), formMode: 'instanceAi', ...inputData, }, }, ], }; case n8n_workflow_1.WEBHOOK_NODE_TYPE: { const envelopeKeys = new Set(['body', 'headers', 'query', 'params']); const inputKeys = Object.keys(inputData); const looksLikeEnvelope = inputKeys.length > 0 && inputKeys.every((key) => envelopeKeys.has(key)); const body = looksLikeEnvelope ? Object.hasOwn(inputData, 'body') ? toWorkflowJsonValue(inputData.body) : {} : inputData; const headers = looksLikeEnvelope && typeof inputData.headers === 'object' && inputData.headers !== null ? inputData.headers : {}; const query = looksLikeEnvelope && typeof inputData.query === 'object' && inputData.query !== null ? inputData.query : {}; const params = looksLikeEnvelope && typeof inputData.params === 'object' && inputData.params !== null ? inputData.params : {}; return { [node.name]: [ { json: { headers, query, params, body }, }, ], }; } case n8n_workflow_1.SCHEDULE_TRIGGER_NODE_TYPE: { const now = new Date(); return { [node.name]: [ { json: { timestamp: now.toISOString(), 'Readable date': now.toLocaleString(), 'Day of week': now.toLocaleDateString('en-US', { weekday: 'long' }), Year: String(now.getFullYear()), Month: now.toLocaleDateString('en-US', { month: 'long' }), 'Day of month': String(now.getDate()).padStart(2, '0'), Hour: String(now.getHours()).padStart(2, '0'), Minute: String(now.getMinutes()).padStart(2, '0'), Second: String(now.getSeconds()).padStart(2, '0'), }, }, ], }; } default: return { [node.name]: [{ json: inputData }], }; } } //# sourceMappingURL=instance-ai-run-pin-data.js.map