UNPKG

n8n

Version:

n8n Workflow Automation Tool

256 lines 8.99 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TaskManager = void 0; const n8n_workflow_1 = require("n8n-workflow"); const nanoid_1 = require("nanoid"); const runner_types_1 = require("../runner-types"); const workflowToParameters = (workflow) => { return { id: workflow.id, name: workflow.name, active: workflow.active, connections: workflow.connectionsBySourceNode, nodes: Object.values(workflow.nodes), pinData: workflow.pinData, settings: workflow.settings, staticData: workflow.staticData, }; }; class TaskManager { constructor() { this.requestAcceptRejects = new Map(); this.taskAcceptRejects = new Map(); this.pendingRequests = new Map(); this.tasks = new Map(); } async startTask(additionalData, taskType, settings, executeFunctions, inputData, node, workflow, runExecutionData, runIndex, itemIndex, activeNodeName, connectionInputData, siblingParameters, mode, envProviderState, executeData, defaultReturnRunIndex = -1, selfData = {}, contextNodeName = activeNodeName) { const data = { workflow, runExecutionData, runIndex, connectionInputData, inputData, node, executeFunctions, itemIndex, siblingParameters, mode, envProviderState, executeData, defaultReturnRunIndex, selfData, contextNodeName, activeNodeName, additionalData, }; const request = { requestId: (0, nanoid_1.nanoid)(), taskType, settings, data, }; this.pendingRequests.set(request.requestId, request); const taskIdPromise = new Promise((resolve, reject) => { this.requestAcceptRejects.set(request.requestId, { accept: resolve, reject, }); }); this.sendMessage({ type: 'requester:taskrequest', requestId: request.requestId, taskType, }); const taskId = await taskIdPromise; const task = { taskId, data, settings, }; this.tasks.set(task.taskId, task); try { const dataPromise = new Promise((resolve, reject) => { this.taskAcceptRejects.set(task.taskId, { accept: resolve, reject, }); }); this.sendMessage({ type: 'requester:tasksettings', taskId, settings, }); const resultData = await dataPromise; if (resultData.customData) { Object.entries(resultData.customData).forEach(([k, v]) => { if (!runExecutionData.resultData.metadata) { runExecutionData.resultData.metadata = {}; } runExecutionData.resultData.metadata[k] = v; }); } return (0, n8n_workflow_1.createResultOk)(resultData.result); } catch (e) { return (0, n8n_workflow_1.createResultError)(e); } finally { this.tasks.delete(taskId); } } sendMessage(_message) { } onMessage(message) { switch (message.type) { case 'broker:taskready': this.taskReady(message.requestId, message.taskId); break; case 'broker:taskdone': this.taskDone(message.taskId, message.data); break; case 'broker:taskerror': this.taskError(message.taskId, message.error); break; case 'broker:taskdatarequest': this.sendTaskData(message.taskId, message.requestId, message.requestType); break; case 'broker:rpc': void this.handleRpc(message.taskId, message.callId, message.name, message.params); break; } } taskReady(requestId, taskId) { const acceptReject = this.requestAcceptRejects.get(requestId); if (!acceptReject) { this.rejectTask(taskId, 'Request ID not found. In multi-main setup, it is possible for one of the mains to have reported ready state already.'); return; } acceptReject.accept(taskId); this.requestAcceptRejects.delete(requestId); } rejectTask(jobId, reason) { this.sendMessage({ type: 'requester:taskcancel', taskId: jobId, reason, }); } taskDone(taskId, data) { const acceptReject = this.taskAcceptRejects.get(taskId); if (acceptReject) { acceptReject.accept(data); this.taskAcceptRejects.delete(taskId); } } taskError(taskId, error) { const acceptReject = this.taskAcceptRejects.get(taskId); if (acceptReject) { acceptReject.reject(error); this.taskAcceptRejects.delete(taskId); } } sendTaskData(taskId, requestId, requestType) { const job = this.tasks.get(taskId); if (!job) { return; } if (requestType === 'all') { const jd = job.data; const ad = jd.additionalData; const data = { workflow: workflowToParameters(jd.workflow), connectionInputData: jd.connectionInputData, inputData: jd.inputData, itemIndex: jd.itemIndex, activeNodeName: jd.activeNodeName, contextNodeName: jd.contextNodeName, defaultReturnRunIndex: jd.defaultReturnRunIndex, mode: jd.mode, envProviderState: jd.envProviderState, node: jd.node, runExecutionData: jd.runExecutionData, runIndex: jd.runIndex, selfData: jd.selfData, siblingParameters: jd.siblingParameters, executeData: jd.executeData, additionalData: { formWaitingBaseUrl: ad.formWaitingBaseUrl, instanceBaseUrl: ad.instanceBaseUrl, restApiUrl: ad.restApiUrl, variables: ad.variables, webhookBaseUrl: ad.webhookBaseUrl, webhookTestBaseUrl: ad.webhookTestBaseUrl, webhookWaitingBaseUrl: ad.webhookWaitingBaseUrl, currentNodeParameters: ad.currentNodeParameters, executionId: ad.executionId, executionTimeoutTimestamp: ad.executionTimeoutTimestamp, restartExecutionId: ad.restartExecutionId, userId: ad.userId, }, }; this.sendMessage({ type: 'requester:taskdataresponse', taskId, requestId, data, }); } } async handleRpc(taskId, callId, name, params) { const job = this.tasks.get(taskId); if (!job) { return; } try { if (!runner_types_1.RPC_ALLOW_LIST.includes(name)) { this.sendMessage({ type: 'requester:rpcresponse', taskId, callId, status: 'error', data: 'Method not allowed', }); return; } const splitPath = name.split('.'); const funcs = job.data.executeFunctions; let func = undefined; let funcObj = funcs; for (const part of splitPath) { funcObj = funcObj[part] ?? undefined; if (!funcObj) { break; } } func = funcObj; if (!func) { this.sendMessage({ type: 'requester:rpcresponse', taskId, callId, status: 'error', data: 'Could not find method', }); return; } const data = (await func.call(funcs, ...params)); this.sendMessage({ type: 'requester:rpcresponse', taskId, callId, status: 'success', data, }); } catch (e) { this.sendMessage({ type: 'requester:rpcresponse', taskId, callId, status: 'error', data: e, }); } } } exports.TaskManager = TaskManager; //# sourceMappingURL=task-manager.js.map