mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-21 20:00:02 +00:00
refactor(core): Refactor execution contexts to reduce code duplication, and improve type-safety (no-changelog) (#12138)
This commit is contained in:
committed by
GitHub
parent
e6985f79db
commit
ec54333f78
@@ -1,19 +1,21 @@
|
||||
import get from 'lodash/get';
|
||||
import type {
|
||||
CloseFunction,
|
||||
ExecutionBaseError,
|
||||
IExecuteData,
|
||||
IGetNodeParameterOptions,
|
||||
INode,
|
||||
INodeExecutionData,
|
||||
IRunExecutionData,
|
||||
ISupplyDataFunctions,
|
||||
ITaskData,
|
||||
ITaskDataConnections,
|
||||
ITaskMetadata,
|
||||
IWorkflowExecuteAdditionalData,
|
||||
NodeConnectionType,
|
||||
Workflow,
|
||||
WorkflowExecuteMode,
|
||||
} from 'n8n-workflow';
|
||||
import { ApplicationError, createDeferredPromise } from 'n8n-workflow';
|
||||
import { ApplicationError, NodeConnectionType, createDeferredPromise } from 'n8n-workflow';
|
||||
|
||||
// eslint-disable-next-line import/no-cycle
|
||||
import {
|
||||
@@ -29,7 +31,6 @@ import {
|
||||
normalizeItems,
|
||||
returnJsonArray,
|
||||
getInputConnectionData,
|
||||
addExecutionDataFunctions,
|
||||
} from '@/NodeExecuteFunctions';
|
||||
|
||||
import { BaseExecuteContext } from './base-execute-context';
|
||||
@@ -104,7 +105,10 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
)) as ISupplyDataFunctions['getNodeParameter'];
|
||||
}
|
||||
|
||||
async getInputConnectionData(inputName: NodeConnectionType, itemIndex: number): Promise<unknown> {
|
||||
async getInputConnectionData(
|
||||
connectionType: NodeConnectionType,
|
||||
itemIndex: number,
|
||||
): Promise<unknown> {
|
||||
return await getInputConnectionData.call(
|
||||
this,
|
||||
this.workflow,
|
||||
@@ -116,34 +120,21 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
this.executeData,
|
||||
this.mode,
|
||||
this.closeFunctions,
|
||||
inputName,
|
||||
connectionType,
|
||||
itemIndex,
|
||||
this.abortSignal,
|
||||
);
|
||||
}
|
||||
|
||||
getInputData(inputIndex = 0, inputName = 'main') {
|
||||
if (!this.inputData.hasOwnProperty(inputName)) {
|
||||
getInputData(inputIndex = 0, connectionType = NodeConnectionType.Main) {
|
||||
if (!this.inputData.hasOwnProperty(connectionType)) {
|
||||
// Return empty array because else it would throw error when nothing is connected to input
|
||||
return [];
|
||||
}
|
||||
|
||||
// TODO: Check if nodeType has input with that index defined
|
||||
if (this.inputData[inputName].length < inputIndex) {
|
||||
throw new ApplicationError('Could not get input with given index', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
if (this.inputData[inputName][inputIndex] === null) {
|
||||
throw new ApplicationError('Value of input was not set', {
|
||||
extra: { inputIndex, inputName },
|
||||
});
|
||||
}
|
||||
|
||||
return this.inputData[inputName][inputIndex];
|
||||
return super.getInputItems(inputIndex, connectionType) ?? [];
|
||||
}
|
||||
|
||||
/** @deprecated create a context object with inputData for every runIndex */
|
||||
addInputData(
|
||||
connectionType: NodeConnectionType,
|
||||
data: INodeExecutionData[][],
|
||||
@@ -154,15 +145,11 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
currentNodeRunIndex = this.runExecutionData.resultData.runData[nodeName].length;
|
||||
}
|
||||
|
||||
addExecutionDataFunctions(
|
||||
this.addExecutionDataFunctions(
|
||||
'input',
|
||||
nodeName,
|
||||
data,
|
||||
this.runExecutionData,
|
||||
connectionType,
|
||||
this.additionalData,
|
||||
nodeName,
|
||||
this.runIndex,
|
||||
currentNodeRunIndex,
|
||||
).catch((error) => {
|
||||
this.logger.warn(
|
||||
@@ -176,6 +163,7 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
return { index: currentNodeRunIndex };
|
||||
}
|
||||
|
||||
/** @deprecated Switch to WorkflowExecute to store output on runExecutionData.resultData.runData */
|
||||
addOutputData(
|
||||
connectionType: NodeConnectionType,
|
||||
currentNodeRunIndex: number,
|
||||
@@ -183,15 +171,11 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
metadata?: ITaskMetadata,
|
||||
): void {
|
||||
const nodeName = this.node.name;
|
||||
addExecutionDataFunctions(
|
||||
this.addExecutionDataFunctions(
|
||||
'output',
|
||||
nodeName,
|
||||
data,
|
||||
this.runExecutionData,
|
||||
connectionType,
|
||||
this.additionalData,
|
||||
nodeName,
|
||||
this.runIndex,
|
||||
currentNodeRunIndex,
|
||||
metadata,
|
||||
).catch((error) => {
|
||||
@@ -203,4 +187,115 @@ export class SupplyDataContext extends BaseExecuteContext implements ISupplyData
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
async addExecutionDataFunctions(
|
||||
type: 'input' | 'output',
|
||||
data: INodeExecutionData[][] | ExecutionBaseError,
|
||||
connectionType: NodeConnectionType,
|
||||
sourceNodeName: string,
|
||||
currentNodeRunIndex: number,
|
||||
metadata?: ITaskMetadata,
|
||||
): Promise<void> {
|
||||
if (connectionType === NodeConnectionType.Main) {
|
||||
throw new ApplicationError('Setting type is not supported for main connection', {
|
||||
extra: { type },
|
||||
});
|
||||
}
|
||||
|
||||
const {
|
||||
additionalData,
|
||||
runExecutionData,
|
||||
runIndex: sourceNodeRunIndex,
|
||||
node: { name: nodeName },
|
||||
} = this;
|
||||
|
||||
let taskData: ITaskData | undefined;
|
||||
if (type === 'input') {
|
||||
taskData = {
|
||||
startTime: new Date().getTime(),
|
||||
executionTime: 0,
|
||||
executionStatus: 'running',
|
||||
source: [null],
|
||||
};
|
||||
} else {
|
||||
// At the moment we expect that there is always an input sent before the output
|
||||
taskData = get(
|
||||
runExecutionData,
|
||||
['resultData', 'runData', nodeName, currentNodeRunIndex],
|
||||
undefined,
|
||||
);
|
||||
if (taskData === undefined) {
|
||||
return;
|
||||
}
|
||||
taskData.metadata = metadata;
|
||||
}
|
||||
taskData = taskData!;
|
||||
|
||||
if (data instanceof Error) {
|
||||
taskData.executionStatus = 'error';
|
||||
taskData.error = data;
|
||||
} else {
|
||||
if (type === 'output') {
|
||||
taskData.executionStatus = 'success';
|
||||
}
|
||||
taskData.data = {
|
||||
[connectionType]: data,
|
||||
} as ITaskDataConnections;
|
||||
}
|
||||
|
||||
if (type === 'input') {
|
||||
if (!(data instanceof Error)) {
|
||||
this.inputData[connectionType] = data;
|
||||
// TODO: remove inputOverride
|
||||
taskData.inputOverride = {
|
||||
[connectionType]: data,
|
||||
} as ITaskDataConnections;
|
||||
}
|
||||
|
||||
if (!runExecutionData.resultData.runData.hasOwnProperty(nodeName)) {
|
||||
runExecutionData.resultData.runData[nodeName] = [];
|
||||
}
|
||||
|
||||
runExecutionData.resultData.runData[nodeName][currentNodeRunIndex] = taskData;
|
||||
if (additionalData.sendDataToUI) {
|
||||
additionalData.sendDataToUI('nodeExecuteBefore', {
|
||||
executionId: additionalData.executionId,
|
||||
nodeName,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Outputs
|
||||
taskData.executionTime = new Date().getTime() - taskData.startTime;
|
||||
|
||||
if (additionalData.sendDataToUI) {
|
||||
additionalData.sendDataToUI('nodeExecuteAfter', {
|
||||
executionId: additionalData.executionId,
|
||||
nodeName,
|
||||
data: taskData,
|
||||
});
|
||||
}
|
||||
|
||||
if (get(runExecutionData, 'executionData.metadata', undefined) === undefined) {
|
||||
runExecutionData.executionData!.metadata = {};
|
||||
}
|
||||
|
||||
let sourceTaskData = runExecutionData.executionData?.metadata?.[sourceNodeName];
|
||||
|
||||
if (!sourceTaskData) {
|
||||
runExecutionData.executionData!.metadata[sourceNodeName] = [];
|
||||
sourceTaskData = runExecutionData.executionData!.metadata[sourceNodeName];
|
||||
}
|
||||
|
||||
if (!sourceTaskData[sourceNodeRunIndex]) {
|
||||
sourceTaskData[sourceNodeRunIndex] = {
|
||||
subRun: [],
|
||||
};
|
||||
}
|
||||
|
||||
sourceTaskData[sourceNodeRunIndex].subRun!.push({
|
||||
node: nodeName,
|
||||
runIndex: currentNodeRunIndex,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user