n8n-core 1.72.1 → 1.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/LICENSE.md +5 -3
  2. package/dist/ActiveWorkflows.d.ts +9 -3
  3. package/dist/ActiveWorkflows.js +25 -14
  4. package/dist/ActiveWorkflows.js.map +1 -1
  5. package/dist/BinaryData/BinaryData.service.js +3 -3
  6. package/dist/BinaryData/BinaryData.service.js.map +1 -1
  7. package/dist/BinaryData/ObjectStore.manager.js +2 -2
  8. package/dist/BinaryData/ObjectStore.manager.js.map +1 -1
  9. package/dist/Cipher.js +2 -2
  10. package/dist/Cipher.js.map +1 -1
  11. package/dist/Constants.d.ts +5 -0
  12. package/dist/Constants.js +29 -1
  13. package/dist/Constants.js.map +1 -1
  14. package/dist/CreateNodeAsTool.d.ts +2 -2
  15. package/dist/CreateNodeAsTool.js +30 -44
  16. package/dist/CreateNodeAsTool.js.map +1 -1
  17. package/dist/Credentials.js +2 -2
  18. package/dist/Credentials.js.map +1 -1
  19. package/dist/DirectoryLoader.d.ts +3 -0
  20. package/dist/DirectoryLoader.js +26 -6
  21. package/dist/DirectoryLoader.js.map +1 -1
  22. package/dist/InstanceSettings.d.ts +11 -3
  23. package/dist/InstanceSettings.js +53 -24
  24. package/dist/InstanceSettings.js.map +1 -1
  25. package/dist/InstanceSettingsConfig.d.ts +3 -0
  26. package/dist/InstanceSettingsConfig.js +9 -1
  27. package/dist/InstanceSettingsConfig.js.map +1 -1
  28. package/dist/NodeExecuteFunctions.d.ts +2 -7
  29. package/dist/NodeExecuteFunctions.js +27 -125
  30. package/dist/NodeExecuteFunctions.js.map +1 -1
  31. package/dist/ObjectStore/ObjectStore.service.ee.d.ts +3 -1
  32. package/dist/ObjectStore/ObjectStore.service.ee.js +9 -4
  33. package/dist/ObjectStore/ObjectStore.service.ee.js.map +1 -1
  34. package/dist/RoutingNode.d.ts +18 -0
  35. package/dist/RoutingNode.js +560 -0
  36. package/dist/RoutingNode.js.map +1 -0
  37. package/dist/SSHClientsManager.js +2 -2
  38. package/dist/SSHClientsManager.js.map +1 -1
  39. package/dist/ScheduledTaskManager.js +2 -2
  40. package/dist/ScheduledTaskManager.js.map +1 -1
  41. package/dist/SerializedBuffer.d.ts +6 -0
  42. package/dist/SerializedBuffer.js +16 -0
  43. package/dist/SerializedBuffer.js.map +1 -0
  44. package/dist/TriggersAndPollers.d.ts +5 -0
  45. package/dist/TriggersAndPollers.js +70 -0
  46. package/dist/TriggersAndPollers.js.map +1 -0
  47. package/dist/WorkflowExecute.d.ts +9 -1
  48. package/dist/WorkflowExecute.js +267 -117
  49. package/dist/WorkflowExecute.js.map +1 -1
  50. package/dist/build.tsbuildinfo +1 -1
  51. package/dist/decorators/index.d.ts +1 -0
  52. package/dist/decorators/index.js +6 -0
  53. package/dist/decorators/index.js.map +1 -0
  54. package/dist/decorators/memoized.d.ts +1 -0
  55. package/dist/decorators/memoized.js +23 -0
  56. package/dist/decorators/memoized.js.map +1 -0
  57. package/dist/error-reporter.d.ts +18 -0
  58. package/dist/error-reporter.js +184 -0
  59. package/dist/error-reporter.js.map +1 -0
  60. package/dist/index.d.ts +6 -0
  61. package/dist/index.js +10 -1
  62. package/dist/index.js.map +1 -1
  63. package/dist/logging/logger.d.ts +34 -0
  64. package/dist/logging/logger.js +210 -0
  65. package/dist/logging/logger.js.map +1 -0
  66. package/dist/node-execution-context/base-execute-context.d.ts +1 -3
  67. package/dist/node-execution-context/base-execute-context.js +2 -10
  68. package/dist/node-execution-context/base-execute-context.js.map +1 -1
  69. package/dist/node-execution-context/execute-context.d.ts +2 -2
  70. package/dist/node-execution-context/execute-context.js +4 -2
  71. package/dist/node-execution-context/execute-context.js.map +1 -1
  72. package/dist/node-execution-context/execute-single-context.js +1 -0
  73. package/dist/node-execution-context/execute-single-context.js.map +1 -1
  74. package/dist/node-execution-context/index.d.ts +2 -1
  75. package/dist/node-execution-context/index.js +5 -3
  76. package/dist/node-execution-context/index.js.map +1 -1
  77. package/dist/node-execution-context/local-load-options-context.d.ts +10 -0
  78. package/dist/node-execution-context/local-load-options-context.js +49 -0
  79. package/dist/node-execution-context/local-load-options-context.js.map +1 -0
  80. package/dist/node-execution-context/node-execution-context.d.ts +10 -4
  81. package/dist/node-execution-context/node-execution-context.js +70 -8
  82. package/dist/node-execution-context/node-execution-context.js.map +1 -1
  83. package/dist/node-execution-context/supply-data-context.d.ts +5 -6
  84. package/dist/node-execution-context/supply-data-context.js +9 -19
  85. package/dist/node-execution-context/supply-data-context.js.map +1 -1
  86. package/dist/node-execution-context/utils/cleanupParameterData.d.ts +2 -0
  87. package/dist/node-execution-context/utils/cleanupParameterData.js +27 -0
  88. package/dist/node-execution-context/utils/cleanupParameterData.js.map +1 -0
  89. package/dist/node-execution-context/utils/ensureType.d.ts +6 -0
  90. package/dist/node-execution-context/utils/ensureType.js +75 -0
  91. package/dist/node-execution-context/utils/ensureType.js.map +1 -0
  92. package/dist/node-execution-context/utils/getAdditionalKeys.d.ts +4 -0
  93. package/dist/node-execution-context/utils/getAdditionalKeys.js +57 -0
  94. package/dist/node-execution-context/utils/getAdditionalKeys.js.map +1 -0
  95. package/dist/node-execution-context/utils/getInputConnectionData.d.ts +4 -0
  96. package/dist/node-execution-context/utils/getInputConnectionData.js +99 -0
  97. package/dist/node-execution-context/utils/getInputConnectionData.js.map +1 -0
  98. package/dist/node-execution-context/utils/validateValueAgainstSchema.d.ts +2 -0
  99. package/dist/node-execution-context/utils/validateValueAgainstSchema.js +129 -0
  100. package/dist/node-execution-context/utils/validateValueAgainstSchema.js.map +1 -0
  101. package/dist/node-execution-context/webhook-context.d.ts +2 -2
  102. package/dist/node-execution-context/webhook-context.js +2 -1
  103. package/dist/node-execution-context/webhook-context.js.map +1 -1
  104. package/dist/node-execution-context/workflow-node-context.d.ts +6 -0
  105. package/dist/node-execution-context/workflow-node-context.js +14 -0
  106. package/dist/node-execution-context/workflow-node-context.js.map +1 -0
  107. package/dist/utils.d.ts +5 -0
  108. package/dist/utils.js +10 -0
  109. package/dist/utils.js.map +1 -0
  110. package/package.json +13 -8
  111. package/dist/node-execution-context/utils.d.ts +0 -11
  112. package/dist/node-execution-context/utils.js +0 -275
  113. package/dist/node-execution-context/utils.js.map +0 -1
