@fsai-flow/workflow 0.0.1

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/.eslintrc.json +33 -0
  2. package/README.md +11 -0
  3. package/dist/README.md +11 -0
  4. package/dist/package.json +42 -0
  5. package/dist/src/index.d.ts +21 -0
  6. package/dist/src/index.js +33 -0
  7. package/dist/src/index.js.map +1 -0
  8. package/dist/src/lib/Constants.d.ts +68 -0
  9. package/dist/src/lib/Constants.js +106 -0
  10. package/dist/src/lib/Constants.js.map +1 -0
  11. package/dist/src/lib/DeferredPromise.d.ts +6 -0
  12. package/dist/src/lib/DeferredPromise.js +11 -0
  13. package/dist/src/lib/DeferredPromise.js.map +1 -0
  14. package/dist/src/lib/Expression.d.ts +65 -0
  15. package/dist/src/lib/Expression.js +215 -0
  16. package/dist/src/lib/Expression.js.map +1 -0
  17. package/dist/src/lib/Interfaces.d.ts +1569 -0
  18. package/dist/src/lib/Interfaces.js +44 -0
  19. package/dist/src/lib/Interfaces.js.map +1 -0
  20. package/dist/src/lib/LoggerProxy.d.ts +9 -0
  21. package/dist/src/lib/LoggerProxy.js +40 -0
  22. package/dist/src/lib/LoggerProxy.js.map +1 -0
  23. package/dist/src/lib/MetadataUtils.d.ts +4 -0
  24. package/dist/src/lib/MetadataUtils.js +27 -0
  25. package/dist/src/lib/MetadataUtils.js.map +1 -0
  26. package/dist/src/lib/NodeErrors.d.ts +82 -0
  27. package/dist/src/lib/NodeErrors.js +289 -0
  28. package/dist/src/lib/NodeErrors.js.map +1 -0
  29. package/dist/src/lib/NodeHelpers.d.ts +198 -0
  30. package/dist/src/lib/NodeHelpers.js +1348 -0
  31. package/dist/src/lib/NodeHelpers.js.map +1 -0
  32. package/dist/src/lib/ObservableObject.d.ts +5 -0
  33. package/dist/src/lib/ObservableObject.js +61 -0
  34. package/dist/src/lib/ObservableObject.js.map +1 -0
  35. package/dist/src/lib/RoutingNode.d.ts +18 -0
  36. package/dist/src/lib/RoutingNode.js +508 -0
  37. package/dist/src/lib/RoutingNode.js.map +1 -0
  38. package/dist/src/lib/TelemetryHelpers.d.ts +3 -0
  39. package/dist/src/lib/TelemetryHelpers.js +69 -0
  40. package/dist/src/lib/TelemetryHelpers.js.map +1 -0
  41. package/dist/src/lib/TypeValidation.d.ts +21 -0
  42. package/dist/src/lib/TypeValidation.js +385 -0
  43. package/dist/src/lib/TypeValidation.js.map +1 -0
  44. package/dist/src/lib/VersionedNodeType.d.ts +9 -0
  45. package/dist/src/lib/VersionedNodeType.js +26 -0
  46. package/dist/src/lib/VersionedNodeType.js.map +1 -0
  47. package/dist/src/lib/Workflow.d.ts +248 -0
  48. package/dist/src/lib/Workflow.js +901 -0
  49. package/dist/src/lib/Workflow.js.map +1 -0
  50. package/dist/src/lib/WorkflowDataProxy.d.ts +87 -0
  51. package/dist/src/lib/WorkflowDataProxy.js +556 -0
  52. package/dist/src/lib/WorkflowDataProxy.js.map +1 -0
  53. package/dist/src/lib/WorkflowErrors.d.ts +9 -0
  54. package/dist/src/lib/WorkflowErrors.js +18 -0
  55. package/dist/src/lib/WorkflowErrors.js.map +1 -0
  56. package/dist/src/lib/WorkflowHooks.d.ts +11 -0
  57. package/dist/src/lib/WorkflowHooks.js +34 -0
  58. package/dist/src/lib/WorkflowHooks.js.map +1 -0
  59. package/dist/src/lib/errors/base/base.error.d.ts +30 -0
  60. package/dist/src/lib/errors/base/base.error.js +45 -0
  61. package/dist/src/lib/errors/base/base.error.js.map +1 -0
  62. package/dist/src/lib/errors/base/operational.error.d.ts +15 -0
  63. package/dist/src/lib/errors/base/operational.error.js +19 -0
  64. package/dist/src/lib/errors/base/operational.error.js.map +1 -0
  65. package/dist/src/lib/errors/error.types.d.ts +11 -0
  66. package/dist/src/lib/errors/error.types.js +3 -0
  67. package/dist/src/lib/errors/error.types.js.map +1 -0
  68. package/dist/src/lib/errors/index.d.ts +1 -0
  69. package/dist/src/lib/errors/index.js +6 -0
  70. package/dist/src/lib/errors/index.js.map +1 -0
  71. package/dist/src/lib/result.d.ts +19 -0
  72. package/dist/src/lib/result.js +36 -0
  73. package/dist/src/lib/result.js.map +1 -0
  74. package/dist/src/lib/utils.d.ts +50 -0
  75. package/dist/src/lib/utils.js +110 -0
  76. package/dist/src/lib/utils.js.map +1 -0
  77. package/eslint.config.js +19 -0
  78. package/jest.config.ts +10 -0
  79. package/package.json +40 -0
  80. package/project.json +19 -0
  81. package/src/index.ts +33 -0
  82. package/src/lib/Constants.ts +124 -0
  83. package/src/lib/DeferredPromise.ts +14 -0
  84. package/src/lib/Expression.ts +375 -0
  85. package/src/lib/Interfaces.ts +2229 -0
  86. package/src/lib/LoggerProxy.ts +43 -0
  87. package/src/lib/MetadataUtils.ts +34 -0
  88. package/src/lib/NodeErrors.ts +332 -0
  89. package/src/lib/NodeHelpers.ts +1666 -0
  90. package/src/lib/ObservableObject.ts +77 -0
  91. package/src/lib/RoutingNode.ts +862 -0
  92. package/src/lib/TelemetryHelpers.ts +86 -0
  93. package/src/lib/TypeValidation.ts +431 -0
  94. package/src/lib/VersionedNodeType.ts +30 -0
  95. package/src/lib/Workflow.ts +1266 -0
  96. package/src/lib/WorkflowDataProxy.ts +708 -0
  97. package/src/lib/WorkflowErrors.ts +18 -0
  98. package/src/lib/WorkflowHooks.ts +51 -0
  99. package/src/lib/errors/base/base.error.ts +68 -0
  100. package/src/lib/errors/base/operational.error.ts +21 -0
  101. package/src/lib/errors/error.types.ts +14 -0
  102. package/src/lib/errors/index.ts +1 -0
  103. package/src/lib/result.ts +34 -0
  104. package/src/lib/utils.ts +132 -0
  105. package/tests/Helpers.ts +667 -0
  106. package/tests/NodeHelpers.test.ts +3053 -0
  107. package/tests/ObservableObject.test.ts +171 -0
  108. package/tests/RoutingNode.test.ts +1680 -0
  109. package/tests/Workflow.test.ts +1284 -0
  110. package/tests/WorkflowDataProxy.test.ts +199 -0
  111. package/tsconfig.json +27 -0
  112. package/tsconfig.lib.json +11 -0
  113. package/tsconfig.spec.json +14 -0
