mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-20 19:32:15 +00:00
feat: Only send needed data to task runner (no-changelog) (#11487)
This commit is contained in:
@@ -388,8 +388,13 @@ export class WorkflowDataProxy {
|
||||
* @private
|
||||
* @param {string} nodeName The name of the node query data from
|
||||
* @param {boolean} [shortSyntax=false] If short syntax got used
|
||||
* @param {boolean} [throwOnMissingExecutionData=true] If an error should get thrown if no execution data is available
|
||||
*/
|
||||
private nodeDataGetter(nodeName: string, shortSyntax = false) {
|
||||
private nodeDataGetter(
|
||||
nodeName: string,
|
||||
shortSyntax = false,
|
||||
throwOnMissingExecutionData = true,
|
||||
) {
|
||||
const that = this;
|
||||
const node = this.workflow.nodes[nodeName];
|
||||
|
||||
@@ -416,6 +421,10 @@ export class WorkflowDataProxy {
|
||||
shortSyntax,
|
||||
});
|
||||
|
||||
if (executionData.length === 0 && !throwOnMissingExecutionData) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (executionData.length === 0) {
|
||||
if (that.workflow.getParentNodes(nodeName).length === 0) {
|
||||
throw new ExpressionError('No execution data available', {
|
||||
@@ -613,7 +622,7 @@ export class WorkflowDataProxy {
|
||||
* Returns the data proxy object which allows to query data from current run
|
||||
*
|
||||
*/
|
||||
getDataProxy(): IWorkflowDataProxyData {
|
||||
getDataProxy(opts?: { throwOnMissingExecutionData: boolean }): IWorkflowDataProxyData {
|
||||
const that = this;
|
||||
|
||||
// replacing proxies with the actual data.
|
||||
@@ -1367,6 +1376,7 @@ export class WorkflowDataProxy {
|
||||
$nodeId: that.workflow.getNode(that.activeNodeName)?.id,
|
||||
$webhookId: that.workflow.getNode(that.activeNodeName)?.webhookId,
|
||||
};
|
||||
const throwOnMissingExecutionData = opts?.throwOnMissingExecutionData ?? true;
|
||||
|
||||
return new Proxy(base, {
|
||||
has: () => true,
|
||||
@@ -1374,10 +1384,11 @@ export class WorkflowDataProxy {
|
||||
if (name === 'isProxy') return true;
|
||||
|
||||
if (['$data', '$json'].includes(name as string)) {
|
||||
return that.nodeDataGetter(that.contextNodeName, true)?.json;
|
||||
return that.nodeDataGetter(that.contextNodeName, true, throwOnMissingExecutionData)?.json;
|
||||
}
|
||||
if (name === '$binary') {
|
||||
return that.nodeDataGetter(that.contextNodeName, true)?.binary;
|
||||
return that.nodeDataGetter(that.contextNodeName, true, throwOnMissingExecutionData)
|
||||
?.binary;
|
||||
}
|
||||
|
||||
return Reflect.get(target, name, receiver);
|
||||
|
||||
@@ -26,6 +26,7 @@ const getProxyFromFixture = (
|
||||
run: IRun | null,
|
||||
activeNode: string,
|
||||
mode?: WorkflowExecuteMode,
|
||||
opts?: { throwOnMissingExecutionData: boolean },
|
||||
) => {
|
||||
const taskData = run?.data.resultData.runData[activeNode]?.[0];
|
||||
const lastNodeConnectionInputData = taskData?.data?.main[0];
|
||||
@@ -73,7 +74,7 @@ const getProxyFromFixture = (
|
||||
executeData,
|
||||
);
|
||||
|
||||
return dataProxy.getDataProxy();
|
||||
return dataProxy.getDataProxy(opts);
|
||||
};
|
||||
|
||||
describe('WorkflowDataProxy', () => {
|
||||
@@ -404,4 +405,42 @@ describe('WorkflowDataProxy', () => {
|
||||
expect(proxy.$node.PinnedSet.json.firstName).toBe('Joe');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Partial data', () => {
|
||||
const fixture = loadFixture('partial_data');
|
||||
|
||||
describe('Default behaviour (throw on missing execution data)', () => {
|
||||
const proxy = getProxyFromFixture(fixture.workflow, fixture.run, 'End');
|
||||
|
||||
test('$binary', () => {
|
||||
expect(() => proxy.$binary).toThrowError(ExpressionError);
|
||||
});
|
||||
|
||||
test('$json', () => {
|
||||
expect(() => proxy.$json).toThrowError(ExpressionError);
|
||||
});
|
||||
|
||||
test('$data', () => {
|
||||
expect(() => proxy.$data).toThrowError(ExpressionError);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Don't throw on missing execution data)", () => {
|
||||
const proxy = getProxyFromFixture(fixture.workflow, fixture.run, 'End', undefined, {
|
||||
throwOnMissingExecutionData: false,
|
||||
});
|
||||
|
||||
test('$binary', () => {
|
||||
expect(proxy.$binary).toBeUndefined();
|
||||
});
|
||||
|
||||
test('$json', () => {
|
||||
expect(proxy.$json).toBeUndefined();
|
||||
});
|
||||
|
||||
test('$data', () => {
|
||||
expect(proxy.$data).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
71
packages/workflow/test/fixtures/WorkflowDataProxy/partial_data_run.json
vendored
Normal file
71
packages/workflow/test/fixtures/WorkflowDataProxy/partial_data_run.json
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"data": {
|
||||
"startData": {},
|
||||
"resultData": {
|
||||
"runData": {
|
||||
"Start": [
|
||||
{
|
||||
"startTime": 1,
|
||||
"executionTime": 1,
|
||||
"data": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"json": {}
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"Function": [
|
||||
{
|
||||
"startTime": 1,
|
||||
"executionTime": 1,
|
||||
"data": {
|
||||
"main": [[]]
|
||||
},
|
||||
"source": [
|
||||
{
|
||||
"previousNode": "Start"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Rename": [
|
||||
{
|
||||
"startTime": 1,
|
||||
"executionTime": 1,
|
||||
"data": {
|
||||
"main": [[]]
|
||||
},
|
||||
"source": [
|
||||
{
|
||||
"previousNode": "Function"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"End": [
|
||||
{
|
||||
"startTime": 1,
|
||||
"executionTime": 1,
|
||||
"data": {
|
||||
"main": [[]]
|
||||
},
|
||||
"source": [
|
||||
{
|
||||
"previousNode": "Rename"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"mode": "manual",
|
||||
"startedAt": "2024-02-08T15:45:18.848Z",
|
||||
"stoppedAt": "2024-02-08T15:45:18.862Z",
|
||||
"status": "running"
|
||||
}
|
||||
86
packages/workflow/test/fixtures/WorkflowDataProxy/partial_data_workflow.json
vendored
Normal file
86
packages/workflow/test/fixtures/WorkflowDataProxy/partial_data_workflow.json
vendored
Normal file
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"name": "",
|
||||
"nodes": [
|
||||
{
|
||||
"name": "Start",
|
||||
"type": "test.set",
|
||||
"parameters": {},
|
||||
"typeVersion": 1,
|
||||
"id": "uuid-1",
|
||||
"position": [100, 200]
|
||||
},
|
||||
{
|
||||
"name": "Function",
|
||||
"type": "test.set",
|
||||
"parameters": {
|
||||
"functionCode": "// Code here will run only once, no matter how many input items there are.\n// More info and help: https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.function/\nconst { DateTime, Duration, Interval } = require(\"luxon\");\n\nconst data = [\n {\n \"length\": 105\n },\n {\n \"length\": 160\n },\n {\n \"length\": 121\n },\n {\n \"length\": 275\n },\n {\n \"length\": 950\n },\n];\n\nreturn data.map(fact => ({json: fact}));"
|
||||
},
|
||||
"typeVersion": 1,
|
||||
"id": "uuid-2",
|
||||
"position": [280, 200]
|
||||
},
|
||||
{
|
||||
"name": "Rename",
|
||||
"type": "test.set",
|
||||
"parameters": {
|
||||
"value1": "data",
|
||||
"value2": "initialName"
|
||||
},
|
||||
"typeVersion": 1,
|
||||
"id": "uuid-3",
|
||||
"position": [460, 200]
|
||||
},
|
||||
{
|
||||
"name": "Set",
|
||||
"type": "test.set",
|
||||
"parameters": {},
|
||||
"typeVersion": 1,
|
||||
"id": "uuid-4",
|
||||
"position": [640, 200]
|
||||
},
|
||||
{
|
||||
"name": "End",
|
||||
"type": "test.set",
|
||||
"parameters": {},
|
||||
"typeVersion": 1,
|
||||
"id": "uuid-5",
|
||||
"position": [640, 200]
|
||||
}
|
||||
],
|
||||
"pinData": {},
|
||||
"connections": {
|
||||
"Start": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Function",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Function": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "Rename",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
},
|
||||
"Rename": {
|
||||
"main": [
|
||||
[
|
||||
{
|
||||
"node": "End",
|
||||
"type": "main",
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user