@@ -37,14 +37,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  exports.WorkflowExecute = void 0;
40
+ const di_1 = require("@n8n/di");
40
41
  const assert = __importStar(require("assert/strict"));
41
42
  const events_1 = require("events");
42
43
  const lodash_1 = require("lodash");
43
44
  const get_1 = __importDefault(require("lodash/get"));
44
45
  const n8n_workflow_1 = require("n8n-workflow");
45
46
  const p_cancelable_1 = __importDefault(require("p-cancelable"));
47
+ const error_reporter_1 = require("./error-reporter");
48
+ const node_execution_context_1 = require("./node-execution-context");
46
49
  const NodeExecuteFunctions = __importStar(require("./NodeExecuteFunctions"));
47
50
  const PartialExecutionUtils_1 = require("./PartialExecutionUtils");
51
+ const RoutingNode_1 = require("./RoutingNode");
52
+ const TriggersAndPollers_1 = require("./TriggersAndPollers");
48
53
  class WorkflowExecute {
49
54
  constructor(additionalData, mode, runExecutionData = {
50
55
  startData: {},
@@ -304,18 +309,16 @@ class WorkflowExecute {
304
309
  return true;
305
310
  }
306
311
  prepareWaitingToExecution(nodeName, numberOfConnections, runIndex) {
307
- if (!this.runExecutionData.executionData.waitingExecutionSource) {
308
- this.runExecutionData.executionData.waitingExecutionSource = {};
309
- }
310
- this.runExecutionData.executionData.waitingExecution[nodeName][runIndex] = {
311
- main: [],
312
- };
313
- this.runExecutionData.executionData.waitingExecutionSource[nodeName][runIndex] = {
314
- main: [],
315
- };
312
+ const executionData = this.runExecutionData.executionData;
313
+ executionData.waitingExecution ??= {};
314
+ executionData.waitingExecutionSource ??= {};
315
+ const nodeWaiting = (executionData.waitingExecution[nodeName] ??= []);
316
+ const nodeWaitingSource = (executionData.waitingExecutionSource[nodeName] ??= []);
317
+ nodeWaiting[runIndex] = { main: [] };
318
+ nodeWaitingSource[runIndex] = { main: [] };
316
319
  for (let i = 0; i < numberOfConnections; i++) {
317
- this.runExecutionData.executionData.waitingExecution[nodeName][runIndex].main.push(null);
318
- this.runExecutionData.executionData.waitingExecutionSource[nodeName][runIndex].main.push(null);
320
+ nodeWaiting[runIndex].main.push(null);
321
+ nodeWaitingSource[runIndex].main.push(null);
319
322
  }
320
323
  }
321
324
  addNodeToBeExecuted(workflow, connectionData, outputIndex, parentNodeName, nodeSuccessData, runIndex) {
@@ -536,6 +539,151 @@ class WorkflowExecute {
536
539
  });
537
540
  }
538
541
  }
542
+ checkReadyForExecution(workflow, inputData = {}) {
543
+ const workflowIssues = {};
544
+ let checkNodes = [];
545
+ if (inputData.destinationNode) {
546
+ checkNodes = workflow.getParentNodes(inputData.destinationNode);
547
+ checkNodes.push(inputData.destinationNode);
548
+ }
549
+ else if (inputData.startNode) {
550
+ checkNodes = workflow.getChildNodes(inputData.startNode);
551
+ checkNodes.push(inputData.startNode);
552
+ }
553
+ for (const nodeName of checkNodes) {
554
+ let nodeIssues = null;
555
+ const node = workflow.nodes[nodeName];
556
+ if (node.disabled === true) {
557
+ continue;
558
+ }
559
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
560
+ if (nodeType === undefined) {
561
+ nodeIssues = {
562
+ typeUnknown: true,
563
+ };
564
+ }
565
+ else {
566
+ nodeIssues = n8n_workflow_1.NodeHelpers.getNodeParametersIssues(nodeType.description.properties, node, inputData.pinDataNodeNames);
567
+ }
568
+ if (nodeIssues !== null) {
569
+ workflowIssues[node.name] = nodeIssues;
570
+ }
571
+ }
572
+ if (Object.keys(workflowIssues).length === 0) {
573
+ return null;
574
+ }
575
+ return workflowIssues;
576
+ }
577
+ async runNode(workflow, executionData, runExecutionData, runIndex, additionalData, mode, abortSignal) {
578
+ const { node } = executionData;
579
+ let inputData = executionData.data;
580
+ if (node.disabled === true) {
581
+ if (inputData.hasOwnProperty('main') && inputData.main.length > 0) {
582
+ if (inputData.main[0] === null) {
583
+ return { data: undefined };
584
+ }
585
+ return { data: [inputData.main[0]] };
586
+ }
587
+ return { data: undefined };
588
+ }
589
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(node.type, node.typeVersion);
590
+ let connectionInputData = [];
591
+ if (nodeType.execute || (!nodeType.poll && !nodeType.trigger && !nodeType.webhook)) {
592
+ if (inputData.main?.length > 0) {
593
+ connectionInputData = inputData.main[0];
594
+ }
595
+ const forceInputNodeExecution = workflow.settings.executionOrder !== 'v1';
596
+ if (!forceInputNodeExecution) {
597
+ for (const mainData of inputData.main) {
598
+ if (mainData?.length) {
599
+ connectionInputData = mainData;
600
+ break;
601
+ }
602
+ }
603
+ }
604
+ if (connectionInputData.length === 0) {
605
+ return { data: undefined };
606
+ }
607
+ }
608
+ if (runExecutionData.resultData.lastNodeExecuted === node.name &&
609
+ runExecutionData.resultData.error !== undefined) {
610
+ if (runExecutionData.resultData.error.name === 'NodeOperationError' ||
611
+ runExecutionData.resultData.error.name === 'NodeApiError') {
612
+ throw runExecutionData.resultData.error;
613
+ }
614
+ const error = new Error(runExecutionData.resultData.error.message);
615
+ error.stack = runExecutionData.resultData.error.stack;
616
+ throw error;
617
+ }
618
+ if (node.executeOnce === true) {
619
+ const newInputData = {};
620
+ for (const connectionType of Object.keys(inputData)) {
621
+ newInputData[connectionType] = inputData[connectionType].map((input) => {
622
+ return input && input.slice(0, 1);
623
+ });
624
+ }
625
+ inputData = newInputData;
626
+ }
627
+ if (nodeType.execute) {
628
+ const closeFunctions = [];
629
+ const context = new node_execution_context_1.ExecuteContext(workflow, node, additionalData, mode, runExecutionData, runIndex, connectionInputData, inputData, executionData, closeFunctions, abortSignal);
630
+ const data = nodeType instanceof n8n_workflow_1.Node
631
+ ? await nodeType.execute(context)
632
+ : await nodeType.execute.call(context);
633
+ const closeFunctionsResults = await Promise.allSettled(closeFunctions.map(async (fn) => await fn()));
634
+ const closingErrors = closeFunctionsResults
635
+ .filter((result) => result.status === 'rejected')
636
+ .map((result) => result.reason);
637
+ if (closingErrors.length > 0) {
638
+ if (closingErrors[0] instanceof Error)
639
+ throw closingErrors[0];
640
+ throw new n8n_workflow_1.ApplicationError("Error on execution node's close function(s)", {
641
+ extra: { nodeName: node.name },
642
+ tags: { nodeType: node.type },
643
+ cause: closingErrors,
644
+ });
645
+ }
646
+ return { data };
647
+ }
648
+ else if (nodeType.poll) {
649
+ if (mode === 'manual') {
650
+ const context = new node_execution_context_1.PollContext(workflow, node, additionalData, mode, 'manual');
651
+ return { data: await nodeType.poll.call(context) };
652
+ }
653
+ return { data: inputData.main };
654
+ }
655
+ else if (nodeType.trigger) {
656
+ if (mode === 'manual') {
657
+ const triggerResponse = await di_1.Container.get(TriggersAndPollers_1.TriggersAndPollers).runTrigger(workflow, node, NodeExecuteFunctions.getExecuteTriggerFunctions, additionalData, mode, 'manual');
658
+ if (triggerResponse === undefined) {
659
+ return { data: null };
660
+ }
661
+ let closeFunction;
662
+ if (triggerResponse.closeFunction) {
663
+ closeFunction = triggerResponse.closeFunction;
664
+ abortSignal?.addEventListener('abort', closeFunction);
665
+ }
666
+ if (triggerResponse.manualTriggerFunction !== undefined) {
667
+ await triggerResponse.manualTriggerFunction();
668
+ }
669
+ const response = await triggerResponse.manualTriggerResponse;
670
+ if (response.length === 0) {
671
+ return { data: null, closeFunction };
672
+ }
673
+ return { data: response, closeFunction };
674
+ }
675
+ return { data: inputData.main };
676
+ }
677
+ else if (nodeType.webhook) {
678
+ return { data: inputData.main };
679
+ }
680
+ else {
681
+ const routingNode = new RoutingNode_1.RoutingNode(workflow, node, connectionInputData, runExecutionData ?? null, additionalData, mode);
682
+ return {
683
+ data: await routingNode.runNode(inputData, runIndex, nodeType, executionData, undefined, abortSignal),
684
+ };
685
+ }
686
+ }
539
687
  processRunExecutionData(workflow) {
540
688
  n8n_workflow_1.LoggerProxy.debug('Workflow execution started', { workflowId: workflow.id });
541
689
  const startedAt = new Date();
@@ -547,13 +695,13 @@ class WorkflowExecute {
547
695
  destinationNode = this.runExecutionData.startData.destinationNode;
548
696
  }
549
697
  const pinDataNodeNames = Object.keys(this.runExecutionData.resultData.pinData ?? {});
550
- const workflowIssues = workflow.checkReadyForExecution({
698
+ const workflowIssues = this.checkReadyForExecution(workflow, {
551
699
  startNode,
552
700
  destinationNode,
553
701
  pinDataNodeNames,
554
702
  });
555
703
  if (workflowIssues !== null) {
556
- throw new n8n_workflow_1.WorkflowOperationError('The workflow has issues and can for that reason not be executed. Please fix them first.');
704
+ throw new n8n_workflow_1.WorkflowOperationError('The workflow has issues and cannot be executed for that reason. Please fix them first.');
557
705
  }
558
706
  let executionData;
559
707
  let executionError;
@@ -721,12 +869,12 @@ class WorkflowExecute {
721
869
  node: executionNode.name,
722
870
  workflowId: workflow.id,
723
871
  });
724
- let runNodeData = await workflow.runNode(executionData, this.runExecutionData, runIndex, this.additionalData, NodeExecuteFunctions, this.mode, this.abortController.signal);
872
+ let runNodeData = await this.runNode(workflow, executionData, this.runExecutionData, runIndex, this.additionalData, this.mode, this.abortController.signal);
725
873
  nodeSuccessData = runNodeData.data;
726
874
  const didContinueOnFail = nodeSuccessData?.at(0)?.at(0)?.json?.error !== undefined;
727
875
  while (didContinueOnFail && tryIndex !== maxTries - 1) {
728
876
  await (0, n8n_workflow_1.sleep)(waitBetweenTries);
729
- runNodeData = await workflow.runNode(executionData, this.runExecutionData, runIndex, this.additionalData, NodeExecuteFunctions, this.mode, this.abortController.signal);
877
+ runNodeData = await this.runNode(workflow, executionData, this.runExecutionData, runIndex, this.additionalData, this.mode, this.abortController.signal);
730
878
  tryIndex++;
731
879
  }
732
880
  if (nodeSuccessData instanceof n8n_workflow_1.NodeExecutionOutput) {
@@ -734,71 +882,7 @@ class WorkflowExecute {
734
882
  executionHints.push(...hints);
735
883
  }
736
884
  if (nodeSuccessData && executionData.node.onError === 'continueErrorOutput') {
737
- const nodeType = workflow.nodeTypes.getByNameAndVersion(executionData.node.type, executionData.node.typeVersion);
738
- const outputs = n8n_workflow_1.NodeHelpers.getNodeOutputs(workflow, executionData.node, nodeType.description);
739
- const outputTypes = n8n_workflow_1.NodeHelpers.getConnectionTypes(outputs);
740
- const mainOutputTypes = outputTypes.filter((output) => output === "main");
741
- const errorItems = [];
742
- const closeFunctions = [];
743
- const executeFunctions = NodeExecuteFunctions.getExecuteFunctions(workflow, this.runExecutionData, runIndex, [], executionData.data, executionData.node, this.additionalData, executionData, this.mode, closeFunctions, this.abortController.signal);
744
- const dataProxy = executeFunctions.getWorkflowDataProxy(0);
745
- for (let outputIndex = 0; outputIndex < mainOutputTypes.length - 1; outputIndex++) {
746
- const successItems = [];
747
- const items = nodeSuccessData[outputIndex]?.length
748
- ? nodeSuccessData[outputIndex]
749
- : [];
750
- while (items.length) {
751
- const item = items.shift();
752
- if (item === undefined) {
753
- continue;
754
- }
755
- let errorData;
756
- if (item.error) {
757
- errorData = item.error;
758
- item.error = undefined;
759
- }
760
- else if (item.json.error && Object.keys(item.json).length === 1) {
761
- errorData = item.json.error;
762
- }
763
- else if (item.json.error &&
764
- item.json.message &&
765
- Object.keys(item.json).length === 2) {
766
- errorData = item.json.error;
767
- }
768
- if (errorData) {
769
- const pairedItemData = item.pairedItem && typeof item.pairedItem === 'object'
770
- ? Array.isArray(item.pairedItem)
771
- ? item.pairedItem[0]
772
- : item.pairedItem
773
- : undefined;
774
- if (executionData.source === null || pairedItemData === undefined) {
775
- errorItems.push(item);
776
- }
777
- else {
778
- const pairedItemInputIndex = pairedItemData.input || 0;
779
- const sourceData = executionData.source["main"][pairedItemInputIndex];
780
- const constPairedItem = dataProxy.$getPairedItem(sourceData.previousNode, sourceData, pairedItemData);
781
- if (constPairedItem === null) {
782
- errorItems.push(item);
783
- }
784
- else {
785
- errorItems.push({
786
- ...item,
787
- json: {
788
- ...constPairedItem.json,
789
- ...item.json,
790
- },
791
- });
792
- }
793
- }
794
- }
795
- else {
796
- successItems.push(item);
797
- }
798
- }
799
- nodeSuccessData[outputIndex] = successItems;
800
- }
801
- nodeSuccessData[mainOutputTypes.length - 1] = errorItems;
885
+ this.handleNodeErrorOutput(workflow, executionData, nodeSuccessData, runIndex);
802
886
  }
803
887
  if (runNodeData.closeFunction) {
804
888
  closeFunction = runNodeData.closeFunction();
@@ -808,40 +892,7 @@ class WorkflowExecute {
808
892
  node: executionNode.name,
809
893
  workflowId: workflow.id,
810
894
  });
811
- if (nodeSuccessData?.length) {
812
- const isSingleInputAndOutput = executionData.data.main.length === 1 && executionData.data.main[0]?.length === 1;
813
- const isSameNumberOfItems = nodeSuccessData.length === 1 &&
814
- executionData.data.main.length === 1 &&
815
- executionData.data.main[0]?.length === nodeSuccessData[0].length;
816
- checkOutputData: for (const outputData of nodeSuccessData) {
817
- if (outputData === null) {
818
- continue;
819
- }
820
- for (const [index, item] of outputData.entries()) {
821
- if (item.pairedItem === undefined) {
822
- if (isSingleInputAndOutput) {
823
- item.pairedItem = {
824
- item: 0,
825
- };
826
- }
827
- else if (isSameNumberOfItems) {
828
- item.pairedItem = {
829
- item: index,
830
- };
831
- }
832
- else {
833
- break checkOutputData;
834
- }
835
- }
836
- }
837
- }
838
- }
839
- if (nodeSuccessData === undefined) {
840
- nodeSuccessData = null;
841
- }
842
- else {
843
- this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
844
- }
895
+ nodeSuccessData = this.assignPairedItems(nodeSuccessData, executionData);
845
896
  if (nodeSuccessData === null || nodeSuccessData[0][0] === undefined) {
846
897
  if (executionData.node.alwaysOutputData === true) {
847
898
  const pairedItem = [];
@@ -881,7 +932,7 @@ class WorkflowExecute {
881
932
  toReport = error;
882
933
  }
883
934
  if (toReport) {
884
- n8n_workflow_1.ErrorReporterProxy.error(toReport, {
935
+ di_1.Container.get(error_reporter_1.ErrorReporter).error(toReport, {
885
936
  extra: {
886
937
  nodeName: executionNode.name,
887
938
  nodeType: executionNode.type,
@@ -1204,14 +1255,113 @@ class WorkflowExecute {
1204
1255
  return fullRunData;
1205
1256
  }
1206
1257
  getFullRunData(startedAt) {
1207
- const fullRunData = {
1258
+ return {
1208
1259
  data: this.runExecutionData,
1209
1260
  mode: this.mode,
1210
1261
  startedAt,
1211
1262
  stoppedAt: new Date(),
1212
1263
  status: this.status,
1213
1264
  };
1214
- return fullRunData;
1265
+ }
1266
+ handleNodeErrorOutput(workflow, executionData, nodeSuccessData, runIndex) {
1267
+ const nodeType = workflow.nodeTypes.getByNameAndVersion(executionData.node.type, executionData.node.typeVersion);
1268
+ const outputs = n8n_workflow_1.NodeHelpers.getNodeOutputs(workflow, executionData.node, nodeType.description);
1269
+ const outputTypes = n8n_workflow_1.NodeHelpers.getConnectionTypes(outputs);
1270
+ const mainOutputTypes = outputTypes.filter((output) => output === "main");
1271
+ const errorItems = [];
1272
+ const closeFunctions = [];
1273
+ const executeFunctions = new node_execution_context_1.ExecuteContext(workflow, executionData.node, this.additionalData, this.mode, this.runExecutionData, runIndex, [], executionData.data, executionData, closeFunctions, this.abortController.signal);
1274
+ const dataProxy = executeFunctions.getWorkflowDataProxy(0);
1275
+ for (let outputIndex = 0; outputIndex < mainOutputTypes.length - 1; outputIndex++) {
1276
+ const successItems = [];
1277
+ const items = nodeSuccessData[outputIndex]?.length ? nodeSuccessData[outputIndex] : [];
1278
+ while (items.length) {
1279
+ const item = items.shift();
1280
+ if (item === undefined) {
1281
+ continue;
1282
+ }
1283
+ let errorData;
1284
+ if (item.error) {
1285
+ errorData = item.error;
1286
+ item.error = undefined;
1287
+ }
1288
+ else if (item.json.error && Object.keys(item.json).length === 1) {
1289
+ errorData = item.json.error;
1290
+ }
1291
+ else if (item.json.error && item.json.message && Object.keys(item.json).length === 2) {
1292
+ errorData = item.json.error;
1293
+ }
1294
+ if (errorData) {
1295
+ const pairedItemData = item.pairedItem && typeof item.pairedItem === 'object'
1296
+ ? Array.isArray(item.pairedItem)
1297
+ ? item.pairedItem[0]
1298
+ : item.pairedItem
1299
+ : undefined;
1300
+ if (executionData.source === null || pairedItemData === undefined) {
1301
+ errorItems.push(item);
1302
+ }
1303
+ else {
1304
+ const pairedItemInputIndex = pairedItemData.input || 0;
1305
+ const sourceData = executionData.source["main"][pairedItemInputIndex];
1306
+ const constPairedItem = dataProxy.$getPairedItem(sourceData.previousNode, sourceData, pairedItemData);
1307
+ if (constPairedItem === null) {
1308
+ errorItems.push(item);
1309
+ }
1310
+ else {
1311
+ errorItems.push({
1312
+ ...item,
1313
+ json: {
1314
+ ...constPairedItem.json,
1315
+ ...item.json,
1316
+ },
1317
+ });
1318
+ }
1319
+ }
1320
+ }
1321
+ else {
1322
+ successItems.push(item);
1323
+ }
1324
+ }
1325
+ nodeSuccessData[outputIndex] = successItems;
1326
+ }
1327
+ nodeSuccessData[mainOutputTypes.length - 1] = errorItems;
1328
+ }
1329
+ assignPairedItems(nodeSuccessData, executionData) {
1330
+ if (nodeSuccessData?.length) {
1331
+ const isSingleInputAndOutput = executionData.data.main.length === 1 && executionData.data.main[0]?.length === 1;
1332
+ const isSameNumberOfItems = nodeSuccessData.length === 1 &&
1333
+ executionData.data.main.length === 1 &&
1334
+ executionData.data.main[0]?.length === nodeSuccessData[0].length;
1335
+ checkOutputData: for (const outputData of nodeSuccessData) {
1336
+ if (outputData === null) {
1337
+ continue;
1338
+ }
1339
+ for (const [index, item] of outputData.entries()) {
1340
+ if (item.pairedItem === undefined) {
1341
+ if (isSingleInputAndOutput) {
1342
+ item.pairedItem = {
1343
+ item: 0,
1344
+ };
1345
+ }
1346
+ else if (isSameNumberOfItems) {
1347
+ item.pairedItem = {
1348
+ item: index,
1349
+ };
1350
+ }
1351
+ else {
1352
+ break checkOutputData;
1353
+ }
1354
+ }
1355
+ }
1356
+ }
1357
+ }
1358
+ if (nodeSuccessData === undefined) {
1359
+ nodeSuccessData = null;
1360
+ }
1361
+ else {
1362
+ this.runExecutionData.resultData.lastNodeExecuted = executionData.node.name;
1363
+ }
1364
+ return nodeSuccessData;
1215
1365
  }
1216
1366
  get isCancelled() {
1217
1367
  return this.abortController.signal.aborted;