fix(core & function nodes): Update function nodes to work with binary-data-mode 'filesystem'. (#3845)

* Initial Fix

* Self-Review #1

* Lint

* Added support for FunctionItem. Minor updates.

* Self-review

* review comments. Added testing.

* Self Review

* Fixed memory handling on data manager use.

* Fixes for unnecessary memory leaks.
This commit is contained in:
Rhys Williams
2022-09-11 16:42:09 +02:00
committed by GitHub
parent b450e977a3
commit f6064ef278
7 changed files with 267 additions and 4 deletions

View File

@@ -1,5 +1,6 @@
import { IExecuteFunctions } from 'n8n-core';
import {
IBinaryKeyData,
IDataObject,
INodeExecutionData,
INodeType,
@@ -61,6 +62,11 @@ return items;`,
// Copy the items as they may get changed in the functions
items = JSON.parse(JSON.stringify(items));
// Assign item indexes
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
items[itemIndex].index = itemIndex;
}
const cleanupData = (inputData: IDataObject): IDataObject => {
Object.keys(inputData).map((key) => {
if (inputData[key] !== null && typeof inputData[key] === 'object') {
@@ -84,6 +90,48 @@ return items;`,
items,
// To be able to access data of other items
$item: (index: number) => this.getWorkflowDataProxy(index),
getBinaryDataAsync: async (item: INodeExecutionData): Promise<IBinaryKeyData | undefined> => {
// Fetch Binary Data, if available. Cannot check item with `if (item?.index)`, as index may be 0.
if (item?.binary && item?.index !== undefined && item?.index !== null) {
for (const binaryPropertyName of Object.keys(item.binary)) {
item.binary[binaryPropertyName].data = (
await this.helpers.getBinaryDataBuffer(item.index, binaryPropertyName)
)?.toString('base64');
}
}
// Return Data
return item.binary;
},
setBinaryDataAsync: async (item: INodeExecutionData, data: IBinaryKeyData) => {
// Ensure item is provided, else return a friendly error.
if (!item) {
throw new NodeOperationError(
this.getNode(),
'No item was provided to setBinaryDataAsync (item: INodeExecutionData, data: IBinaryKeyData).',
);
}
// Ensure data is provided, else return a friendly error.
if (!data) {
throw new NodeOperationError(
this.getNode(),
'No data was provided to setBinaryDataAsync (item: INodeExecutionData, data: IBinaryKeyData).',
);
}
// Set Binary Data
for (const binaryPropertyName of Object.keys(data)) {
const binaryItem = data[binaryPropertyName];
data[binaryPropertyName] = await this.helpers.setBinaryDataBuffer(
binaryItem,
Buffer.from(binaryItem.data, 'base64'),
);
}
// Set Item Reference
item.binary = data;
},
};
// Make it possible to access data via $node, $parameter, ...