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 type { PartialAdditionalData, TaskData } from '@n8n/task-runner';
|
||||||
import { mock } from 'jest-mock-extended';
|
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';
|
import { DataRequestResponseBuilder } from '../data-request-response-builder';
|
||||||
|
|
||||||
|
@ -19,6 +25,22 @@ const additionalData = mock<PartialAdditionalData>({
|
||||||
restartExecutionId: undefined,
|
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>({
|
const workflow: TaskData['workflow'] = mock<Workflow>({
|
||||||
id: '1',
|
id: '1',
|
||||||
name: 'Test Workflow',
|
name: 'Test Workflow',
|
||||||
|
@ -30,9 +52,39 @@ const workflow: TaskData['workflow'] = mock<Workflow>({
|
||||||
staticData: {},
|
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>({
|
const taskData = mock<TaskData>({
|
||||||
additionalData,
|
additionalData,
|
||||||
workflow,
|
workflow,
|
||||||
|
runExecutionData,
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DataRequestResponseBuilder', () => {
|
describe('DataRequestResponseBuilder', () => {
|
||||||
|
@ -71,4 +123,20 @@ describe('DataRequestResponseBuilder', () => {
|
||||||
staticData: workflow.staticData,
|
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: {},
|
contextData: {},
|
||||||
nodeExecutionStack: [],
|
nodeExecutionStack: [],
|
||||||
metadata: {},
|
metadata: {},
|
||||||
waitingExecution: {
|
waitingExecution: {},
|
||||||
[codeNode.name]: {
|
waitingExecutionSource: {},
|
||||||
'0': {
|
|
||||||
main: [codeNodeInputItems],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
waitingExecutionSource: {
|
|
||||||
[codeNode.name]: {
|
|
||||||
'0': {
|
|
||||||
main: [
|
|
||||||
{
|
|
||||||
previousNode: debugHelperNode.name,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
runIndex: 0,
|
runIndex: 0,
|
||||||
|
|
|
@ -1,5 +1,10 @@
|
||||||
import type { DataRequestResponse, PartialAdditionalData, TaskData } from '@n8n/task-runner';
|
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
|
* Transforms TaskData to DataRequestResponse. The main purpose of the
|
||||||
|
@ -20,7 +25,7 @@ export class DataRequestResponseBuilder {
|
||||||
mode: taskData.mode,
|
mode: taskData.mode,
|
||||||
envProviderState: taskData.envProviderState,
|
envProviderState: taskData.envProviderState,
|
||||||
node: taskData.node,
|
node: taskData.node,
|
||||||
runExecutionData: taskData.runExecutionData,
|
runExecutionData: this.buildRunExecutionData(taskData.runExecutionData),
|
||||||
runIndex: taskData.runIndex,
|
runIndex: taskData.runIndex,
|
||||||
selfData: taskData.selfData,
|
selfData: taskData.selfData,
|
||||||
siblingParameters: taskData.siblingParameters,
|
siblingParameters: taskData.siblingParameters,
|
||||||
|
@ -59,4 +64,23 @@ export class DataRequestResponseBuilder {
|
||||||
staticData: workflow.staticData,
|
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),
|
runData: this.stripRunData(runExecutionData.resultData.runData),
|
||||||
pinData: this.stripPinData(runExecutionData.resultData.pinData),
|
pinData: this.stripPinData(runExecutionData.resultData.pinData),
|
||||||
},
|
},
|
||||||
executionData: runExecutionData.executionData
|
// TODO: We could send `runExecutionData.contextData` only if requested,
|
||||||
? {
|
// since it's only needed if $input.context or $("node").context is used.
|
||||||
// TODO: Figure out what these two are and can they be stripped
|
executionData: runExecutionData.executionData,
|
||||||
contextData: runExecutionData.executionData?.contextData,
|
|
||||||
nodeExecutionStack: runExecutionData.executionData.nodeExecutionStack,
|
|
||||||
|
|
||||||
metadata: runExecutionData.executionData.metadata,
|
|
||||||
waitingExecution: runExecutionData.executionData.waitingExecution,
|
|
||||||
waitingExecutionSource: runExecutionData.executionData.waitingExecutionSource,
|
|
||||||
}
|
|
||||||
: undefined,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -388,7 +388,10 @@ const currentOutputIndex = computed(() => {
|
||||||
return props.overrideOutputs[0];
|
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 branches = computed(() => {
|
||||||
const capitalize = (name: string) => name.charAt(0).toLocaleUpperCase() + name.slice(1);
|
const capitalize = (name: string) => name.charAt(0).toLocaleUpperCase() + name.slice(1);
|
||||||
|
|
Loading…
Reference in a new issue