-
Notifications
You must be signed in to change notification settings - Fork 8.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(Split In Batches Node): Roll back changes in v1 and create v2 (#5747
- Loading branch information
Showing
6 changed files
with
506 additions
and
159 deletions.
There are no files selected for viewing
181 changes: 23 additions & 158 deletions
181
packages/nodes-base/nodes/SplitInBatches/SplitInBatches.node.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,160 +1,25 @@ | ||
import type { | ||
IExecuteFunctions, | ||
INodeExecutionData, | ||
INodeType, | ||
INodeTypeDescription, | ||
IPairedItemData, | ||
} from 'n8n-workflow'; | ||
import { deepCopy } from 'n8n-workflow'; | ||
|
||
export class SplitInBatches implements INodeType { | ||
description: INodeTypeDescription = { | ||
displayName: 'Split In Batches', | ||
name: 'splitInBatches', | ||
icon: 'fa:th-large', | ||
group: ['organization'], | ||
version: 1, | ||
description: 'Split data into batches and iterate over each batch', | ||
defaults: { | ||
name: 'Split In Batches', | ||
color: '#007755', | ||
}, | ||
inputs: ['main'], | ||
// eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong | ||
outputs: ['main', 'main'], | ||
outputNames: ['loop', 'done'], | ||
properties: [ | ||
{ | ||
displayName: | ||
'You may not need this node — n8n nodes automatically run once for each input item. <a href="https://docs.n8n.io/getting-started/key-concepts/looping.html#using-loops-in-n8n" target="_blank">More info</a>', | ||
name: 'splitInBatchesNotice', | ||
type: 'notice', | ||
default: '', | ||
}, | ||
{ | ||
displayName: 'Batch Size', | ||
name: 'batchSize', | ||
type: 'number', | ||
typeOptions: { | ||
minValue: 1, | ||
}, | ||
default: 10, | ||
description: 'The number of items to return with each call', | ||
}, | ||
{ | ||
displayName: 'Options', | ||
name: 'options', | ||
type: 'collection', | ||
placeholder: 'Add Option', | ||
default: {}, | ||
options: [ | ||
{ | ||
displayName: 'Reset', | ||
name: 'reset', | ||
type: 'boolean', | ||
default: false, | ||
description: | ||
'Whether the node will be reset and so with the current input-data newly initialized', | ||
}, | ||
], | ||
}, | ||
], | ||
}; | ||
|
||
async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][] | null> { | ||
// Get the input data and create a new array so that we can remove | ||
// items without a problem | ||
const items = this.getInputData().slice(); | ||
|
||
const nodeContext = this.getContext('node'); | ||
|
||
const batchSize = this.getNodeParameter('batchSize', 0) as number; | ||
|
||
const returnItems: INodeExecutionData[] = []; | ||
|
||
const options = this.getNodeParameter('options', 0, {}); | ||
|
||
if (nodeContext.items === undefined || options.reset === true) { | ||
// Is the first time the node runs | ||
|
||
const sourceData = this.getInputSourceData(); | ||
|
||
nodeContext.currentRunIndex = 0; | ||
nodeContext.maxRunIndex = Math.ceil(items.length / batchSize); | ||
nodeContext.sourceData = deepCopy(sourceData); | ||
|
||
// Get the items which should be returned | ||
returnItems.push.apply(returnItems, items.splice(0, batchSize)); | ||
|
||
// Save the incoming items to be able to return them for later runs | ||
nodeContext.items = [...items]; | ||
|
||
// Reset processedItems as they get only added starting from the first iteration | ||
nodeContext.processedItems = []; | ||
} else { | ||
// The node has been called before. So return the next batch of items. | ||
nodeContext.currentRunIndex += 1; | ||
returnItems.push.apply( | ||
returnItems, | ||
(nodeContext.items as INodeExecutionData[]).splice(0, batchSize), | ||
); | ||
|
||
const addSourceOverwrite = (pairedItem: IPairedItemData | number): IPairedItemData => { | ||
if (typeof pairedItem === 'number') { | ||
return { | ||
item: pairedItem, | ||
sourceOverwrite: nodeContext.sourceData, | ||
}; | ||
} | ||
|
||
return { | ||
...pairedItem, | ||
sourceOverwrite: nodeContext.sourceData, | ||
}; | ||
}; | ||
|
||
function getPairedItemInformation( | ||
item: INodeExecutionData, | ||
): IPairedItemData | IPairedItemData[] { | ||
if (item.pairedItem === undefined) { | ||
return { | ||
item: 0, | ||
sourceOverwrite: nodeContext.sourceData, | ||
}; | ||
} | ||
|
||
if (Array.isArray(item.pairedItem)) { | ||
return item.pairedItem.map(addSourceOverwrite); | ||
} | ||
|
||
return addSourceOverwrite(item.pairedItem); | ||
} | ||
|
||
const sourceOverwrite = this.getInputSourceData(); | ||
|
||
const newItems = items.map((item, index) => { | ||
return { | ||
...item, | ||
pairedItem: { | ||
sourceOverwrite, | ||
item: index, | ||
}, | ||
}; | ||
}); | ||
|
||
nodeContext.processedItems = [...nodeContext.processedItems, ...newItems]; | ||
|
||
returnItems.map((item) => { | ||
item.pairedItem = getPairedItemInformation(item); | ||
}); | ||
} | ||
|
||
nodeContext.noItemsLeft = nodeContext.items.length === 0; | ||
|
||
if (returnItems.length === 0) { | ||
return [[], nodeContext.processedItems]; | ||
} | ||
|
||
return [returnItems, []]; | ||
import type { INodeTypeBaseDescription, IVersionedNodeType } from 'n8n-workflow'; | ||
import { VersionedNodeType } from 'n8n-workflow'; | ||
|
||
import { SplitInBatchesV1 } from './v1/SplitInBatchesV1.node'; | ||
import { SplitInBatchesV2 } from './v2/SplitInBatchesV2.node'; | ||
|
||
export class SplitInBatches extends VersionedNodeType { | ||
constructor() { | ||
const baseDescription: INodeTypeBaseDescription = { | ||
displayName: 'Split In Batches', | ||
name: 'splitInBatches', | ||
icon: 'fa:th-large', | ||
group: ['organization'], | ||
description: 'Split data into batches and iterate over each batch', | ||
defaultVersion: 2, | ||
}; | ||
|
||
const nodeVersions: IVersionedNodeType['nodeVersions'] = { | ||
1: new SplitInBatchesV1(), | ||
2: new SplitInBatchesV2(), | ||
}; | ||
|
||
super(nodeVersions, baseDescription); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
178 changes: 178 additions & 0 deletions
178
packages/nodes-base/nodes/SplitInBatches/test/SplitInBatches.workflow_v2.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
{ | ||
"name": "Split in Batches Test", | ||
"nodes": [ | ||
{ | ||
"parameters": {}, | ||
"id": "86b8149f-b0a0-489c-bb62-e59142988996", | ||
"name": "When clicking \"Execute Workflow\"", | ||
"type": "n8n-nodes-base.manualTrigger", | ||
"typeVersion": 1, | ||
"position": [400, 220] | ||
}, | ||
{ | ||
"parameters": { | ||
"batchSize": 1, | ||
"options": {} | ||
}, | ||
"id": "30c5546e-bdcc-44ff-bfca-89c5fb97b678", | ||
"name": "Split In Batches", | ||
"type": "n8n-nodes-base.splitInBatches", | ||
"typeVersion": 2, | ||
"position": [1100, 220] | ||
}, | ||
{ | ||
"parameters": { | ||
"values": { | ||
"string": [ | ||
{ | ||
"name": "data[0]", | ||
"value": "n8n" | ||
}, | ||
{ | ||
"name": "data[1]", | ||
"value": "test" | ||
} | ||
] | ||
}, | ||
"options": {} | ||
}, | ||
"id": "92d386b8-60be-4f8b-801c-b6459ec206f7", | ||
"name": "Set", | ||
"type": "n8n-nodes-base.set", | ||
"typeVersion": 1, | ||
"position": [640, 220] | ||
}, | ||
{ | ||
"parameters": { | ||
"fieldToSplitOut": "data", | ||
"options": {} | ||
}, | ||
"id": "74b7e63e-a9f8-4a82-9e1f-7b2429d9118d", | ||
"name": "Item Lists", | ||
"type": "n8n-nodes-base.itemLists", | ||
"typeVersion": 1, | ||
"position": [860, 220] | ||
}, | ||
{ | ||
"parameters": { | ||
"conditions": { | ||
"boolean": [ | ||
{ | ||
"value1": "={{ $node[\"Split In Batches\"].context[\"noItemsLeft\"] }}", | ||
"value2": true | ||
} | ||
] | ||
} | ||
}, | ||
"id": "a5f68369-4e70-4f16-b260-3c8b74517993", | ||
"name": "IF", | ||
"type": "n8n-nodes-base.if", | ||
"typeVersion": 1, | ||
"position": [1280, 220] | ||
}, | ||
{ | ||
"parameters": { | ||
"values": { | ||
"string": [ | ||
{ | ||
"name": "maxRunIndex", | ||
"value": "={{ $node[\"Split In Batches\"].context[\"maxRunIndex\"] }}" | ||
}, | ||
{ | ||
"value": "={{ $node[\"Split In Batches\"].context[\"currentRunIndex\"] }}" | ||
} | ||
] | ||
}, | ||
"options": {} | ||
}, | ||
"id": "1f44eb0a-5fb7-43a7-8281-84a8a7ec8464", | ||
"name": "Output", | ||
"type": "n8n-nodes-base.set", | ||
"typeVersion": 1, | ||
"position": [1480, 200] | ||
} | ||
], | ||
"pinData": { | ||
"Output": [ | ||
{ | ||
"json": { | ||
"data": "test", | ||
"maxRunIndex": 2, | ||
"propertyName": 1 | ||
} | ||
} | ||
] | ||
}, | ||
"connections": { | ||
"When clicking \"Execute Workflow\"": { | ||
"main": [ | ||
[ | ||
{ | ||
"node": "Set", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
] | ||
] | ||
}, | ||
"Split In Batches": { | ||
"main": [ | ||
[ | ||
{ | ||
"node": "IF", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
] | ||
] | ||
}, | ||
"Set": { | ||
"main": [ | ||
[ | ||
{ | ||
"node": "Item Lists", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
] | ||
] | ||
}, | ||
"Item Lists": { | ||
"main": [ | ||
[ | ||
{ | ||
"node": "Split In Batches", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
] | ||
] | ||
}, | ||
"IF": { | ||
"main": [ | ||
[ | ||
{ | ||
"node": "Output", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
], | ||
[ | ||
{ | ||
"node": "Split In Batches", | ||
"type": "main", | ||
"index": 0 | ||
} | ||
] | ||
] | ||
} | ||
}, | ||
"active": false, | ||
"settings": {}, | ||
"versionId": "de1a454e-43e9-4c2d-b786-18da5d97940f", | ||
"id": "389", | ||
"meta": { | ||
"instanceId": "REMOVED" | ||
}, | ||
"tags": [] | ||
} |
Oops, something went wrong.