mirror of
https://github.com/n8n-io/n8n.git
synced 2025-01-11 12:57:29 -08:00
⚡ Tolerate missing json key in function node output (#2885)
* 🔨 implemented Tolerate missing json key in function node output * 🔨 clean up * Small change to code * ⚡ tolerate returning object * ⚡ Rename function Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
parent
af09bf8e6a
commit
62e05cf0b3
|
@ -62,6 +62,7 @@ export interface IExecuteFunctions extends IExecuteFunctionsBase {
|
||||||
requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions,
|
requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions,
|
||||||
): Promise<any>; // tslint:disable-line:no-any
|
): Promise<any>; // tslint:disable-line:no-any
|
||||||
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
|
||||||
|
normalizeItemsInArray(items: INodeExecutionData[]): INodeExecutionData[];
|
||||||
httpRequestWithAuthentication(
|
httpRequestWithAuthentication(
|
||||||
this: IAllExecuteFunctions,
|
this: IAllExecuteFunctions,
|
||||||
credentialsType: string,
|
credentialsType: string,
|
||||||
|
|
|
@ -1132,6 +1132,51 @@ export function returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExe
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically put the objects under a 'json' key and don't error,
|
||||||
|
* if some objects contain json/binary keys and others don't, throws error 'Inconsistent item format'
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @param {INodeExecutionData | INodeExecutionData[]} executionData
|
||||||
|
* @returns {INodeExecutionData[]}
|
||||||
|
*/
|
||||||
|
export function normalizeItems(
|
||||||
|
executionData: INodeExecutionData | INodeExecutionData[],
|
||||||
|
): INodeExecutionData[] {
|
||||||
|
if (typeof executionData === 'object' && !Array.isArray(executionData))
|
||||||
|
executionData = [{ json: executionData as IDataObject }];
|
||||||
|
if (executionData.every((item) => typeof item === 'object' && 'json' in item))
|
||||||
|
return executionData;
|
||||||
|
|
||||||
|
if (executionData.some((item) => typeof item === 'object' && 'json' in item)) {
|
||||||
|
throw new Error('Inconsistent item format');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (executionData.every((item) => typeof item === 'object' && 'binary' in item)) {
|
||||||
|
const normalizedItems: INodeExecutionData[] = [];
|
||||||
|
executionData.forEach((item) => {
|
||||||
|
const json = Object.keys(item).reduce((acc, key) => {
|
||||||
|
if (key === 'binary') return acc;
|
||||||
|
return { ...acc, [key]: item[key] };
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
normalizedItems.push({
|
||||||
|
json,
|
||||||
|
binary: item.binary,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
return normalizedItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (executionData.some((item) => typeof item === 'object' && 'binary' in item)) {
|
||||||
|
throw new Error('Inconsistent item format');
|
||||||
|
}
|
||||||
|
|
||||||
|
return executionData.map((item) => {
|
||||||
|
return { json: item };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Move up later
|
// TODO: Move up later
|
||||||
export async function requestWithAuthentication(
|
export async function requestWithAuthentication(
|
||||||
this: IAllExecuteFunctions,
|
this: IAllExecuteFunctions,
|
||||||
|
@ -2080,6 +2125,7 @@ export function getExecuteFunctions(
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
returnJsonArray,
|
returnJsonArray,
|
||||||
|
normalizeItems,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
})(workflow, runExecutionData, connectionInputData, inputData, node);
|
})(workflow, runExecutionData, connectionInputData, inputData, node);
|
||||||
|
|
|
@ -119,6 +119,8 @@ return items;`,
|
||||||
try {
|
try {
|
||||||
// Execute the function code
|
// Execute the function code
|
||||||
items = (await vm.run(`module.exports = async function() {${functionCode}\n}()`, __dirname));
|
items = (await vm.run(`module.exports = async function() {${functionCode}\n}()`, __dirname));
|
||||||
|
items = this.helpers.normalizeItems(items);
|
||||||
|
|
||||||
// Do very basic validation of the data
|
// Do very basic validation of the data
|
||||||
if (items === undefined) {
|
if (items === undefined) {
|
||||||
throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!');
|
throw new NodeOperationError(this.getNode(), 'No data got returned. Always return an Array of items!');
|
||||||
|
|
Loading…
Reference in a new issue