mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
merge master
This commit is contained in:
commit
ee4becce2f
|
@ -1,6 +1,12 @@
|
|||
import type { PartialAdditionalData, TaskData } from '@n8n/task-runner';
|
||||
import { mock } from 'jest-mock-extended';
|
||||
import type { Workflow } from 'n8n-workflow';
|
||||
import type {
|
||||
IExecuteContextData,
|
||||
INode,
|
||||
INodeExecutionData,
|
||||
IRunExecutionData,
|
||||
Workflow,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
import { DataRequestResponseBuilder } from '../data-request-response-builder';
|
||||
|
||||
|
@ -19,6 +25,22 @@ const additionalData = mock<PartialAdditionalData>({
|
|||
restartExecutionId: undefined,
|
||||
});
|
||||
|
||||
const node = mock<INode>();
|
||||
const outputItems: INodeExecutionData[] = [
|
||||
{
|
||||
json: {
|
||||
uid: 'abb74fd4-bef2-4fae-9d53-ea24e9eb3032',
|
||||
email: 'Dan.Schmidt31@yahoo.com',
|
||||
firstname: 'Toni',
|
||||
lastname: 'Schuster',
|
||||
password: 'Q!D6C2',
|
||||
},
|
||||
pairedItem: {
|
||||
item: 0,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const workflow: TaskData['workflow'] = mock<Workflow>({
|
||||
id: '1',
|
||||
name: 'Test Workflow',
|
||||
|
@ -30,9 +52,39 @@ const workflow: TaskData['workflow'] = mock<Workflow>({
|
|||
staticData: {},
|
||||
});
|
||||
|
||||
const contextData = mock<IExecuteContextData>();
|
||||
const metadata = {
|
||||
'0': [],
|
||||
};
|
||||
|
||||
const runExecutionData = mock<IRunExecutionData>({
|
||||
executionData: {
|
||||
contextData,
|
||||
metadata,
|
||||
nodeExecutionStack: [
|
||||
{
|
||||
node,
|
||||
data: {
|
||||
main: [outputItems],
|
||||
},
|
||||
source: {},
|
||||
},
|
||||
],
|
||||
waitingExecution: {
|
||||
node: {
|
||||
'0': {
|
||||
main: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
waitingExecutionSource: {},
|
||||
},
|
||||
});
|
||||
|
||||
const taskData = mock<TaskData>({
|
||||
additionalData,
|
||||
workflow,
|
||||
runExecutionData,
|
||||
});
|
||||
|
||||
describe('DataRequestResponseBuilder', () => {
|
||||
|
@ -71,4 +123,20 @@ describe('DataRequestResponseBuilder', () => {
|
|||
staticData: workflow.staticData,
|
||||
});
|
||||
});
|
||||
|
||||
it('clears nodeExecutionStack, waitingExecution and waitingExecutionSource from runExecutionData', () => {
|
||||
const result = builder.buildFromTaskData(taskData);
|
||||
|
||||
expect(result.runExecutionData).toStrictEqual({
|
||||
startData: runExecutionData.startData,
|
||||
resultData: runExecutionData.resultData,
|
||||
executionData: {
|
||||
contextData,
|
||||
metadata,
|
||||
nodeExecutionStack: [],
|
||||
waitingExecution: {},
|
||||
waitingExecutionSource: null,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -115,24 +115,8 @@ const taskData: DataRequestResponse = {
|
|||
contextData: {},
|
||||
nodeExecutionStack: [],
|
||||
metadata: {},
|
||||
waitingExecution: {
|
||||
[codeNode.name]: {
|
||||
'0': {
|
||||
main: [codeNodeInputItems],
|
||||
},
|
||||
},
|
||||
},
|
||||
waitingExecutionSource: {
|
||||
[codeNode.name]: {
|
||||
'0': {
|
||||
main: [
|
||||
{
|
||||
previousNode: debugHelperNode.name,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
waitingExecution: {},
|
||||
waitingExecutionSource: {},
|
||||
},
|
||||
},
|
||||
runIndex: 0,
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
import type { DataRequestResponse, PartialAdditionalData, TaskData } from '@n8n/task-runner';
|
||||
import type { IWorkflowExecuteAdditionalData, Workflow, WorkflowParameters } from 'n8n-workflow';
|
||||
import type {
|
||||
IRunExecutionData,
|
||||
IWorkflowExecuteAdditionalData,
|
||||
Workflow,
|
||||
WorkflowParameters,
|
||||
} from 'n8n-workflow';
|
||||
|
||||
/**
|
||||
* Transforms TaskData to DataRequestResponse. The main purpose of the
|
||||
|
@ -20,7 +25,7 @@ export class DataRequestResponseBuilder {
|
|||
mode: taskData.mode,
|
||||
envProviderState: taskData.envProviderState,
|
||||
node: taskData.node,
|
||||
runExecutionData: taskData.runExecutionData,
|
||||
runExecutionData: this.buildRunExecutionData(taskData.runExecutionData),
|
||||
runIndex: taskData.runIndex,
|
||||
selfData: taskData.selfData,
|
||||
siblingParameters: taskData.siblingParameters,
|
||||
|
@ -59,4 +64,23 @@ export class DataRequestResponseBuilder {
|
|||
staticData: workflow.staticData,
|
||||
};
|
||||
}
|
||||
|
||||
private buildRunExecutionData(runExecutionData: IRunExecutionData) {
|
||||
return {
|
||||
startData: runExecutionData.startData,
|
||||
resultData: runExecutionData.resultData,
|
||||
executionData: runExecutionData.executionData
|
||||
? {
|
||||
contextData: runExecutionData.executionData.contextData,
|
||||
metadata: runExecutionData.executionData.metadata,
|
||||
|
||||
// These are related to workflow execution and are not something
|
||||
// that are accessible by nodes, so we always omit them
|
||||
nodeExecutionStack: [],
|
||||
waitingExecution: {},
|
||||
waitingExecutionSource: null,
|
||||
}
|
||||
: undefined,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,17 +52,9 @@ export class DataRequestResponseStripper {
|
|||
runData: this.stripRunData(runExecutionData.resultData.runData),
|
||||
pinData: this.stripPinData(runExecutionData.resultData.pinData),
|
||||
},
|
||||
executionData: runExecutionData.executionData
|
||||
? {
|
||||
// TODO: Figure out what these two are and can they be stripped
|
||||
contextData: runExecutionData.executionData?.contextData,
|
||||
nodeExecutionStack: runExecutionData.executionData.nodeExecutionStack,
|
||||
|
||||
metadata: runExecutionData.executionData.metadata,
|
||||
waitingExecution: runExecutionData.executionData.waitingExecution,
|
||||
waitingExecutionSource: runExecutionData.executionData.waitingExecutionSource,
|
||||
}
|
||||
: undefined,
|
||||
// TODO: We could send `runExecutionData.contextData` only if requested,
|
||||
// since it's only needed if $input.context or $("node").context is used.
|
||||
executionData: runExecutionData.executionData,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -388,7 +388,10 @@ const currentOutputIndex = computed(() => {
|
|||
return props.overrideOutputs[0];
|
||||
}
|
||||
|
||||
return outputIndex.value;
|
||||
// In some cases nodes may switch their outputCount while the user still
|
||||
// has a higher outputIndex selected. We could adjust outputIndex directly,
|
||||
// but that loses data as we can keep the user selection if the branch reappears.
|
||||
return Math.min(outputIndex.value, maxOutputIndex.value);
|
||||
});
|
||||
const branches = computed(() => {
|
||||
const capitalize = (name: string) => name.charAt(0).toLocaleUpperCase() + name.slice(1);
|
||||
|
|
Loading…
Reference in a new issue