mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 10:02:05 +00:00
feat: Improvements to pairedItem
This commit is contained in:
@@ -10,6 +10,7 @@ export class ExpressionError extends ExecutionBaseError {
|
||||
options?: {
|
||||
causeDetailed?: string;
|
||||
description?: string;
|
||||
descriptionTemplate?: string;
|
||||
runIndex?: number;
|
||||
itemIndex?: number;
|
||||
messageTemplate?: string;
|
||||
@@ -23,6 +24,10 @@ export class ExpressionError extends ExecutionBaseError {
|
||||
this.description = options.description;
|
||||
}
|
||||
|
||||
if (options?.descriptionTemplate !== undefined) {
|
||||
this.context.descriptionTemplate = options.descriptionTemplate;
|
||||
}
|
||||
|
||||
if (options?.causeDetailed !== undefined) {
|
||||
this.context.causeDetailed = options.causeDetailed;
|
||||
}
|
||||
|
||||
@@ -839,10 +839,9 @@ export interface INode {
|
||||
parameters: INodeParameters;
|
||||
credentials?: INodeCredentials;
|
||||
webhookId?: string;
|
||||
pinData?: IDataObject;
|
||||
}
|
||||
|
||||
export interface PinData {
|
||||
export interface IPinData {
|
||||
[nodeName: string]: IDataObject[];
|
||||
}
|
||||
|
||||
@@ -1328,7 +1327,7 @@ export interface IRunExecutionData {
|
||||
resultData: {
|
||||
error?: ExecutionError;
|
||||
runData: IRunData;
|
||||
pinData?: PinData;
|
||||
pinData?: IPinData;
|
||||
lastNodeExecuted?: string;
|
||||
};
|
||||
executionData?: {
|
||||
@@ -1402,7 +1401,7 @@ export interface IWorkflowBase {
|
||||
connections: IConnections;
|
||||
settings?: IWorkflowSettings;
|
||||
staticData?: IDataObject;
|
||||
pinData?: PinData;
|
||||
pinData?: IPinData;
|
||||
}
|
||||
|
||||
export interface IWorkflowCredentials {
|
||||
|
||||
@@ -28,6 +28,7 @@ import {
|
||||
INodes,
|
||||
INodeType,
|
||||
INodeTypes,
|
||||
IPinData,
|
||||
IPollFunctions,
|
||||
IRunExecutionData,
|
||||
ITaskDataConnections,
|
||||
@@ -84,6 +85,8 @@ export class Workflow {
|
||||
// ids of registred webhooks of nodes
|
||||
staticData: IDataObject;
|
||||
|
||||
pinData?: IPinData;
|
||||
|
||||
// constructor(id: string | undefined, nodes: INode[], connections: IConnections, active: boolean, nodeTypes: INodeTypes, staticData?: IDataObject, settings?: IWorkflowSettings) {
|
||||
constructor(parameters: {
|
||||
id?: string;
|
||||
@@ -94,10 +97,12 @@ export class Workflow {
|
||||
nodeTypes: INodeTypes;
|
||||
staticData?: IDataObject;
|
||||
settings?: IWorkflowSettings;
|
||||
pinData?: IPinData;
|
||||
}) {
|
||||
this.id = parameters.id;
|
||||
this.name = parameters.name;
|
||||
this.nodeTypes = parameters.nodeTypes;
|
||||
this.pinData = parameters.pinData;
|
||||
|
||||
// Save nodes in workflow as object to be able to get the
|
||||
// nodes easily by its name.
|
||||
@@ -410,6 +415,17 @@ export class Workflow {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the pinData of the node with the given name if it exists
|
||||
*
|
||||
* @param {string} nodeName Name of the node to return the pinData of
|
||||
* @returns {(IDataObject[] | undefined)}
|
||||
* @memberof Workflow
|
||||
*/
|
||||
getPinDataOfNode(nodeName: string): IDataObject[] | undefined {
|
||||
return this.pinData ? this.pinData[nodeName] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renames nodes in expressions
|
||||
*
|
||||
|
||||
@@ -532,11 +532,27 @@ export class WorkflowDataProxy {
|
||||
const createExpressionError = (
|
||||
message: string,
|
||||
context?: {
|
||||
messageTemplate?: string;
|
||||
description?: string;
|
||||
causeDetailed?: string;
|
||||
description?: string;
|
||||
descriptionTemplate?: string;
|
||||
messageTemplate?: string;
|
||||
},
|
||||
nodeName?: string,
|
||||
) => {
|
||||
if (nodeName) {
|
||||
const pinData = this.workflow.getPinDataOfNode(nodeName);
|
||||
|
||||
if (pinData) {
|
||||
if (!context) {
|
||||
context = {};
|
||||
}
|
||||
message = `‘${nodeName}‘ must be unpinned to execute`;
|
||||
context.description = `To fetch the data the expression needs, The node ‘${nodeName}’ needs to execute without being pinned. <a>Unpin it</a>`;
|
||||
context.description = `To fetch the data for the expression, you must unpin the node '${nodeName}' and execute the workflow again.`;
|
||||
context.descriptionTemplate = `To fetch the data for the expression under '%%PARAMETER%%', you must unpin the node '${nodeName}' and execute the workflow again.`;
|
||||
}
|
||||
}
|
||||
|
||||
return new ExpressionError(message, {
|
||||
runIndex: that.runIndex,
|
||||
itemIndex: that.itemIndex,
|
||||
@@ -560,6 +576,7 @@ export class WorkflowDataProxy {
|
||||
};
|
||||
}
|
||||
|
||||
let nodeBeforeLast: string | undefined;
|
||||
while (sourceData !== null && destinationNodeName !== sourceData.previousNode) {
|
||||
taskData =
|
||||
that.runExecutionData!.resultData.runData[sourceData.previousNode][
|
||||
@@ -569,20 +586,29 @@ export class WorkflowDataProxy {
|
||||
const previousNodeOutput = sourceData.previousNodeOutput || 0;
|
||||
if (previousNodeOutput >= taskData.data!.main.length) {
|
||||
// `Could not resolve as the defined node-output is not valid on node '${sourceData.previousNode}'.`
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’',
|
||||
description: `Apologies, this is an internal error. See details for more information`,
|
||||
causeDetailed: 'Referencing a non-existent output on a node, problem with source data',
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: 'Can’t get data for expression under ‘%%PARAMETER%%’',
|
||||
description: `Apologies, this is an internal error. See details for more information`,
|
||||
causeDetailed:
|
||||
'Referencing a non-existent output on a node, problem with source data',
|
||||
},
|
||||
nodeBeforeLast,
|
||||
);
|
||||
}
|
||||
|
||||
if (pairedItem.item >= taskData.data!.main[previousNodeOutput]!.length) {
|
||||
// `Could not resolve as the defined item index is not valid on node '${sourceData.previousNode}'.
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to an item which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to an item ‘${pairedItem.item}‘ which does not exist on node ‘${sourceData.previousNode}‘ (output node did probably supply a wrong one)`,
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to an item which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to an item ‘${pairedItem.item}‘ which does not exist on node ‘${sourceData.previousNode}‘ (output node did probably supply a wrong one)`,
|
||||
},
|
||||
nodeBeforeLast,
|
||||
);
|
||||
}
|
||||
|
||||
const itemPreviousNode: INodeExecutionData =
|
||||
@@ -590,11 +616,15 @@ export class WorkflowDataProxy {
|
||||
|
||||
if (itemPreviousNode.pairedItem === undefined) {
|
||||
// `Could not resolve, as pairedItem data is missing on node '${sourceData.previousNode}'.`,
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `To fetch the data from other nodes that this expression needs, more information is needed from the node ‘${sourceData.previousNode}’`,
|
||||
causeDetailed: `Missing pairedItem data (node ‘${sourceData.previousNode}’ did probably not supply it)`,
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `To fetch the data from other nodes that this expression needs, more information is needed from the node ‘${sourceData.previousNode}’`,
|
||||
causeDetailed: `Missing pairedItem data (node ‘${sourceData.previousNode}’ did probably not supply it)`,
|
||||
},
|
||||
sourceData.previousNode,
|
||||
);
|
||||
}
|
||||
|
||||
if (Array.isArray(itemPreviousNode.pairedItem)) {
|
||||
@@ -647,22 +677,31 @@ export class WorkflowDataProxy {
|
||||
});
|
||||
}
|
||||
// `Could not resolve pairedItem as the defined node input '${itemInput}' does not exist on node '${sourceData.previousNode}'.`
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to a node input which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to a node input ‘${itemInput}‘ which does not exist on node ‘${sourceData.previousNode}‘ (node did probably supply a wrong one)`,
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to a node input which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to a node input ‘${itemInput}‘ which does not exist on node ‘${sourceData.previousNode}‘ (node did probably supply a wrong one)`,
|
||||
},
|
||||
nodeBeforeLast,
|
||||
);
|
||||
}
|
||||
|
||||
nodeBeforeLast = sourceData.previousNode;
|
||||
sourceData = taskData.source[pairedItem.input || 0] || null;
|
||||
}
|
||||
|
||||
if (sourceData === null) {
|
||||
// 'Could not resolve, proably no pairedItem exists.'
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Could not resolve, proably no pairedItem exists`,
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Could not resolve, proably no pairedItem exists`,
|
||||
},
|
||||
nodeBeforeLast,
|
||||
);
|
||||
}
|
||||
|
||||
taskData =
|
||||
@@ -682,11 +721,15 @@ export class WorkflowDataProxy {
|
||||
|
||||
if (pairedItem.item >= taskData.data!.main[previousNodeOutput]!.length) {
|
||||
// `Could not resolve pairedItem as the item with the index '${pairedItem.item}' does not exist on node '${sourceData.previousNode}'.`
|
||||
throw createExpressionError('Can’t get data for expression', {
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to an item which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to an item ‘${pairedItem.item}‘ which does not exist on node ‘${sourceData.previousNode}‘ (output node did probably supply a wrong one)`,
|
||||
});
|
||||
throw createExpressionError(
|
||||
'Can’t get data for expression',
|
||||
{
|
||||
messageTemplate: `Can’t get data for expression under ‘%%PARAMETER%%’`,
|
||||
description: `Item points to an item which does not exist`,
|
||||
causeDetailed: `The pairedItem data points to an item ‘${pairedItem.item}‘ which does not exist on node ‘${sourceData.previousNode}‘ (output node did probably supply a wrong one)`,
|
||||
},
|
||||
nodeBeforeLast,
|
||||
);
|
||||
}
|
||||
|
||||
return taskData.data!.main[previousNodeOutput]![pairedItem.item];
|
||||
|
||||
Reference in New Issue
Block a user