@@ -0,0 +1,1680 @@
1
+ import {
2
+ INode,
3
+ INodeExecutionData,
4
+ INodeParameters,
5
+ IRequestOptionsFromParameters,
6
+ IRunExecutionData,
7
+ RoutingNode,
8
+ Workflow,
9
+ INodeProperties,
10
+ IDataObject,
11
+ IExecuteSingleFunctions,
12
+ IHttpRequestOptions,
13
+ IN8nHttpFullResponse,
14
+ ITaskDataConnections,
15
+ INodeExecuteFunctions,
16
+ IN8nRequestOperations,
17
+ INodeCredentialDescription,
18
+ } from '..';
19
+
20
+ import * as Helpers from './Helpers';
21
+
22
+ const postReceiveFunction1 = async function (
23
+ this: IExecuteSingleFunctions,
24
+ items: INodeExecutionData[],
25
+ response: IN8nHttpFullResponse,
26
+ ): Promise<INodeExecutionData[]> {
27
+ items.forEach((item) => (item['json1'] = { success: true }));
28
+ return items;
29
+ };
30
+
31
+ const preSendFunction1 = async function (
32
+ this: IExecuteSingleFunctions,
33
+ requestOptions: IHttpRequestOptions,
34
+ ): Promise<IHttpRequestOptions> {
35
+ requestOptions.headers = (requestOptions.headers || {}) as IDataObject;
36
+ requestOptions.headers['addedIn'] = 'preSendFunction1';
37
+ return requestOptions;
38
+ };
39
+
40
+ describe('RoutingNode', () => {
41
+ describe('getRequestOptionsFromParameters', () => {
42
+ const tests: Array<{
43
+ description: string;
44
+ input: {
45
+ nodeParameters: INodeParameters;
46
+ nodeTypeProperties: INodeProperties;
47
+ };
48
+ output: IRequestOptionsFromParameters | undefined;
49
+ }> = [
50
+ {
51
+ description: 'single parameter, only send defined, fixed value',
52
+ input: {
53
+ nodeParameters: {},
54
+ nodeTypeProperties: {
55
+ displayName: 'Email',
56
+ name: 'email',
57
+ type: 'string',
58
+ routing: {
59
+ send: {
60
+ property: 'toEmail',
61
+ type: 'body',
62
+ value: 'fixedValue',
63
+ },
64
+ },
65
+ default: '',
66
+ },
67
+ },
68
+ output: {
69
+ options: {
70
+ qs: {},
71
+ body: {
72
+ toEmail: 'fixedValue',
73
+ },
74
+ },
75
+ preSend: [],
76
+ postReceive: [],
77
+ requestOperations: {},
78
+ },
79
+ },
80
+ {
81
+ description: 'single parameter, only send defined, using expression',
82
+ input: {
83
+ nodeParameters: {
84
+ email: 'test@test.com',
85
+ },
86
+ nodeTypeProperties: {
87
+ displayName: 'Email',
88
+ name: 'email',
89
+ type: 'string',
90
+ routing: {
91
+ send: {
92
+ property: 'toEmail',
93
+ type: 'body',
94
+ value: '={{$value.toUpperCase()}}',
95
+ },
96
+ },
97
+ default: '',
98
+ },
99
+ },
100
+ output: {
101
+ options: {
102
+ qs: {},
103
+ body: {
104
+ toEmail: 'TEST@TEST.COM',
105
+ },
106
+ },
107
+ preSend: [],
108
+ postReceive: [],
109
+ requestOperations: {},
110
+ },
111
+ },
112
+ {
113
+ description: 'single parameter, send and operations defined, fixed value',
114
+ input: {
115
+ nodeParameters: {},
116
+ nodeTypeProperties: {
117
+ displayName: 'Email',
118
+ name: 'email',
119
+ type: 'string',
120
+ routing: {
121
+ send: {
122
+ property: 'toEmail',
123
+ type: 'body',
124
+ value: 'fixedValue',
125
+ },
126
+ operations: {
127
+ pagination: {
128
+ type: 'offset',
129
+ properties: {
130
+ limitParameter: 'limit',
131
+ offsetParameter: 'offset',
132
+ pageSize: 10,
133
+ rootProperty: 'data',
134
+ type: 'body',
135
+ },
136
+ },
137
+ },
138
+ },
139
+ default: '',
140
+ },
141
+ },
142
+ output: {
143
+ options: {
144
+ qs: {},
145
+ body: {
146
+ toEmail: 'fixedValue',
147
+ },
148
+ },
149
+ preSend: [],
150
+ postReceive: [],
151
+ requestOperations: {
152
+ pagination: {
153
+ type: 'offset',
154
+ properties: {
155
+ limitParameter: 'limit',
156
+ offsetParameter: 'offset',
157
+ pageSize: 10,
158
+ rootProperty: 'data',
159
+ type: 'body',
160
+ },
161
+ },
162
+ },
163
+ },
164
+ },
165
+ {
166
+ description: 'mutliple parameters, complex example with everything',
167
+ input: {
168
+ nodeParameters: {
169
+ multipleFields: {
170
+ value1: 'v1',
171
+ value2: 'v2',
172
+ value3: 'v3',
173
+ value4: 4,
174
+ lowerLevel: {
175
+ lowLevelValue1: 1,
176
+ lowLevelValue2: 'llv2',
177
+ },
178
+ customPropertiesSingle1: {
179
+ property: {
180
+ name: 'cSName1',
181
+ value: 'cSValue1',
182
+ },
183
+ },
184
+ customPropertiesMulti: {
185
+ property0: [
186
+ {
187
+ name: 'cM0Name1',
188
+ value: 'cM0Value1',
189
+ },
190
+ {
191
+ name: 'cM0Name2',
192
+ value: 'cM0Value2',
193
+ },
194
+ ],
195
+ property1: [
196
+ {
197
+ name: 'cM1Name2',
198
+ value: 'cM1Value2',
199
+ },
200
+ {
201
+ name: 'cM1Name2',
202
+ value: 'cM1Value2',
203
+ },
204
+ ],
205
+ },
206
+ },
207
+ },
208
+ nodeTypeProperties: {
209
+ displayName: 'Multiple Fields',
210
+ name: 'multipleFields',
211
+ type: 'collection',
212
+ placeholder: 'Add Field',
213
+ routing: {
214
+ request: {
215
+ method: 'GET',
216
+ url: '/destination1',
217
+ },
218
+ operations: {
219
+ pagination: {
220
+ type: 'offset',
221
+ properties: {
222
+ limitParameter: 'limit1',
223
+ offsetParameter: 'offset1',
224
+ pageSize: 1,
225
+ rootProperty: 'data1',
226
+ type: 'body',
227
+ },
228
+ },
229
+ },
230
+ output: {
231
+ maxResults: 10,
232
+ postReceive: [postReceiveFunction1],
233
+ },
234
+ },
235
+ default: {},
236
+ options: [
237
+ {
238
+ displayName: 'Value 1',
239
+ name: 'value1',
240
+ type: 'string',
241
+ routing: {
242
+ send: {
243
+ property: 'value1',
244
+ type: 'body',
245
+ },
246
+ },
247
+ default: '',
248
+ },
249
+ {
250
+ displayName: 'Value 2',
251
+ name: 'value2',
252
+ type: 'string',
253
+ routing: {
254
+ send: {
255
+ property: 'topLevel.value2',
256
+ propertyInDotNotation: false,
257
+ type: 'body',
258
+ preSend: [preSendFunction1],
259
+ },
260
+ },
261
+ default: '',
262
+ },
263
+ {
264
+ displayName: 'Value 3',
265
+ name: 'value3',
266
+ type: 'string',
267
+ routing: {
268
+ send: {
269
+ property: 'lowerLevel.value3',
270
+ type: 'body',
271
+ },
272
+ },
273
+ default: '',
274
+ },
275
+ {
276
+ displayName: 'Value 4',
277
+ name: 'value4',
278
+ type: 'number',
279
+ default: 0,
280
+ routing: {
281
+ send: {
282
+ property: 'value4',
283
+ type: 'query',
284
+ },
285
+ output: {
286
+ maxResults: '={{$value}}',
287
+ },
288
+ operations: {
289
+ pagination: {
290
+ type: 'offset',
291
+ properties: {
292
+ limitParameter: 'limit100',
293
+ offsetParameter: 'offset100',
294
+ pageSize: 100,
295
+ rootProperty: 'data100',
296
+ type: 'query',
297
+ },
298
+ },
299
+ },
300
+ },
301
+ },
302
+ // This one should not be included
303
+ {
304
+ displayName: 'Value 5',
305
+ name: 'value5',
306
+ type: 'number',
307
+ displayOptions: {
308
+ show: {
309
+ value4: [1],
310
+ },
311
+ },
312
+ default: 5,
313
+ routing: {
314
+ send: {
315
+ property: 'value5',
316
+ type: 'query',
317
+ },
318
+ operations: {
319
+ pagination: {
320
+ type: 'offset',
321
+ properties: {
322
+ limitParameter: 'limit10',
323
+ offsetParameter: 'offset10',
324
+ pageSize: 10,
325
+ rootProperty: 'data10',
326
+ type: 'body',
327
+ },
328
+ },
329
+ },
330
+ },
331
+ },
332
+ {
333
+ displayName: 'Lower Level',
334
+ name: 'lowerLevel',
335
+ type: 'collection',
336
+ placeholder: 'Add Field',
337
+ default: {},
338
+ options: [
339
+ {
340
+ displayName: 'Low Level Value1',
341
+ name: 'lowLevelValue1',
342
+ type: 'number',
343
+ default: 0,
344
+ routing: {
345
+ send: {
346
+ property: 'llvalue1',
347
+ type: 'query',
348
+ },
349
+ },
350
+ },
351
+ {
352
+ displayName: 'Low Level Value2',
353
+ name: 'lowLevelValue2',
354
+ type: 'string',
355
+ default: '',
356
+ routing: {
357
+ send: {
358
+ property: 'llvalue2',
359
+ type: 'query',
360
+ preSend: [preSendFunction1],
361
+ },
362
+ output: {
363
+ postReceive: [
364
+ {
365
+ type: 'rootProperty',
366
+ properties: {
367
+ property: 'data',
368
+ },
369
+ },
370
+ ],
371
+ },
372
+ },
373
+ },
374
+ ],
375
+ },
376
+ // Test fixed collection1: multipleValues=false
377
+ {
378
+ displayName: 'Custom Properties1 (single)',
379
+ name: 'customPropertiesSingle1',
380
+ placeholder: 'Add Custom Property',
381
+ type: 'fixedCollection',
382
+ default: {},
383
+ options: [
384
+ {
385
+ name: 'property',
386
+ displayName: 'Property',
387
+ values: [
388
+ // To set: { single-customValues: { name: 'name', value: 'value'} }
389
+ {
390
+ displayName: 'Property Name',
391
+ name: 'name',
392
+ type: 'string',
393
+ default: '',
394
+ routing: {
395
+ request: {
396
+ method: 'POST',
397
+ url: '=/{{$value}}',
398
+ },
399
+ send: {
400
+ property: 'single-customValues.name',
401
+ },
402
+ },
403
+ },
404
+ {
405
+ displayName: 'Property Value',
406
+ name: 'value',
407
+ type: 'string',
408
+ default: '',
409
+ routing: {
410
+ send: {
411
+ property: 'single-customValues.value',
412
+ },
413
+ },
414
+ },
415
+ ],
416
+ },
417
+ ],
418
+ },
419
+ // Test fixed collection: multipleValues=true
420
+ {
421
+ displayName: 'Custom Properties (multi)',
422
+ name: 'customPropertiesMulti',
423
+ placeholder: 'Add Custom Property',
424
+ type: 'fixedCollection',
425
+ typeOptions: {
426
+ multipleValues: true,
427
+ },
428
+ default: {},
429
+ options: [
430
+ {
431
+ name: 'property0',
432
+ displayName: 'Property0',
433
+ values: [
434
+ // To set: { name0: 'value0', name1: 'value1' }
435
+ {
436
+ displayName: 'Property Name',
437
+ name: 'name',
438
+ type: 'string',
439
+ default: '',
440
+ description: 'Name of the property to set.',
441
+ },
442
+ {
443
+ displayName: 'Property Value',
444
+ name: 'value',
445
+ type: 'string',
446
+ default: '',
447
+ routing: {
448
+ send: {
449
+ property: '=customMulti0.{{$parent.name}}',
450
+ type: 'body',
451
+ },
452
+ },
453
+ description: 'Value of the property to set.',
454
+ },
455
+ ],
456
+ },
457
+
458
+ {
459
+ name: 'property1',
460
+ displayName: 'Property1',
461
+ values: [
462
+ // To set: { customValues: [ { name: 'name0', value: 'value0'}, { name: 'name1', value: 'value1'} ]}
463
+ {
464
+ displayName: 'Property Name',
465
+ name: 'name',
466
+ type: 'string',
467
+ default: '',
468
+ routing: {
469
+ send: {
470
+ property: '=customMulti1[{{$index}}].name',
471
+ type: 'body',
472
+ },
473
+ },
474
+ },
475
+ {
476
+ displayName: 'Property Value',
477
+ name: 'value',
478
+ type: 'string',
479
+ default: '',
480
+ routing: {
481
+ send: {
482
+ property: '=customMulti1[{{$index}}].value',
483
+ type: 'body',
484
+ },
485
+ },
486
+ },
487
+ ],
488
+ },
489
+ ],
490
+ },
491
+ ],
492
+ },
493
+ },
494
+ output: {
495
+ maxResults: 4,
496
+ options: {
497
+ method: 'POST',
498
+ url: '/cSName1',
499
+ qs: {
500
+ value4: 4,
501
+ llvalue1: 1,
502
+ llvalue2: 'llv2',
503
+ 'single-customValues': {
504
+ name: 'cSName1',
505
+ value: 'cSValue1',
506
+ },
507
+ },
508
+ body: {
509
+ value1: 'v1',
510
+ 'topLevel.value2': 'v2',
511
+ lowerLevel: {
512
+ value3: 'v3',
513
+ },
514
+ customMulti0: {
515
+ cM0Name1: 'cM0Value1',
516
+ cM0Name2: 'cM0Value2',
517
+ },
518
+ customMulti1: [
519
+ {
520
+ name: 'cM1Name2',
521
+ value: 'cM1Value2',
522
+ },
523
+ {
524
+ name: 'cM1Name2',
525
+ value: 'cM1Value2',
526
+ },
527
+ ],
528
+ },
529
+ },
530
+ preSend: [preSendFunction1, preSendFunction1],
531
+ postReceive: [
532
+ {
533
+ actions: [postReceiveFunction1],
534
+ data: {
535
+ parameterValue: {
536
+ value1: 'v1',
537
+ value2: 'v2',
538
+ value3: 'v3',
539
+ value4: 4,
540
+ lowerLevel: {
541
+ lowLevelValue1: 1,
542
+ lowLevelValue2: 'llv2',
543
+ },
544
+ customPropertiesSingle1: {
545
+ property: {
546
+ name: 'cSName1',
547
+ value: 'cSValue1',
548
+ },
549
+ },
550
+ customPropertiesMulti: {
551
+ property0: [
552
+ {
553
+ name: 'cM0Name1',
554
+ value: 'cM0Value1',
555
+ },
556
+ {
557
+ name: 'cM0Name2',
558
+ value: 'cM0Value2',
559
+ },
560
+ ],
561
+ property1: [
562
+ {
563
+ name: 'cM1Name2',
564
+ value: 'cM1Value2',
565
+ },
566
+ {
567
+ name: 'cM1Name2',
568
+ value: 'cM1Value2',
569
+ },
570
+ ],
571
+ },
572
+ },
573
+ },
574
+ },
575
+ {
576
+ actions: [
577
+ {
578
+ type: 'rootProperty',
579
+ properties: {
580
+ property: 'data',
581
+ },
582
+ },
583
+ ],
584
+ data: {
585
+ parameterValue: 'llv2',
586
+ },
587
+ },
588
+ ],
589
+ requestOperations: {
590
+ pagination: {
591
+ type: 'offset',
592
+ properties: {
593
+ limitParameter: 'limit100',
594
+ offsetParameter: 'offset100',
595
+ pageSize: 100,
596
+ rootProperty: 'data100',
597
+ type: 'query',
598
+ },
599
+ },
600
+ },
601
+ },
602
+ },
603
+ ];
604
+
605
+ const nodeTypes = Helpers.NodeTypes();
606
+ const node: INode = {
607
+ parameters: {},
608
+ name: 'test',
609
+ type: 'test.set',
610
+ typeVersion: 1,
611
+ position: [0, 0],
612
+ };
613
+
614
+ const mode = 'internal';
615
+ const runIndex = 0;
616
+ const itemIndex = 0;
617
+ const connectionInputData: INodeExecutionData[] = [];
618
+ const runExecutionData: IRunExecutionData = { resultData: { runData: {} } };
619
+ const additionalData = Helpers.WorkflowExecuteAdditionalData();
620
+ const path = '';
621
+ const nodeType = nodeTypes.getByNameAndVersion(node.type);
622
+
623
+ const workflowData = {
624
+ nodes: [node],
625
+ connections: {},
626
+ };
627
+
628
+ for (const testData of tests) {
629
+ test(testData.description, () => {
630
+ node.parameters = testData.input.nodeParameters;
631
+
632
+ // @ts-ignore
633
+ nodeType.description.properties = [testData.input.nodeTypeProperties];
634
+
635
+ const workflow = new Workflow({
636
+ nodes: workflowData.nodes,
637
+ connections: workflowData.connections,
638
+ active: false,
639
+ nodeTypes,
640
+ });
641
+
642
+ const routingNode = new RoutingNode(
643
+ workflow,
644
+ node,
645
+ connectionInputData,
646
+ runExecutionData ?? null,
647
+ additionalData,
648
+ mode,
649
+ );
650
+
651
+ const executeSingleFunctions = Helpers.getExecuteSingleFunctions(
652
+ workflow,
653
+ runExecutionData,
654
+ runIndex,
655
+ connectionInputData,
656
+ {},
657
+ node,
658
+ itemIndex,
659
+ additionalData,
660
+ mode,
661
+ );
662
+
663
+ const result = routingNode.getRequestOptionsFromParameters(
664
+ executeSingleFunctions,
665
+ testData.input.nodeTypeProperties,
666
+ itemIndex,
667
+ runIndex,
668
+ path,
669
+ {},
670
+ );
671
+
672
+ expect(result).toEqual(testData.output);
673
+ });
674
+ }
675
+ });
676
+
677
+ describe('runNode', () => {
678
+ const tests: Array<{
679
+ description: string;
680
+ input: {
681
+ nodeType: {
682
+ properties?: INodeProperties[];
683
+ credentials?: INodeCredentialDescription[];
684
+ requestDefaults?: IHttpRequestOptions;
685
+ requestOperations?: IN8nRequestOperations;
686
+ };
687
+ node: {
688
+ parameters: INodeParameters;
689
+ };
690
+ };
691
+ output: INodeExecutionData[][] | undefined;
692
+ }> = [
693
+ {
694
+ description: 'single parameter, only send defined, fixed value, using requestDefaults',
695
+ input: {
696
+ nodeType: {
697
+ requestDefaults: {
698
+ baseURL: 'http://127.0.0.1:5678',
699
+ url: '/test-url',
700
+ },
701
+ properties: [
702
+ {
703
+ displayName: 'Email',
704
+ name: 'email',
705
+ type: 'string',
706
+ routing: {
707
+ send: {
708
+ property: 'toEmail',
709
+ type: 'body',
710
+ value: 'fixedValue',
711
+ },
712
+ },
713
+ default: '',
714
+ },
715
+ ],
716
+ },
717
+ node: {
718
+ parameters: {},
719
+ },
720
+ },
721
+ output: [
722
+ [
723
+ {
724
+ json: {
725
+ headers: {},
726
+ statusCode: 200,
727
+ requestOptions: {
728
+ url: '/test-url',
729
+ qs: {},
730
+ body: {
731
+ toEmail: 'fixedValue',
732
+ },
733
+ baseURL: 'http://127.0.0.1:5678',
734
+ returnFullResponse: true,
735
+ },
736
+ },
737
+ },
738
+ ],
739
+ ],
740
+ },
741
+ {
742
+ description: 'single parameter, only send defined, fixed value, using requestDefaults',
743
+ input: {
744
+ nodeType: {
745
+ requestDefaults: {
746
+ baseURL: 'http://127.0.0.1:5678',
747
+ url: '/test-url',
748
+ },
749
+ properties: [
750
+ {
751
+ displayName: 'Email',
752
+ name: 'email',
753
+ type: 'string',
754
+ routing: {
755
+ send: {
756
+ property: 'toEmail',
757
+ type: 'body',
758
+ value: 'fixedValue',
759
+ },
760
+ },
761
+ default: '',
762
+ },
763
+ ],
764
+ },
765
+ node: {
766
+ parameters: {},
767
+ },
768
+ },
769
+ output: [
770
+ [
771
+ {
772
+ json: {
773
+ headers: {},
774
+ statusCode: 200,
775
+ requestOptions: {
776
+ url: '/test-url',
777
+ qs: {},
778
+ body: {
779
+ toEmail: 'fixedValue',
780
+ },
781
+ baseURL: 'http://127.0.0.1:5678',
782
+ returnFullResponse: true,
783
+ },
784
+ },
785
+ },
786
+ ],
787
+ ],
788
+ },
789
+ {
790
+ description:
791
+ 'single parameter, only send defined, using expression, using requestDefaults with overwrite',
792
+ input: {
793
+ node: {
794
+ parameters: {
795
+ email: 'test@test.com',
796
+ },
797
+ },
798
+ nodeType: {
799
+ requestDefaults: {
800
+ baseURL: 'http://127.0.0.1:5678',
801
+ url: '/test-url',
802
+ },
803
+ properties: [
804
+ {
805
+ displayName: 'Email',
806
+ name: 'email',
807
+ type: 'string',
808
+ routing: {
809
+ send: {
810
+ property: 'toEmail',
811
+ type: 'body',
812
+ value: '={{$value.toUpperCase()}}',
813
+ },
814
+ request: {
815
+ url: '/overwritten',
816
+ },
817
+ },
818
+ default: '',
819
+ },
820
+ ],
821
+ },
822
+ },
823
+ output: [
824
+ [
825
+ {
826
+ json: {
827
+ headers: {},
828
+ statusCode: 200,
829
+ requestOptions: {
830
+ url: '/overwritten',
831
+ qs: {},
832
+ body: {
833
+ toEmail: 'TEST@TEST.COM',
834
+ },
835
+ baseURL: 'http://127.0.0.1:5678',
836
+ returnFullResponse: true,
837
+ },
838
+ },
839
+ },
840
+ ],
841
+ ],
842
+ },
843
+ {
844
+ description:
845
+ 'single parameter, only send defined, using expression, using requestDefaults with overwrite and expressions',
846
+ input: {
847
+ node: {
848
+ parameters: {
849
+ endpoint: 'custom-overwritten',
850
+ },
851
+ },
852
+ nodeType: {
853
+ requestDefaults: {
854
+ baseURL: 'http://127.0.0.1:5678',
855
+ url: '/test-url',
856
+ },
857
+ properties: [
858
+ {
859
+ displayName: 'Endpoint',
860
+ name: 'endpoint',
861
+ type: 'string',
862
+ routing: {
863
+ send: {
864
+ property: '={{"theProperty"}}',
865
+ type: 'body',
866
+ value: '={{$value}}',
867
+ },
868
+ request: {
869
+ url: '=/{{$value}}',
870
+ },
871
+ },
872
+ default: '',
873
+ },
874
+ ],
875
+ },
876
+ },
877
+ output: [
878
+ [
879
+ {
880
+ json: {
881
+ headers: {},
882
+ statusCode: 200,
883
+ requestOptions: {
884
+ url: '/custom-overwritten',
885
+ qs: {},
886
+ body: {
887
+ theProperty: 'custom-overwritten',
888
+ },
889
+ baseURL: 'http://127.0.0.1:5678',
890
+ returnFullResponse: true,
891
+ },
892
+ },
893
+ },
894
+ ],
895
+ ],
896
+ },
897
+ {
898
+ description: 'single parameter, send and operations defined, fixed value with pagination',
899
+ input: {
900
+ node: {
901
+ parameters: {},
902
+ },
903
+ nodeType: {
904
+ properties: [
905
+ {
906
+ displayName: 'Email',
907
+ name: 'email',
908
+ type: 'string',
909
+ routing: {
910
+ send: {
911
+ property: 'toEmail',
912
+ type: 'body',
913
+ value: 'fixedValue',
914
+ paginate: true,
915
+ },
916
+ operations: {
917
+ pagination: {
918
+ type: 'offset',
919
+ properties: {
920
+ limitParameter: 'limit',
921
+ offsetParameter: 'offset',
922
+ pageSize: 10,
923
+ type: 'body',
924
+ },
925
+ },
926
+ },
927
+ },
928
+ default: '',
929
+ },
930
+ ],
931
+ },
932
+ },
933
+ output: [
934
+ [
935
+ {
936
+ json: {
937
+ headers: {},
938
+ statusCode: 200,
939
+ requestOptions: {
940
+ qs: {},
941
+ body: {
942
+ toEmail: 'fixedValue',
943
+ limit: 10,
944
+ offset: 10,
945
+ },
946
+ returnFullResponse: true,
947
+ },
948
+ },
949
+ },
950
+ ],
951
+ ],
952
+ },
953
+ {
954
+ description: 'mutliple parameters, complex example with everything',
955
+ input: {
956
+ node: {
957
+ parameters: {
958
+ multipleFields: {
959
+ value1: 'v1',
960
+ value2: 'v2',
961
+ value3: 'v3',
962
+ value4: 4,
963
+ lowerLevel: {
964
+ lowLevelValue1: 1,
965
+ lowLevelValue2: 'llv2',
966
+ },
967
+ customPropertiesSingle1: {
968
+ property: {
969
+ name: 'cSName1',
970
+ value: 'cSValue1',
971
+ },
972
+ },
973
+ customPropertiesMulti: {
974
+ property0: [
975
+ {
976
+ name: 'cM0Name1',
977
+ value: 'cM0Value1',
978
+ },
979
+ {
980
+ name: 'cM0Name2',
981
+ value: 'cM0Value2',
982
+ },
983
+ ],
984
+ property1: [
985
+ {
986
+ name: 'cM1Name2',
987
+ value: 'cM1Value2',
988
+ },
989
+ {
990
+ name: 'cM1Name2',
991
+ value: 'cM1Value2',
992
+ },
993
+ ],
994
+ },
995
+ },
996
+ },
997
+ },
998
+ nodeType: {
999
+ properties: [
1000
+ {
1001
+ displayName: 'Multiple Fields',
1002
+ name: 'multipleFields',
1003
+ type: 'collection',
1004
+ placeholder: 'Add Field',
1005
+ routing: {
1006
+ request: {
1007
+ method: 'GET',
1008
+ url: '/destination1',
1009
+ },
1010
+ operations: {
1011
+ pagination: {
1012
+ type: 'offset',
1013
+ properties: {
1014
+ limitParameter: 'limit1',
1015
+ offsetParameter: 'offset1',
1016
+ pageSize: 1,
1017
+ rootProperty: 'data1',
1018
+ type: 'body',
1019
+ },
1020
+ },
1021
+ },
1022
+ output: {
1023
+ maxResults: 10,
1024
+ postReceive: [postReceiveFunction1],
1025
+ },
1026
+ },
1027
+ default: {},
1028
+ options: [
1029
+ {
1030
+ displayName: 'Value 1',
1031
+ name: 'value1',
1032
+ type: 'string',
1033
+ routing: {
1034
+ send: {
1035
+ property: 'value1',
1036
+ type: 'body',
1037
+ },
1038
+ },
1039
+ default: '',
1040
+ },
1041
+ {
1042
+ displayName: 'Value 2',
1043
+ name: 'value2',
1044
+ type: 'string',
1045
+ routing: {
1046
+ send: {
1047
+ property: 'topLevel.value2',
1048
+ propertyInDotNotation: false,
1049
+ type: 'body',
1050
+ preSend: [preSendFunction1],
1051
+ },
1052
+ },
1053
+ default: '',
1054
+ },
1055
+ {
1056
+ displayName: 'Value 3',
1057
+ name: 'value3',
1058
+ type: 'string',
1059
+ routing: {
1060
+ send: {
1061
+ property: 'lowerLevel.value3',
1062
+ type: 'body',
1063
+ },
1064
+ },
1065
+ default: '',
1066
+ },
1067
+ {
1068
+ displayName: 'Value 4',
1069
+ name: 'value4',
1070
+ type: 'number',
1071
+ default: 0,
1072
+ routing: {
1073
+ send: {
1074
+ property: 'value4',
1075
+ type: 'query',
1076
+ },
1077
+ output: {
1078
+ maxResults: '={{$value}}',
1079
+ },
1080
+ operations: {
1081
+ pagination: {
1082
+ type: 'offset',
1083
+ properties: {
1084
+ limitParameter: 'limit100',
1085
+ offsetParameter: 'offset100',
1086
+ pageSize: 100,
1087
+ rootProperty: 'data100',
1088
+ type: 'query',
1089
+ },
1090
+ },
1091
+ },
1092
+ },
1093
+ },
1094
+ // This one should not be included
1095
+ {
1096
+ displayName: 'Value 5',
1097
+ name: 'value5',
1098
+ type: 'number',
1099
+ displayOptions: {
1100
+ show: {
1101
+ value4: [1],
1102
+ },
1103
+ },
1104
+ default: 5,
1105
+ routing: {
1106
+ send: {
1107
+ property: 'value5',
1108
+ type: 'query',
1109
+ },
1110
+ operations: {
1111
+ pagination: {
1112
+ type: 'offset',
1113
+ properties: {
1114
+ limitParameter: 'limit10',
1115
+ offsetParameter: 'offset10',
1116
+ pageSize: 10,
1117
+ rootProperty: 'data10',
1118
+ type: 'body',
1119
+ },
1120
+ },
1121
+ },
1122
+ },
1123
+ },
1124
+ {
1125
+ displayName: 'Lower Level',
1126
+ name: 'lowerLevel',
1127
+ type: 'collection',
1128
+ placeholder: 'Add Field',
1129
+ default: {},
1130
+ options: [
1131
+ {
1132
+ displayName: 'Low Level Value1',
1133
+ name: 'lowLevelValue1',
1134
+ type: 'number',
1135
+ default: 0,
1136
+ routing: {
1137
+ send: {
1138
+ property: 'llvalue1',
1139
+ type: 'query',
1140
+ },
1141
+ },
1142
+ },
1143
+ {
1144
+ displayName: 'Low Level Value2',
1145
+ name: 'lowLevelValue2',
1146
+ type: 'string',
1147
+ default: '',
1148
+ routing: {
1149
+ send: {
1150
+ property: 'llvalue2',
1151
+ type: 'query',
1152
+ preSend: [preSendFunction1],
1153
+ },
1154
+ output: {
1155
+ postReceive: [
1156
+ {
1157
+ type: 'rootProperty',
1158
+ properties: {
1159
+ property: 'requestOptions',
1160
+ },
1161
+ },
1162
+ ],
1163
+ },
1164
+ },
1165
+ },
1166
+ ],
1167
+ },
1168
+ // Test fixed collection1: multipleValues=false
1169
+ {
1170
+ displayName: 'Custom Properties1 (single)',
1171
+ name: 'customPropertiesSingle1',
1172
+ placeholder: 'Add Custom Property',
1173
+ type: 'fixedCollection',
1174
+ default: {},
1175
+ options: [
1176
+ {
1177
+ name: 'property',
1178
+ displayName: 'Property',
1179
+ values: [
1180
+ // To set: { single-customValues: { name: 'name', value: 'value'} }
1181
+ {
1182
+ displayName: 'Property Name',
1183
+ name: 'name',
1184
+ type: 'string',
1185
+ default: '',
1186
+ routing: {
1187
+ request: {
1188
+ method: 'POST',
1189
+ url: '=/{{$value}}',
1190
+ },
1191
+ send: {
1192
+ property: 'single-customValues.name',
1193
+ },
1194
+ },
1195
+ },
1196
+ {
1197
+ displayName: 'Property Value',
1198
+ name: 'value',
1199
+ type: 'string',
1200
+ default: '',
1201
+ routing: {
1202
+ send: {
1203
+ property: 'single-customValues.value',
1204
+ },
1205
+ },
1206
+ },
1207
+ ],
1208
+ },
1209
+ ],
1210
+ },
1211
+ // Test fixed collection: multipleValues=true
1212
+ {
1213
+ displayName: 'Custom Properties (multi)',
1214
+ name: 'customPropertiesMulti',
1215
+ placeholder: 'Add Custom Property',
1216
+ type: 'fixedCollection',
1217
+ typeOptions: {
1218
+ multipleValues: true,
1219
+ },
1220
+ default: {},
1221
+ options: [
1222
+ {
1223
+ name: 'property0',
1224
+ displayName: 'Property0',
1225
+ values: [
1226
+ // To set: { name0: 'value0', name1: 'value1' }
1227
+ {
1228
+ displayName: 'Property Name',
1229
+ name: 'name',
1230
+ type: 'string',
1231
+ default: '',
1232
+ description: 'Name of the property to set.',
1233
+ },
1234
+ {
1235
+ displayName: 'Property Value',
1236
+ name: 'value',
1237
+ type: 'string',
1238
+ default: '',
1239
+ routing: {
1240
+ send: {
1241
+ property: '=customMulti0.{{$parent.name}}',
1242
+ type: 'body',
1243
+ },
1244
+ },
1245
+ description: 'Value of the property to set.',
1246
+ },
1247
+ ],
1248
+ },
1249
+ {
1250
+ name: 'property1',
1251
+ displayName: 'Property1',
1252
+ values: [
1253
+ // To set: { customValues: [ { name: 'name0', value: 'value0'}, { name: 'name1', value: 'value1'} ]}
1254
+ {
1255
+ displayName: 'Property Name',
1256
+ name: 'name',
1257
+ type: 'string',
1258
+ default: '',
1259
+ routing: {
1260
+ send: {
1261
+ property: '=customMulti1[{{$index}}].name',
1262
+ type: 'body',
1263
+ },
1264
+ },
1265
+ },
1266
+ {
1267
+ displayName: 'Property Value',
1268
+ name: 'value',
1269
+ type: 'string',
1270
+ default: '',
1271
+ routing: {
1272
+ send: {
1273
+ property: '=customMulti1[{{$index}}].value',
1274
+ type: 'body',
1275
+ },
1276
+ },
1277
+ },
1278
+ ],
1279
+ },
1280
+ ],
1281
+ },
1282
+ ],
1283
+ },
1284
+ ],
1285
+ },
1286
+ },
1287
+ output: [
1288
+ [
1289
+ {
1290
+ json: {
1291
+ url: '/cSName1',
1292
+ qs: {
1293
+ value4: 4,
1294
+ llvalue1: 1,
1295
+ llvalue2: 'llv2',
1296
+ 'single-customValues': {
1297
+ name: 'cSName1',
1298
+ value: 'cSValue1',
1299
+ },
1300
+ },
1301
+ body: {
1302
+ value1: 'v1',
1303
+ 'topLevel.value2': 'v2',
1304
+ lowerLevel: {
1305
+ value3: 'v3',
1306
+ },
1307
+ customMulti0: {
1308
+ cM0Name1: 'cM0Value1',
1309
+ cM0Name2: 'cM0Value2',
1310
+ },
1311
+ customMulti1: [
1312
+ {
1313
+ name: 'cM1Name2',
1314
+ value: 'cM1Value2',
1315
+ },
1316
+ {
1317
+ name: 'cM1Name2',
1318
+ value: 'cM1Value2',
1319
+ },
1320
+ ],
1321
+ },
1322
+ method: 'POST',
1323
+ headers: {
1324
+ addedIn: 'preSendFunction1',
1325
+ },
1326
+ returnFullResponse: true,
1327
+ },
1328
+ },
1329
+ ],
1330
+ ],
1331
+ },
1332
+ {
1333
+ description: 'single parameter, postReceive: set',
1334
+ input: {
1335
+ nodeType: {
1336
+ requestDefaults: {
1337
+ baseURL: 'http://127.0.0.1:5678',
1338
+ url: '/test-url',
1339
+ },
1340
+ properties: [
1341
+ {
1342
+ displayName: 'JSON Data',
1343
+ name: 'jsonData',
1344
+ type: 'string',
1345
+ routing: {
1346
+ send: {
1347
+ property: 'jsonData',
1348
+ type: 'body',
1349
+ },
1350
+ output: {
1351
+ postReceive: [
1352
+ {
1353
+ type: 'set',
1354
+ properties: {
1355
+ value: '={{ { "value": $value, "response": $response } }}',
1356
+ },
1357
+ },
1358
+ ],
1359
+ },
1360
+ },
1361
+ default: '',
1362
+ },
1363
+ ],
1364
+ },
1365
+ node: {
1366
+ parameters: {
1367
+ jsonData: {
1368
+ root: [
1369
+ {
1370
+ name: 'Jim',
1371
+ age: 34,
1372
+ },
1373
+ {
1374
+ name: 'James',
1375
+ age: 44,
1376
+ },
1377
+ ],
1378
+ },
1379
+ },
1380
+ },
1381
+ },
1382
+ output: [
1383
+ [
1384
+ {
1385
+ json: {
1386
+ value: {
1387
+ root: [
1388
+ {
1389
+ name: 'Jim',
1390
+ age: 34,
1391
+ },
1392
+ {
1393
+ name: 'James',
1394
+ age: 44,
1395
+ },
1396
+ ],
1397
+ },
1398
+ response: {
1399
+ body: {
1400
+ headers: {},
1401
+ statusCode: 200,
1402
+ requestOptions: {
1403
+ qs: {},
1404
+ body: {
1405
+ jsonData: {
1406
+ root: [
1407
+ {
1408
+ name: 'Jim',
1409
+ age: 34,
1410
+ },
1411
+ {
1412
+ name: 'James',
1413
+ age: 44,
1414
+ },
1415
+ ],
1416
+ },
1417
+ },
1418
+ baseURL: 'http://127.0.0.1:5678',
1419
+ url: '/test-url',
1420
+ returnFullResponse: true,
1421
+ },
1422
+ },
1423
+ },
1424
+ },
1425
+ },
1426
+ ],
1427
+ ],
1428
+ },
1429
+ {
1430
+ description: 'single parameter, postReceive: rootProperty',
1431
+ input: {
1432
+ nodeType: {
1433
+ requestDefaults: {
1434
+ baseURL: 'http://127.0.0.1:5678',
1435
+ url: '/test-url',
1436
+ },
1437
+ properties: [
1438
+ {
1439
+ displayName: 'JSON Data',
1440
+ name: 'jsonData',
1441
+ type: 'string',
1442
+ routing: {
1443
+ send: {
1444
+ property: 'jsonData',
1445
+ type: 'body',
1446
+ },
1447
+ output: {
1448
+ postReceive: [
1449
+ {
1450
+ type: 'rootProperty',
1451
+ properties: {
1452
+ property: 'requestOptions',
1453
+ },
1454
+ },
1455
+ {
1456
+ type: 'rootProperty',
1457
+ properties: {
1458
+ property: 'body.jsonData.root',
1459
+ },
1460
+ },
1461
+ ],
1462
+ },
1463
+ },
1464
+ default: '',
1465
+ },
1466
+ ],
1467
+ },
1468
+ node: {
1469
+ parameters: {
1470
+ jsonData: {
1471
+ root: [
1472
+ {
1473
+ name: 'Jim',
1474
+ age: 34,
1475
+ },
1476
+ {
1477
+ name: 'James',
1478
+ age: 44,
1479
+ },
1480
+ ],
1481
+ },
1482
+ },
1483
+ },
1484
+ },
1485
+ output: [
1486
+ [
1487
+ {
1488
+ json: {
1489
+ name: 'Jim',
1490
+ age: 34,
1491
+ },
1492
+ },
1493
+ {
1494
+ json: {
1495
+ name: 'James',
1496
+ age: 44,
1497
+ },
1498
+ },
1499
+ ],
1500
+ ],
1501
+ },
1502
+ {
1503
+ description: 'single parameter, mutliple postReceive: rootProperty, setKeyValue, sort',
1504
+ input: {
1505
+ nodeType: {
1506
+ requestDefaults: {
1507
+ baseURL: 'http://127.0.0.1:5678',
1508
+ url: '/test-url',
1509
+ },
1510
+ properties: [
1511
+ {
1512
+ displayName: 'JSON Data',
1513
+ name: 'jsonData',
1514
+ type: 'string',
1515
+ routing: {
1516
+ send: {
1517
+ property: 'jsonData',
1518
+ type: 'body',
1519
+ },
1520
+ output: {
1521
+ postReceive: [
1522
+ {
1523
+ type: 'rootProperty',
1524
+ properties: {
1525
+ property: 'requestOptions.body.jsonData.root',
1526
+ },
1527
+ },
1528
+ {
1529
+ type: 'setKeyValue',
1530
+ properties: {
1531
+ display1: '={{$responseItem.name}} ({{$responseItem.age}})',
1532
+ display2: '={{$responseItem.name}} is {{$responseItem.age}}',
1533
+ },
1534
+ },
1535
+ {
1536
+ type: 'sort',
1537
+ properties: {
1538
+ key: 'display1',
1539
+ },
1540
+ },
1541
+ ],
1542
+ },
1543
+ },
1544
+ default: '',
1545
+ },
1546
+ ],
1547
+ },
1548
+ node: {
1549
+ parameters: {
1550
+ jsonData: {
1551
+ root: [
1552
+ {
1553
+ name: 'Jim',
1554
+ age: 34,
1555
+ },
1556
+ {
1557
+ name: 'James',
1558
+ age: 44,
1559
+ },
1560
+ ],
1561
+ },
1562
+ },
1563
+ },
1564
+ },
1565
+ output: [
1566
+ [
1567
+ {
1568
+ json: {
1569
+ display1: 'James (44)',
1570
+ display2: 'James is 44',
1571
+ },
1572
+ },
1573
+ {
1574
+ json: {
1575
+ display1: 'Jim (34)',
1576
+ display2: 'Jim is 34',
1577
+ },
1578
+ },
1579
+ ],
1580
+ ],
1581
+ },
1582
+ ];
1583
+
1584
+ const nodeTypes = Helpers.NodeTypes();
1585
+ const baseNode: INode = {
1586
+ parameters: {},
1587
+ name: 'test',
1588
+ type: 'test.set',
1589
+ typeVersion: 1,
1590
+ position: [0, 0],
1591
+ };
1592
+
1593
+ const mode = 'internal';
1594
+ const runIndex = 0;
1595
+ const itemIndex = 0;
1596
+ const connectionInputData: INodeExecutionData[] = [];
1597
+ const runExecutionData: IRunExecutionData = { resultData: { runData: {} } };
1598
+ const additionalData = Helpers.WorkflowExecuteAdditionalData();
1599
+ const nodeType = nodeTypes.getByNameAndVersion(baseNode.type);
1600
+
1601
+ const inputData: ITaskDataConnections = {
1602
+ main: [
1603
+ [
1604
+ {
1605
+ json: {},
1606
+ },
1607
+ ],
1608
+ ],
1609
+ };
1610
+
1611
+ for (const testData of tests) {
1612
+ test(testData.description, async () => {
1613
+ const node: INode = { ...baseNode, ...testData.input.node };
1614
+
1615
+ const workflowData = {
1616
+ nodes: [node],
1617
+ connections: {},
1618
+ };
1619
+
1620
+ // @ts-ignore
1621
+ nodeType.description = { ...testData.input.nodeType };
1622
+
1623
+ const workflow = new Workflow({
1624
+ nodes: workflowData.nodes,
1625
+ connections: workflowData.connections,
1626
+ active: false,
1627
+ nodeTypes,
1628
+ });
1629
+
1630
+ const routingNode = new RoutingNode(
1631
+ workflow,
1632
+ node,
1633
+ connectionInputData,
1634
+ runExecutionData ?? null,
1635
+ additionalData,
1636
+ mode,
1637
+ );
1638
+
1639
+ // @ts-ignore
1640
+ const nodeExecuteFunctions: INodeExecuteFunctions = {
1641
+ getExecuteFunctions: () => {
1642
+ return Helpers.getExecuteFunctions(
1643
+ workflow,
1644
+ runExecutionData,
1645
+ runIndex,
1646
+ connectionInputData,
1647
+ {},
1648
+ node,
1649
+ itemIndex,
1650
+ additionalData,
1651
+ mode,
1652
+ );
1653
+ },
1654
+ getExecuteSingleFunctions: () => {
1655
+ return Helpers.getExecuteSingleFunctions(
1656
+ workflow,
1657
+ runExecutionData,
1658
+ runIndex,
1659
+ connectionInputData,
1660
+ {},
1661
+ node,
1662
+ itemIndex,
1663
+ additionalData,
1664
+ mode,
1665
+ );
1666
+ },
1667
+ };
1668
+
1669
+ const result = await routingNode.runNode(
1670
+ inputData,
1671
+ runIndex,
1672
+ nodeType,
1673
+ nodeExecuteFunctions,
1674
+ );
1675
+
1676
+ expect(result).toEqual(testData.output);
1677
+ });
1678
+ }
1679
+ });
1680
+ });