n8n-nodes-base
Version:
Base nodes of n8n
93 lines • 4.25 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PythonTaskRunnerSandbox = void 0;
const n8n_workflow_1 = require("n8n-workflow");
const result_validation_1 = require("./result-validation");
const throw_execution_error_1 = require("./throw-execution-error");
const PYTHON_TEXT_KEYS = {
object: { singular: 'dictionary', plural: 'dictionaries' },
};
class PythonTaskRunnerSandbox {
pythonCode;
nodeMode;
workflowMode;
executeFunctions;
additionalProperties;
constructor(pythonCode, nodeMode, workflowMode, executeFunctions, additionalProperties = {}) {
this.pythonCode = pythonCode;
this.nodeMode = nodeMode;
this.workflowMode = workflowMode;
this.executeFunctions = executeFunctions;
this.additionalProperties = additionalProperties;
}
validateCode() {
if (typeof this.pythonCode !== 'string') {
throw new n8n_workflow_1.NodeOperationError(this.executeFunctions.getNode(), 'No Python code found to execute. Please add code to the Code node.');
}
}
/**
* Run a script by forwarding it to a Python task runner, together with input items.
*
* The Python runner receives input items together with the task, whereas the
* JavaScript runner does _not_ receive input items together with the task and
* instead retrieves them later, only if needed, via an RPC request.
*/
async runUsingIncomingItems() {
this.validateCode();
const itemIndex = 0;
const node = this.executeFunctions.getNode();
const workflow = this.executeFunctions.getWorkflow();
const taskSettings = {
code: this.pythonCode,
nodeMode: this.nodeMode,
workflowMode: this.workflowMode,
continueOnFail: this.executeFunctions.continueOnFail(),
items: this.executeFunctions.getInputData(),
nodeId: node.id,
nodeName: node.name,
workflowId: workflow.id,
workflowName: workflow.name,
};
const executionResult = await this.executeFunctions.startJob('python', taskSettings, itemIndex);
if (!executionResult.ok) {
return (0, throw_execution_error_1.throwExecutionError)('error' in executionResult ? executionResult.error : {});
}
if (this.nodeMode === 'runOnceForAllItems') {
return (0, result_validation_1.validateRunCodeAllItems)(executionResult.result, PYTHON_TEXT_KEYS, this.executeFunctions.helpers.normalizeItems.bind(this.executeFunctions.helpers));
}
return executionResult.result.map((item, index) => (0, result_validation_1.validateRunCodeEachItem)(item, index, PYTHON_TEXT_KEYS, this.executeFunctions.helpers.normalizeItems.bind(this.executeFunctions.helpers)));
}
/**
* Run a script for tool execution.
*
* Unlike `runUsingIncomingItems`, this method:
* - Sends empty items (tools don't process workflow items)
* - Passes `query` from `additionalProperties` to the runner
* - Does not validate the result from the runner (tools can return any type)
*/
async runCodeForTool() {
this.validateCode();
const itemIndex = 0;
const node = this.executeFunctions.getNode();
const workflow = this.executeFunctions.getWorkflow();
const taskSettings = {
code: this.pythonCode,
nodeMode: 'runOnceForAllItems',
workflowMode: this.workflowMode,
continueOnFail: this.executeFunctions.continueOnFail(),
items: [],
nodeId: node.id,
nodeName: node.name,
workflowId: workflow.id,
workflowName: workflow.name,
query: this.additionalProperties.query,
};
const executionResult = await this.executeFunctions.startJob('python', taskSettings, itemIndex);
if (!executionResult.ok) {
return (0, throw_execution_error_1.throwExecutionError)('error' in executionResult ? executionResult.error : {});
}
return executionResult.result;
}
}
exports.PythonTaskRunnerSandbox = PythonTaskRunnerSandbox;
//# sourceMappingURL=PythonTaskRunnerSandbox.js.map