diff --git a/packages/core/src/Interfaces.ts b/packages/core/src/Interfaces.ts index 5efda21290..ba2989061e 100644 --- a/packages/core/src/Interfaces.ts +++ b/packages/core/src/Interfaces.ts @@ -14,12 +14,14 @@ import { INodeExecutionData, INodeType, IOAuth2Options, + IPairedItemData, IPollFunctions as IPollFunctionsBase, IPollResponse, ITriggerFunctions as ITriggerFunctionsBase, ITriggerResponse, IWebhookFunctions as IWebhookFunctionsBase, IWorkflowSettings as IWorkflowSettingsWorkflow, + NodeExecutionWithMetadata, } from 'n8n-workflow'; import { OptionsWithUri, OptionsWithUrl } from 'request'; @@ -68,6 +70,10 @@ export interface IExecuteFunctions extends IExecuteFunctionsBase { credentialsType: string, requestOptions: IHttpRequestOptions, ): Promise; + constructExecutionMetaData( + inputData: INodeExecutionData[], + options: { itemData: IPairedItemData | IPairedItemData[] }, + ): NodeExecutionWithMetadata[]; }; } diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index c9645b5939..a4b0fe1a6d 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -59,6 +59,8 @@ import { LoggerProxy as Logger, IExecuteData, OAuth2GrantType, + NodeExecutionWithMetadata, + IPairedItemData, } from 'n8n-workflow'; import { Agent } from 'https'; @@ -1307,13 +1309,31 @@ export function returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExe jsonData = [jsonData]; } - jsonData.forEach((data) => { + jsonData.forEach((data: IDataObject) => { returnData.push({ json: data }); }); return returnData; } +/** + * Takes generic input data and brings it into the new json, pairedItem format n8n uses. + * @export + * @param {(IPairedItemData)} itemData + * @param {(INodeExecutionData[])} inputData + * @returns {(NodeExecutionWithMetadata[])} + */ +export function constructExecutionMetaData( + inputData: INodeExecutionData[], + options: { itemData: IPairedItemData | IPairedItemData[] }, +): NodeExecutionWithMetadata[] { + const { itemData } = options; + return inputData.map((data: INodeExecutionData) => { + const { json, ...rest } = data; + return { json, pairedItem: itemData, ...rest } as NodeExecutionWithMetadata; + }); +} + /** * 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' @@ -2417,6 +2437,7 @@ export function getExecuteFunctions( }, returnJsonArray, normalizeItems, + constructExecutionMetaData, }, }; })(workflow, runExecutionData, connectionInputData, inputData, node); diff --git a/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts b/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts index f557e8f966..d3beb6c7ad 100644 --- a/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts +++ b/packages/nodes-base/nodes/ActiveCampaign/ActiveCampaign.node.ts @@ -309,7 +309,7 @@ export class ActiveCampaign implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let resource: string; let operation: string; @@ -1184,20 +1184,25 @@ export class ActiveCampaign implements INodeType { responseData = { success: true }; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Affinity/Affinity.node.ts b/packages/nodes-base/nodes/Affinity/Affinity.node.ts index 174e65075e..f0afa715a9 100644 --- a/packages/nodes-base/nodes/Affinity/Affinity.node.ts +++ b/packages/nodes-base/nodes/Affinity/Affinity.node.ts @@ -146,7 +146,7 @@ export class Affinity implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -413,19 +413,26 @@ export class Affinity implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Airtable/Airtable.node.ts b/packages/nodes-base/nodes/Airtable/Airtable.node.ts index a8a77fa66d..0dc96e74ca 100644 --- a/packages/nodes-base/nodes/Airtable/Airtable.node.ts +++ b/packages/nodes-base/nodes/Airtable/Airtable.node.ts @@ -418,7 +418,7 @@ export class Airtable implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const operation = this.getNodeParameter('operation', 0) as string; @@ -483,14 +483,17 @@ export class Airtable implements INodeType { body['records'] = rows; responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - - returnData.push(...responseData.records); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.records), + { itemData: { item: i } }, + ); + returnData.push(...executionData); // empty rows rows.length = 0; } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json: { error: error.message }}); continue; } throw error; @@ -524,13 +527,18 @@ export class Airtable implements INodeType { responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - returnData.push(...responseData.records); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.records), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); // empty rows rows.length = 0; } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; @@ -578,9 +586,17 @@ export class Airtable implements INodeType { ); return [data]; } + + // We can return from here + return [ + this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(returnData), + { itemData: { item: 0 } }, + ), + ]; } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); } else { throw error; } @@ -607,10 +623,15 @@ export class Airtable implements INodeType { try { responseData = await apiRequest.call(this, requestMethod, endpoint, body, qs); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; @@ -685,14 +706,19 @@ export class Airtable implements INodeType { responseData = await apiRequest.call(this, requestMethod, endpoint, data, qs); - returnData.push(...responseData.records); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.records), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); // empty rows rows.length = 0; } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; @@ -702,6 +728,6 @@ export class Airtable implements INodeType { throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Asana/Asana.node.ts b/packages/nodes-base/nodes/Asana/Asana.node.ts index a9da13495f..a46bc38cfa 100644 --- a/packages/nodes-base/nodes/Asana/Asana.node.ts +++ b/packages/nodes-base/nodes/Asana/Asana.node.ts @@ -2409,11 +2409,12 @@ export class Asana implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); - } + returnData.push( + ...this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ), + ); } catch (error) { if (this.continueOnFail()) { returnData.push({ error: error.message }); @@ -2423,6 +2424,6 @@ export class Asana implements INodeType { } } - return [this.helpers.returnJsonArray(returnData)]; + return [returnData as INodeExecutionData[]]; } } diff --git a/packages/nodes-base/nodes/Automizy/Automizy.node.ts b/packages/nodes-base/nodes/Automizy/Automizy.node.ts index 22cd8f6009..8e2ada9d20 100644 --- a/packages/nodes-base/nodes/Automizy/Automizy.node.ts +++ b/packages/nodes-base/nodes/Automizy/Automizy.node.ts @@ -7,6 +7,7 @@ import { INodePropertyOptions, INodeType, INodeTypeDescription, + NodeExecutionWithMetadata, } from 'n8n-workflow'; import { automizyApiRequest, automizyApiRequestAllItems } from './GenericFunctions'; @@ -120,7 +121,7 @@ export class Automizy implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -161,6 +162,11 @@ export class Automizy implements INodeType { `/smart-lists/${listId}/contacts`, body, ); + responseData = responseData.contacts; + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'delete') { @@ -169,12 +175,20 @@ export class Automizy implements INodeType { responseData = await automizyApiRequest.call(this, 'DELETE', `/contacts/${contactId}`); responseData = { success: true }; + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'get') { const contactId = this.getNodeParameter('contactId', i) as string; responseData = await automizyApiRequest.call(this, 'GET', `/contacts/${contactId}`); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'getAll') { @@ -211,9 +225,12 @@ export class Automizy implements INodeType { {}, qs, ); - - responseData = responseData.contacts; } + + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'update') { @@ -240,6 +257,10 @@ export class Automizy implements INodeType { } responseData = await automizyApiRequest.call(this, 'PATCH', `/contacts/${email}`, body); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } @@ -252,6 +273,10 @@ export class Automizy implements INodeType { }; responseData = await automizyApiRequest.call(this, 'POST', `/smart-lists`, body); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'delete') { @@ -260,12 +285,20 @@ export class Automizy implements INodeType { responseData = await automizyApiRequest.call(this, 'DELETE', `/smart-lists/${listId}`); responseData = { success: true }; + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'get') { const listId = this.getNodeParameter('listId', i) as string; responseData = await automizyApiRequest.call(this, 'GET', `/smart-lists/${listId}`); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'getAll') { @@ -297,6 +330,11 @@ export class Automizy implements INodeType { responseData = responseData.smartLists; } + + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'update') { @@ -314,14 +352,17 @@ export class Automizy implements INodeType { `/smart-lists/${listId}`, body, ); + + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } - return [this.helpers.returnJsonArray(returnData)]; + + returnData.push(...(responseData as NodeExecutionWithMetadata[])); + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Autopilot/Autopilot.node.ts b/packages/nodes-base/nodes/Autopilot/Autopilot.node.ts index 590d13dea6..c46dbb3da4 100644 --- a/packages/nodes-base/nodes/Autopilot/Autopilot.node.ts +++ b/packages/nodes-base/nodes/Autopilot/Autopilot.node.ts @@ -299,20 +299,24 @@ export class Autopilot implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.toString() }); + const exectionErrorWithMetaData = this.helpers.constructExecutionMetaData( + [{ json: { error: error.message } }], + { itemData: { item: i } }, + ); + responseData.push(...exectionErrorWithMetaData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return [returnData as INodeExecutionData[]]; } } diff --git a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts index b29b48c763..fed8951356 100644 --- a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts +++ b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts @@ -6,7 +6,6 @@ import { INodeExecutionData, INodeType, INodeTypeDescription, - NodeApiError, NodeOperationError, } from 'n8n-workflow'; @@ -472,11 +471,12 @@ export class AwsRekognition implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { returnData.push({ error: error.message }); @@ -485,6 +485,6 @@ export class AwsRekognition implements INodeType { throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return [returnData as INodeExecutionData[]]; } } diff --git a/packages/nodes-base/nodes/Baserow/Baserow.node.ts b/packages/nodes-base/nodes/Baserow/Baserow.node.ts index 50bafa0b8c..21e2808afb 100644 --- a/packages/nodes-base/nodes/Baserow/Baserow.node.ts +++ b/packages/nodes-base/nodes/Baserow/Baserow.node.ts @@ -163,7 +163,7 @@ export class Baserow implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const mapper = new TableFieldMapper(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const operation = this.getNodeParameter('operation', 0) as Operation; const tableId = this.getNodeParameter('tableId', 0) as string; @@ -219,8 +219,11 @@ export class Baserow implements INodeType { )) as Row[]; rows.forEach((row) => mapper.idsToNames(row)); - - returnData.push(...rows); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(rows), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // get @@ -233,8 +236,11 @@ export class Baserow implements INodeType { const row = await baserowApiRequest.call(this, 'GET', endpoint, {}, {}, jwtToken); mapper.idsToNames(row); - - returnData.push(row); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(row), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -276,8 +282,11 @@ export class Baserow implements INodeType { ); mapper.idsToNames(createdRow); - - returnData.push(createdRow); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(createdRow), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -321,8 +330,11 @@ export class Baserow implements INodeType { ); mapper.idsToNames(updatedRow); - - returnData.push(updatedRow); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(updatedRow), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -335,17 +347,21 @@ export class Baserow implements INodeType { const endpoint = `/api/database/rows/table/${tableId}/${rowId}/`; await baserowApiRequest.call(this, 'DELETE', endpoint, {}, {}, jwtToken); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + [{ json: { success: true } }], + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts b/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts index 4b76745800..d872d9846b 100644 --- a/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts +++ b/packages/nodes-base/nodes/Beeminder/Beeminder.node.ts @@ -293,7 +293,7 @@ export class Beeminder implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const timezone = this.getTimezone(); @@ -318,6 +318,11 @@ export class Beeminder implements INodeType { data.timestamp = moment.tz(data.timestamp, timezone).unix(); } results = await createDatapoint.call(this, data); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(results), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'getAll') { const returnAll = this.getNodeParameter('returnAll', i) as boolean; const options = this.getNodeParameter('options', i) as INodeParameters; @@ -331,6 +336,11 @@ export class Beeminder implements INodeType { } results = await getAllDatapoints.call(this, data); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(results), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'update') { const datapointId = this.getNodeParameter('datapointId', i) as string; const options = this.getNodeParameter('updateFields', i) as INodeParameters; @@ -343,6 +353,11 @@ export class Beeminder implements INodeType { data.timestamp = moment.tz(data.timestamp, timezone).unix(); } results = await updateDatapoint.call(this, data); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(results), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'delete') { const datapointId = this.getNodeParameter('datapointId', i) as string; const data: IDataObject = { @@ -350,22 +365,22 @@ export class Beeminder implements INodeType { datapointId, }; results = await deleteDatapoint.call(this, data); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(results), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; } - if (Array.isArray(results)) { - returnData.push.apply(returnData, results as IDataObject[]); - } else { - returnData.push(results as IDataObject); - } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Bitly/Bitly.node.ts b/packages/nodes-base/nodes/Bitly/Bitly.node.ts index 5334954f56..7afc4d12d7 100644 --- a/packages/nodes-base/nodes/Bitly/Bitly.node.ts +++ b/packages/nodes-base/nodes/Bitly/Bitly.node.ts @@ -125,9 +125,8 @@ export class Bitly implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; - const qs: IDataObject = {}; let responseData; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -206,19 +205,20 @@ export class Bitly implements INodeType { responseData = await bitlyApiRequest.call(this, 'GET', `/bitlinks/${linkId}`); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Bitwarden/Bitwarden.node.ts b/packages/nodes-base/nodes/Bitwarden/Bitwarden.node.ts index e98f60f5a1..acb40f39c2 100644 --- a/packages/nodes-base/nodes/Bitwarden/Bitwarden.node.ts +++ b/packages/nodes-base/nodes/Bitwarden/Bitwarden.node.ts @@ -116,7 +116,7 @@ export class Bitwarden implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const token = await getAccessToken.call(this); const bitwardenApiRequest = partialRight(tokenlessBitwardenApiRequest, token); @@ -136,7 +136,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('collectionId', i); const endpoint = `/public/collections/${id}`; responseData = await bitwardenApiRequest.call(this, 'DELETE', endpoint, {}, {}); - responseData = { success: true }; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // collection: get @@ -145,6 +150,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('collectionId', i); const endpoint = `/public/collections/${id}`; responseData = await bitwardenApiRequest.call(this, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // collection: getAll @@ -152,6 +163,12 @@ export class Bitwarden implements INodeType { const endpoint = '/public/collections'; responseData = await handleGetAll.call(this, i, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // collection: update @@ -185,6 +202,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('collectionId', i); const endpoint = `/public/collections/${id}`; responseData = await bitwardenApiRequest.call(this, 'PUT', endpoint, {}, body); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else if (resource === 'event') { // ********************************************************************* @@ -200,6 +223,12 @@ export class Bitwarden implements INodeType { const qs = isEmpty(filters) ? {} : filters; const endpoint = '/public/events'; responseData = await handleGetAll.call(this, i, 'GET', endpoint, qs, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else if (resource === 'group') { // ********************************************************************* @@ -234,6 +263,12 @@ export class Bitwarden implements INodeType { const endpoint = '/public/groups'; responseData = await bitwardenApiRequest.call(this, 'POST', endpoint, {}, body); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // group: delete @@ -242,7 +277,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('groupId', i); const endpoint = `/public/groups/${id}`; responseData = await bitwardenApiRequest.call(this, 'DELETE', endpoint, {}, {}); - responseData = { success: true }; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // group: get @@ -251,6 +291,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('groupId', i); const endpoint = `/public/groups/${id}`; responseData = await bitwardenApiRequest.call(this, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // group: getAll @@ -258,6 +304,12 @@ export class Bitwarden implements INodeType { const endpoint = '/public/groups'; responseData = await handleGetAll.call(this, i, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getMembers') { // ---------------------------------- // group: getMembers @@ -267,6 +319,12 @@ export class Bitwarden implements INodeType { const endpoint = `/public/groups/${id}/member-ids`; responseData = await bitwardenApiRequest.call(this, 'GET', endpoint, {}, {}); responseData = responseData.map((memberId: string) => ({ memberId })); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // group: update @@ -323,6 +381,12 @@ export class Bitwarden implements INodeType { const endpoint = `/public/groups/${groupId}`; responseData = await bitwardenApiRequest.call(this, 'PUT', endpoint, {}, body); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'updateMembers') { // ---------------------------------- // group: updateMembers @@ -337,7 +401,12 @@ export class Bitwarden implements INodeType { const groupId = this.getNodeParameter('groupId', i); const endpoint = `/public/groups/${groupId}/member-ids`; responseData = await bitwardenApiRequest.call(this, 'PUT', endpoint, {}, body); - responseData = { success: true }; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else if (resource === 'member') { // ********************************************************************* @@ -373,6 +442,12 @@ export class Bitwarden implements INodeType { const endpoint = '/public/members/'; responseData = await bitwardenApiRequest.call(this, 'POST', endpoint, {}, body); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // member: delete @@ -382,6 +457,12 @@ export class Bitwarden implements INodeType { const endpoint = `/public/members/${id}`; responseData = await bitwardenApiRequest.call(this, 'DELETE', endpoint, {}, {}); responseData = { success: true }; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // member: get @@ -390,6 +471,12 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('memberId', i); const endpoint = `/public/members/${id}`; responseData = await bitwardenApiRequest.call(this, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // member: getAll @@ -397,6 +484,12 @@ export class Bitwarden implements INodeType { const endpoint = '/public/members'; responseData = await handleGetAll.call(this, i, 'GET', endpoint, {}, {}); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getGroups') { // ---------------------------------- // member: getGroups @@ -406,6 +499,11 @@ export class Bitwarden implements INodeType { const endpoint = `/public/members/${id}/group-ids`; responseData = await bitwardenApiRequest.call(this, 'GET', endpoint, {}, {}); responseData = responseData.map((groupId: string) => ({ groupId })); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // member: update @@ -447,6 +545,11 @@ export class Bitwarden implements INodeType { const id = this.getNodeParameter('memberId', i); const endpoint = `/public/members/${id}`; responseData = await bitwardenApiRequest.call(this, 'PUT', endpoint, {}, body); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'updateGroups') { // ---------------------------------- // member: updateGroups @@ -461,15 +564,15 @@ export class Bitwarden implements INodeType { const memberId = this.getNodeParameter('memberId', i); const endpoint = `/public/members/${memberId}/group-ids`; responseData = await bitwardenApiRequest.call(this, 'PUT', endpoint, {}, body); - responseData = { success: true }; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } - - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Box/Box.node.ts b/packages/nodes-base/nodes/Box/Box.node.ts index 1184412b78..e8cd75520e 100644 --- a/packages/nodes-base/nodes/Box/Box.node.ts +++ b/packages/nodes-base/nodes/Box/Box.node.ts @@ -67,7 +67,7 @@ export class Box implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -104,15 +104,12 @@ export class Box implements INodeType { body, qs, ); - - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/delete-files-id if (operation === 'delete') { const fileId = this.getNodeParameter('fileId', i) as string; responseData = await boxApiRequest.call(this, 'DELETE', `/files/${fileId}`); responseData = { success: true }; - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/get-files-id-content if (operation === 'download') { @@ -150,7 +147,7 @@ export class Box implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -171,7 +168,6 @@ export class Box implements INodeType { qs.fields = additionalFields.fields as string; } responseData = await boxApiRequest.call(this, 'GET', `/files/${fileId}`, {}, qs); - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/get-search/ if (operation === 'search') { @@ -223,7 +219,6 @@ export class Box implements INodeType { responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); responseData = responseData.entries; } - returnData.push.apply(returnData, responseData as IDataObject[]); } // https://developer.box.com/reference/post-collaborations/ if (operation === 'share') { @@ -268,7 +263,6 @@ export class Box implements INodeType { } responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/post-files-content if (operation === 'upload') { @@ -331,8 +325,7 @@ export class Box implements INodeType { 'https://upload.box.com/api/2.0/files/content', { formData: body }, ); - - returnData.push.apply(returnData, responseData.entries as IDataObject[]); + responseData = responseData.entries; } else { const content = this.getNodeParameter('fileContent', i) as string; @@ -364,8 +357,7 @@ export class Box implements INodeType { 'https://upload.box.com/api/2.0/files/content', { formData: body }, ); - - returnData.push.apply(returnData, responseData.entries as IDataObject[]); + responseData = responseData.entries; } } } @@ -407,13 +399,11 @@ export class Box implements INodeType { responseData = await boxApiRequest.call(this, 'DELETE', `/folders/${folderId}`, qs); responseData = { success: true }; - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/get-folders-id/ if (operation === 'get') { const folderId = this.getNodeParameter('folderId', i) as string; responseData = await boxApiRequest.call(this, 'GET', `/folders/${folderId}`, qs); - returnData.push(responseData as IDataObject); } // https://developer.box.com/reference/get-search/ if (operation === 'search') { @@ -465,7 +455,6 @@ export class Box implements INodeType { responseData = await boxApiRequest.call(this, 'GET', `/search`, {}, qs); responseData = responseData.entries; } - returnData.push.apply(returnData, responseData as IDataObject[]); } // https://developer.box.com/reference/post-collaborations/ if (operation === 'share') { @@ -510,7 +499,6 @@ export class Box implements INodeType { } responseData = await boxApiRequest.call(this, 'POST', `/collaborations`, body, qs); - returnData.push(responseData as IDataObject); } //https://developer.box.com/guides/folders/single/move/ if (operation === 'update') { @@ -538,22 +526,31 @@ export class Box implements INodeType { } responseData = await boxApiRequest.call(this, 'PUT', `/folders/${folderId}`, body, qs); - returnData.push(responseData as IDataObject); } } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } + if (resource === 'file' && operation === 'download') { // For file downloads the files get attached to the existing items return this.prepareOutputData(items); } else { - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts b/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts index e3f66a8e15..dcd932bb8b 100644 --- a/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts +++ b/packages/nodes-base/nodes/Brandfetch/Brandfetch.node.ts @@ -146,7 +146,7 @@ export class Brandfetch implements INodeType { const length = items.length; const operation = this.getNodeParameter('operation', 0) as string; - const responseData = []; + const responseData: INodeExecutionData[] = []; for (let i = 0; i < length; i++) { try { if (operation === 'logo') { @@ -173,7 +173,7 @@ export class Brandfetch implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } newItem.json = response.response; @@ -205,7 +205,11 @@ export class Brandfetch implements INodeType { delete items[i].binary; } } else { - responseData.push(response.response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response.response), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } } if (operation === 'color') { @@ -216,7 +220,11 @@ export class Brandfetch implements INodeType { }; const response = await brandfetchApiRequest.call(this, 'POST', `/color`, body); - responseData.push(response.response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } if (operation === 'font') { const domain = this.getNodeParameter('domain', i) as string; @@ -226,7 +234,11 @@ export class Brandfetch implements INodeType { }; const response = await brandfetchApiRequest.call(this, 'POST', `/font`, body); - responseData.push(response.response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } if (operation === 'company') { const domain = this.getNodeParameter('domain', i) as string; @@ -236,7 +248,11 @@ export class Brandfetch implements INodeType { }; const response = await brandfetchApiRequest.call(this, 'POST', `/company`, body); - responseData.push(response.response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } if (operation === 'industry') { const domain = this.getNodeParameter('domain', i) as string; @@ -246,11 +262,16 @@ export class Brandfetch implements INodeType { }; const response = await brandfetchApiRequest.call(this, 'POST', `/industry`, body); - responseData.push.apply(responseData, response.response); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + responseData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - responseData.push({ error: error.message }); + responseData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; @@ -261,7 +282,7 @@ export class Brandfetch implements INodeType { // For file downloads the files get attached to the existing items return this.prepareOutputData(items); } else { - return [this.helpers.returnJsonArray(responseData)]; + return [responseData]; } } } diff --git a/packages/nodes-base/nodes/Bubble/Bubble.node.ts b/packages/nodes-base/nodes/Bubble/Bubble.node.ts index 536535453a..075d5f6a22 100644 --- a/packages/nodes-base/nodes/Bubble/Bubble.node.ts +++ b/packages/nodes-base/nodes/Bubble/Bubble.node.ts @@ -2,6 +2,7 @@ import { IExecuteFunctions } from 'n8n-core'; import { IDataObject, + INode, INodeExecutionData, INodeType, INodeTypeDescription, @@ -59,7 +60,7 @@ export class Bubble implements INodeType { let responseData; const qs: IDataObject = {}; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { if (resource === 'object') { @@ -169,15 +170,17 @@ export class Bubble implements INodeType { property.forEach((data) => (body[data.key] = data.value)); responseData = await bubbleApiRequest.call(this, 'PATCH', endpoint, body, {}); - responseData = { sucess: true }; + responseData = { success: true }; } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts b/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts index 75528ea58d..4c6d18aa77 100644 --- a/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts +++ b/packages/nodes-base/nodes/Chargebee/Chargebee.node.ts @@ -447,7 +447,7 @@ export class Chargebee implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let item: INodeExecutionData; const credentials = await this.getCredentials('chargebeeApi'); @@ -603,26 +603,38 @@ export class Chargebee implements INodeType { if (resource === 'invoice' && operation === 'list') { responseData.list.forEach((data: IDataObject) => { - returnData.push(data.invoice as IDataObject); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ ...(data.invoice as IDataObject) }), + { itemData: { item: i } }, + ); + returnData.push(...responseData); }); } else if (resource === 'invoice' && operation === 'pdfUrl') { const data: IDataObject = {}; Object.assign(data, items[i].json); data.pdfUrl = responseData.download.download_url; - returnData.push(data); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ ...data }), + { itemData: { item: i } }, + ); + returnData.push(...responseData); } else { - returnData.push(responseData); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...responseData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts b/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts index 8e326cccff..49a1b02c08 100644 --- a/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts +++ b/packages/nodes-base/nodes/CircleCi/CircleCi.node.ts @@ -48,7 +48,7 @@ export class CircleCi implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -68,6 +68,10 @@ export class CircleCi implements INodeType { const endpoint = `/project/${vcs}/${slug}/pipeline/${pipelineNumber}`; responseData = await circleciApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'getAll') { const vcs = this.getNodeParameter('vcs', i) as string; @@ -98,6 +102,10 @@ export class CircleCi implements INodeType { responseData = responseData.items; responseData = responseData.splice(0, qs.limit); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'trigger') { @@ -121,21 +129,22 @@ export class CircleCi implements INodeType { } responseData = await circleciApiRequest.call(this, 'POST', endpoint, body, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + returnData.push(...responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {}, itemIndex: i }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts index 7b85bec62d..47adfa73f5 100644 --- a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts +++ b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts @@ -110,7 +110,7 @@ export class CiscoWebex implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const timezone = this.getTimezone(); const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -212,6 +212,10 @@ export class CiscoWebex implements INodeType { } else { responseData = await webexApiRequest.call(this, 'POST', '/messages', body); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'delete') { // ---------------------------------------- // message: delete @@ -222,7 +226,10 @@ export class CiscoWebex implements INodeType { const endpoint = `/messages/${messageId}`; responseData = await webexApiRequest.call(this, 'DELETE', endpoint); - responseData = { success: true }; + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); } else if (operation === 'get') { // ---------------------------------------- // message: get @@ -233,6 +240,10 @@ export class CiscoWebex implements INodeType { const endpoint = `/messages/${messageId}`; responseData = await webexApiRequest.call(this, 'GET', endpoint); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'getAll') { // ---------------------------------------- // message: getAll @@ -263,6 +274,10 @@ export class CiscoWebex implements INodeType { responseData = await webexApiRequest.call(this, 'GET', '/messages', {}, qs); responseData = responseData.items; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.items), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // message: update @@ -287,6 +302,10 @@ export class CiscoWebex implements INodeType { } responseData = await webexApiRequest.call(this, 'PUT', endpoint, body); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } @@ -323,6 +342,10 @@ export class CiscoWebex implements INodeType { } responseData = await webexApiRequest.call(this, 'POST', '/meetings', body); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'delete') { @@ -340,7 +363,10 @@ export class CiscoWebex implements INodeType { {}, qs, ); - responseData = { success: true }; + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); } if (operation === 'get') { @@ -367,6 +393,10 @@ export class CiscoWebex implements INodeType { undefined, { headers }, ); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'getAll') { @@ -398,12 +428,15 @@ export class CiscoWebex implements INodeType { {}, qs, ); - returnData.push(...responseData); } else { qs.max = this.getNodeParameter('limit', i) as number; responseData = await webexApiRequest.call(this, 'GET', '/meetings', {}, qs); responseData = responseData.items; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'update') { @@ -458,17 +491,17 @@ export class CiscoWebex implements INodeType { } responseData = await webexApiRequest.call(this, 'PUT', `/meetings/${meetingId}`, body); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + returnData.push(...responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.toString() }); + returnData.push({ error: error.toString(), json: {}, itemIndex: i }); continue; } @@ -536,6 +569,6 @@ export class CiscoWebex implements INodeType { // } // } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts index e0a20a1a4d..12d2d996ac 100644 --- a/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts +++ b/packages/nodes-base/nodes/Clearbit/Clearbit.node.ts @@ -58,7 +58,7 @@ export class Clearbit implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -147,19 +147,19 @@ export class Clearbit implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts index 04de66d264..35dd2e9cf7 100644 --- a/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts +++ b/packages/nodes-base/nodes/ClickUp/ClickUp.node.ts @@ -423,7 +423,7 @@ export class ClickUp implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -1627,19 +1627,20 @@ export class ClickUp implements INodeType { responseData = await clickupApiRequest.call(this, 'PUT', `/list/${listId}`, body); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Clockify/Clockify.node.ts b/packages/nodes-base/nodes/Clockify/Clockify.node.ts index 17aa05ae17..da166ce1f2 100644 --- a/packages/nodes-base/nodes/Clockify/Clockify.node.ts +++ b/packages/nodes-base/nodes/Clockify/Clockify.node.ts @@ -235,7 +235,7 @@ export class Clockify implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; @@ -835,20 +835,20 @@ export class Clockify implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Coda/Coda.node.ts b/packages/nodes-base/nodes/Coda/Coda.node.ts index 750973fedd..b459d3feb1 100644 --- a/packages/nodes-base/nodes/Coda/Coda.node.ts +++ b/packages/nodes-base/nodes/Coda/Coda.node.ts @@ -7,7 +7,6 @@ import { INodeType, INodeTypeDescription, NodeApiError, - NodeOperationError, } from 'n8n-workflow'; import { codaApiRequest, codaApiRequestAllItems } from './GenericFunctions'; import { tableFields, tableOperations } from './TableDescription'; @@ -240,12 +239,12 @@ export class Coda implements INodeType { }; async execute(this: IExecuteFunctions): Promise { - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const items = this.getInputData(); let responseData; const resource = this.getNodeParameter('resource', 0) as string; - const operation = this.getNodeParameter('operation', 0) as string; let qs: IDataObject = {}; + const operation = this.getNodeParameter('operation', 0) as string; if (resource === 'table') { // https://coda.io/developers/apis/v1beta1#operation/upsertRows @@ -331,23 +330,32 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); if (options.rawData === true) { - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else { - returnData.push({ - id: responseData.id, - ...responseData.values, - }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ id: responseData.id, ...responseData.values }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } // https://coda.io/developers/apis/v1beta1#operation/listRows if (operation === 'getAllRows') { @@ -451,7 +459,11 @@ export class Coda implements INodeType { returnData.push(responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -468,10 +480,18 @@ export class Coda implements INodeType { const columnId = this.getNodeParameter('columnId', i) as string; const endpoint = `/docs/${docId}/tables/${tableId}/columns/${columnId}`; responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -494,16 +514,24 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.items; } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } if (resource === 'formula') { @@ -515,16 +543,24 @@ export class Coda implements INodeType { const formulaId = this.getNodeParameter('formulaId', i) as string; const endpoint = `/docs/${docId}/formulas/${formulaId}`; responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } //https://coda.io/developers/apis/v1beta1#operation/listFormulas if (operation === 'getAll') { @@ -540,16 +576,24 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.items; } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } if (resource === 'control') { @@ -561,16 +605,24 @@ export class Coda implements INodeType { const controlId = this.getNodeParameter('controlId', i) as string; const endpoint = `/docs/${docId}/controls/${controlId}`; responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } //https://coda.io/developers/apis/v1beta1#operation/listControls if (operation === 'getAll') { @@ -586,16 +638,24 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.items; } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } if (resource === 'view') { @@ -606,9 +666,13 @@ export class Coda implements INodeType { const viewId = this.getNodeParameter('viewId', i) as string; const endpoint = `/docs/${docId}/tables/${viewId}`; responseData = await codaApiRequest.call(this, 'GET', endpoint, {}); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } //https://coda.io/developers/apis/v1beta1#operation/listViews if (operation === 'getAll') { @@ -624,16 +688,24 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.items; } - returnData.push.apply(returnData, responseData); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } if (operation === 'getAllViewRows') { const docId = this.getNodeParameter('docId', 0) as string; @@ -698,16 +770,24 @@ export class Coda implements INodeType { const rowId = this.getNodeParameter('rowId', i) as string; const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}`; responseData = await codaApiRequest.call(this, 'DELETE', endpoint); - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } //https://coda.io/developers/apis/v1beta1#operation/pushViewButton if (operation === 'pushViewButton') { @@ -719,16 +799,24 @@ export class Coda implements INodeType { const columnId = this.getNodeParameter('columnId', i) as string; const endpoint = `/docs/${docId}/tables/${viewId}/rows/${rowId}/buttons/${columnId}`; responseData = await codaApiRequest.call(this, 'POST', endpoint); - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } if (operation === 'getAllViewColumns') { for (let i = 0; i < items.length; i++) { @@ -744,16 +832,24 @@ export class Coda implements INodeType { responseData = await codaApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.items; } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.messsage }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } //https://coda.io/developers/apis/v1beta1#operation/updateViewRow if (operation === 'updateViewRow') { diff --git a/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts b/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts index 2789ef3997..af348eec44 100644 --- a/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts +++ b/packages/nodes-base/nodes/CoinGecko/CoinGecko.node.ts @@ -139,7 +139,7 @@ export class CoinGecko implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -471,20 +471,20 @@ export class CoinGecko implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Contentful/Contentful.node.ts b/packages/nodes-base/nodes/Contentful/Contentful.node.ts index aa9e423492..c9bb422f9a 100644 --- a/packages/nodes-base/nodes/Contentful/Contentful.node.ts +++ b/packages/nodes-base/nodes/Contentful/Contentful.node.ts @@ -87,7 +87,7 @@ export class Contentful implements INodeType { let responseData; const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const qs: Record = {}; for (let i = 0; i < items.length; i++) { @@ -353,19 +353,19 @@ export class Contentful implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts b/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts index c54c49bd5c..5b5a104055 100644 --- a/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts +++ b/packages/nodes-base/nodes/ConvertKit/ConvertKit.node.ts @@ -154,7 +154,7 @@ export class ConvertKit implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const qs: IDataObject = {}; let responseData; @@ -478,20 +478,20 @@ export class ConvertKit implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Copper/Copper.node.ts b/packages/nodes-base/nodes/Copper/Copper.node.ts index ce49ef100b..535309d5e8 100644 --- a/packages/nodes-base/nodes/Copper/Copper.node.ts +++ b/packages/nodes-base/nodes/Copper/Copper.node.ts @@ -113,7 +113,7 @@ export class Copper implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -615,18 +615,20 @@ export class Copper implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.toString() }); + returnData.push({ error: error.toString(), json: {} }); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/DeepL/DeepL.node.ts b/packages/nodes-base/nodes/DeepL/DeepL.node.ts index 659c637501..c61f844ded 100644 --- a/packages/nodes-base/nodes/DeepL/DeepL.node.ts +++ b/packages/nodes-base/nodes/DeepL/DeepL.node.ts @@ -7,6 +7,7 @@ import { INodePropertyOptions, INodeType, INodeTypeDescription, + NodeExecutionWithMetadata, } from 'n8n-workflow'; import { deepLApiRequest } from './GenericFunctions'; @@ -108,14 +109,13 @@ export class DeepL implements INodeType { const items = this.getInputData(); const length = items.length; - const responseData = []; + const responseData: INodeExecutionData[] = []; for (let i = 0; i < length; i++) { try { const resource = this.getNodeParameter('resource', i) as string; const operation = this.getNodeParameter('operation', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; - if (resource === 'language') { if (operation === 'translate') { let body: IDataObject = {}; @@ -129,19 +129,30 @@ export class DeepL implements INodeType { : additionalFields.sourceLang; } - const response = await deepLApiRequest.call(this, 'GET', '/translate', body); - responseData.push(response.translations[0]); + const { translations } = await deepLApiRequest.call(this, 'GET', '/translate', body); + const [translation] = translations; + const translationJsonArray = this.helpers.returnJsonArray(translation); + const executionData = this.helpers.constructExecutionMetaData( + translationJsonArray, + { itemData: { item: i } }, + ); + responseData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - responseData.push({ $error: error, $json: this.getInputData(i) }); + const executionErrorData = { + json: {} as IDataObject, + error: error.message, + itemIndex: i, + }; + responseData.push(executionErrorData as INodeExecutionData); continue; } throw error; } } - return [this.helpers.returnJsonArray(responseData)]; + return [responseData]; } } diff --git a/packages/nodes-base/nodes/Discord/Discord.node.ts b/packages/nodes-base/nodes/Discord/Discord.node.ts index d7a9eb256b..d540feedbb 100644 --- a/packages/nodes-base/nodes/Discord/Discord.node.ts +++ b/packages/nodes-base/nodes/Discord/Discord.node.ts @@ -119,7 +119,7 @@ export class Discord implements INodeType { }; async execute(this: IExecuteFunctions): Promise { - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const webhookUri = this.getNodeParameter('webhookUri', 0, '') as string; @@ -269,9 +269,13 @@ export class Discord implements INodeType { }); } - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({success: true}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Discourse/Discourse.node.ts b/packages/nodes-base/nodes/Discourse/Discourse.node.ts index fd0fa0505d..4ae5e3909a 100644 --- a/packages/nodes-base/nodes/Discourse/Discourse.node.ts +++ b/packages/nodes-base/nodes/Discourse/Discourse.node.ts @@ -1,11 +1,8 @@ import { IExecuteFunctions } from 'n8n-core'; import { - ICredentialsDecrypted, - ICredentialTestFunctions, IDataObject, ILoadOptionsFunctions, - INodeCredentialTestResult, INodeExecutionData, INodePropertyOptions, INodeType, @@ -21,17 +18,9 @@ import { categoryFields, categoryOperations } from './CategoryDescription'; import { groupFields, groupOperations } from './GroupDescription'; -// import { -// searchFields, -// searchOperations, -// } from './SearchDescription'; - import { userFields, userOperations } from './UserDescription'; import { userGroupFields, userGroupOperations } from './UserGroupDescription'; -import { OptionsWithUri } from 'request'; - -//import moment from 'moment'; export class Discourse implements INodeType { description: INodeTypeDescription = { @@ -122,7 +111,7 @@ export class Discourse implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -431,19 +420,24 @@ export class Discourse implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Disqus/Disqus.node.ts b/packages/nodes-base/nodes/Disqus/Disqus.node.ts index 6333358582..61801ae40b 100644 --- a/packages/nodes-base/nodes/Disqus/Disqus.node.ts +++ b/packages/nodes-base/nodes/Disqus/Disqus.node.ts @@ -570,7 +570,7 @@ export class Disqus implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -604,7 +604,11 @@ export class Disqus implements INodeType { try { const responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData.response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.response), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { throw error; } @@ -640,7 +644,11 @@ export class Disqus implements INodeType { qs.limit = limit; responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); } - returnData.push.apply(returnData, responseData.response as IDataObject[]); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.response as IDataObject), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { throw error; } @@ -681,7 +689,11 @@ export class Disqus implements INodeType { endpoint, )) as IDataObject; } - returnData.push.apply(returnData, responseData.response as IDataObject[]); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.response as IDataObject), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { throw error; } @@ -718,7 +730,11 @@ export class Disqus implements INodeType { qs.limit = limit; responseData = await disqusApiRequest.call(this, requestMethod, qs, endpoint); } - returnData.push.apply(returnData, responseData.response as IDataObject[]); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.response as IDataObject), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { throw error; } @@ -736,13 +752,17 @@ export class Disqus implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts index fbee220a58..e588d09151 100644 --- a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts +++ b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts @@ -693,7 +693,7 @@ export class Dropbox implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -849,11 +849,11 @@ export class Dropbox implements INodeType { filters.file_extensions = (filters.file_extensions as string).split(','); } - Object.assign(body.options, filters); + Object.assign(body.options!, filters); if (returnAll === false) { const limit = this.getNodeParameter('limit', i) as number; - Object.assign(body.options, { max_results: limit }); + Object.assign(body.options!, { max_results: limit }); } endpoint = 'https://api.dropboxapi.com/2/files/search_v2'; @@ -932,20 +932,24 @@ export class Dropbox implements INodeType { } if (resource === 'file' && operation === 'upload') { - responseData = JSON.parse(responseData); - } - - if (resource === 'file' && operation === 'download') { + const data = JSON.parse(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(data), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + } else if (resource === 'file' && operation === 'download') { const newItem: INodeExecutionData = { json: items[i].json, binary: {}, + pairedItem: {item: i}, }; if (items[i].binary !== undefined) { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -987,29 +991,39 @@ export class Dropbox implements INodeType { } } - returnData.push(newItem as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(newItem), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } else if (resource === 'search' && operation === 'query') { + let data = responseData; if (returnAll === true) { - returnData.push.apply( - returnData, - simple === true ? simplify(responseData) : responseData, - ); + data = (simple === true) ? simplify(responseData) : responseData; } else { - returnData.push.apply( - returnData, - simple === true ? simplify(responseData[property]) : responseData[property], - ); + data = (simple === true) ? simplify(responseData[property]) : responseData[property]; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(data), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { if (resource === 'file' && operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + returnData.push({json: { error: error.message }}); } continue; } @@ -1022,7 +1036,7 @@ export class Dropbox implements INodeType { return this.prepareOutputData(items); } else { // For all other ones does the output items get replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/ERPNext/ERPNext.node.ts b/packages/nodes-base/nodes/ERPNext/ERPNext.node.ts index 188bdfd12d..4d3abd995d 100644 --- a/packages/nodes-base/nodes/ERPNext/ERPNext.node.ts +++ b/packages/nodes-base/nodes/ERPNext/ERPNext.node.ts @@ -114,7 +114,7 @@ export class ERPNext implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const body: IDataObject = {}; @@ -282,10 +282,12 @@ export class ERPNext implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Egoi/Egoi.node.ts b/packages/nodes-base/nodes/Egoi/Egoi.node.ts index cbe3addea4..8dc97277af 100644 --- a/packages/nodes-base/nodes/Egoi/Egoi.node.ts +++ b/packages/nodes-base/nodes/Egoi/Egoi.node.ts @@ -538,7 +538,7 @@ export class Egoi implements INodeType { async execute(this: IExecuteFunctions): Promise { let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const items = this.getInputData(); const length = items.length; const operation = this.getNodeParameter('operation', 0) as string; @@ -739,19 +739,21 @@ export class Egoi implements INodeType { throw error; } else { // Return the actual reason as error - returnData.push({ - error: error.message, - }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Elastic/ElasticSecurity/ElasticSecurity.node.ts b/packages/nodes-base/nodes/Elastic/ElasticSecurity/ElasticSecurity.node.ts index 328918f330..e767fd379d 100644 --- a/packages/nodes-base/nodes/Elastic/ElasticSecurity/ElasticSecurity.node.ts +++ b/packages/nodes-base/nodes/Elastic/ElasticSecurity/ElasticSecurity.node.ts @@ -164,7 +164,7 @@ export class ElasticSecurity implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -573,18 +573,24 @@ export class ElasticSecurity implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts b/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts index 4019683c62..67c8585226 100644 --- a/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts +++ b/packages/nodes-base/nodes/Elastic/Elasticsearch/Elasticsearch.node.ts @@ -66,7 +66,7 @@ export class Elasticsearch implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as 'document' | 'index'; const operation = this.getNodeParameter('operation', 0) as string; @@ -329,11 +329,13 @@ export class Elasticsearch implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Emelia/Emelia.node.ts b/packages/nodes-base/nodes/Emelia/Emelia.node.ts index 34dddc5889..73928ed83f 100644 --- a/packages/nodes-base/nodes/Emelia/Emelia.node.ts +++ b/packages/nodes-base/nodes/Emelia/Emelia.node.ts @@ -82,7 +82,7 @@ export class Emelia implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0); const operation = this.getNodeParameter('operation', 0); @@ -134,7 +134,13 @@ export class Emelia implements INodeType { }, }); - returnData.push({ contactId: responseData.data.addContactToCampaignHook }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ + contactId: responseData.data.addContactToCampaignHook, + }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // campaign: create @@ -159,7 +165,11 @@ export class Emelia implements INodeType { }, }); - returnData.push(responseData.data.createCampaign); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.data.createCampaign), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // campaign: get @@ -200,7 +210,11 @@ export class Emelia implements INodeType { }, }); - returnData.push(responseData.data.campaign); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.data.campaign), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // campaign: getAll @@ -238,7 +252,11 @@ export class Emelia implements INodeType { campaigns = campaigns.slice(0, limit); } - returnData.push(...campaigns); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(campaigns), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'pause') { // ---------------------------------- // campaign: pause @@ -255,7 +273,11 @@ export class Emelia implements INodeType { }, }); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'start') { // ---------------------------------- // campaign: start @@ -272,7 +294,11 @@ export class Emelia implements INodeType { }, }); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'duplicate') { // ---------------------------------- // campaign: duplicate @@ -313,7 +339,11 @@ export class Emelia implements INodeType { variables, }); - returnData.push({ _id: duplicateCampaign }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ _id: duplicateCampaign }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } else if (resource === 'contactList') { // ********************************** @@ -360,7 +390,11 @@ export class Emelia implements INodeType { }, }); - returnData.push({ contactId: responseData.data.addContactsToListHook }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ contactId: responseData.data.addContactsToListHook }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // contactList: getAll @@ -389,18 +423,26 @@ export class Emelia implements INodeType { contactLists = contactLists.slice(0, limit); } - returnData.push(...contactLists); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(contactLists), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Flow/Flow.node.ts b/packages/nodes-base/nodes/Flow/Flow.node.ts index 208f315d0b..5def6aa998 100644 --- a/packages/nodes-base/nodes/Flow/Flow.node.ts +++ b/packages/nodes-base/nodes/Flow/Flow.node.ts @@ -57,7 +57,7 @@ export class Flow implements INodeType { const credentials = await this.getCredentials('flowApi'); const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -258,16 +258,17 @@ export class Flow implements INodeType { responseData = responseData.tasks; } } catch (error) { - throw new NodeApiError(this.getNode(), error); + throw new NodeApiError(this.getNode(), error, { itemIndex: i }); } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts b/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts index c62d7db9c9..c80bf74fce 100644 --- a/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts +++ b/packages/nodes-base/nodes/Freshdesk/Freshdesk.node.ts @@ -1093,7 +1093,7 @@ export class Freshdesk implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const qs: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; @@ -1407,25 +1407,29 @@ export class Freshdesk implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - if (responseData === undefined) { - responseData = { - success: true, - }; - } - - returnData.push(responseData as IDataObject); + if (!Array.isArray(responseData) && responseData === undefined) { + responseData = { + success: true, + }; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Freshservice/Freshservice.node.ts b/packages/nodes-base/nodes/Freshservice/Freshservice.node.ts index 85338b8808..a3c90ed4d3 100644 --- a/packages/nodes-base/nodes/Freshservice/Freshservice.node.ts +++ b/packages/nodes-base/nodes/Freshservice/Freshservice.node.ts @@ -271,7 +271,7 @@ export class Freshservice implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -1230,7 +1230,7 @@ export class Freshservice implements INodeType { const additionalFields = this.getNodeParameter('additionalFields', i) as IDataObject; if (Object.keys(additionalFields).length) { - Object.assign(body.application, additionalFields); + Object.assign(body.application!, additionalFields); } responseData = await freshserviceApiRequest.call(this, 'POST', '/applications', body); @@ -1266,7 +1266,7 @@ export class Freshservice implements INodeType { validateUpdateFields.call(this, updateFields, resource); - Object.assign(body.application, updateFields); + Object.assign(body.application!, updateFields); const softwareId = this.getNodeParameter('softwareId', i); const endpoint = `/applications/${softwareId}`; @@ -1375,17 +1375,23 @@ export class Freshservice implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/FreshworksCrm/FreshworksCrm.node.ts b/packages/nodes-base/nodes/FreshworksCrm/FreshworksCrm.node.ts index 1a86fe02b0..fd3c59a9ab 100644 --- a/packages/nodes-base/nodes/FreshworksCrm/FreshworksCrm.node.ts +++ b/packages/nodes-base/nodes/FreshworksCrm/FreshworksCrm.node.ts @@ -238,7 +238,7 @@ export class FreshworksCrm implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -979,17 +979,23 @@ export class FreshworksCrm implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts index fbffe7ac2f..1b0e28b602 100644 --- a/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts +++ b/packages/nodes-base/nodes/GetResponse/GetResponse.node.ts @@ -131,7 +131,7 @@ export class GetResponse implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -292,19 +292,23 @@ export class GetResponse implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Ghost/Ghost.node.ts b/packages/nodes-base/nodes/Ghost/Ghost.node.ts index aaf30b8157..dff7d61056 100644 --- a/packages/nodes-base/nodes/Ghost/Ghost.node.ts +++ b/packages/nodes-base/nodes/Ghost/Ghost.node.ts @@ -119,7 +119,7 @@ export class Ghost implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const timezone = this.getTimezone(); const qs: IDataObject = {}; @@ -127,6 +127,7 @@ export class Ghost implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; const source = this.getNodeParameter('source', 0) as string; + for (let i = 0; i < length; i++) { try { if (source === 'contentApi') { @@ -147,9 +148,9 @@ export class Ghost implements INodeType { } else { endpoint = `/content/posts/${identifier}`; } - responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); - returnData.push.apply(returnData, responseData.posts); + responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); + responseData = responseData.posts; } if (operation === 'getAll') { @@ -173,8 +174,6 @@ export class Ghost implements INodeType { responseData = await ghostApiRequest.call(this, 'GET', '/content/posts', {}, qs); responseData = responseData.posts; } - - returnData.push.apply(returnData, responseData); } } } @@ -230,16 +229,13 @@ export class Ghost implements INodeType { { posts: [post] }, qs, ); - - returnData.push.apply(returnData, responseData.posts); + responseData = responseData.posts; } if (operation === 'delete') { const postId = this.getNodeParameter('postId', i) as string; responseData = await ghostApiRequest.call(this, 'DELETE', `/admin/posts/${postId}`); - - returnData.push({ success: true }); } if (operation === 'get') { @@ -259,8 +255,7 @@ export class Ghost implements INodeType { endpoint = `/admin/posts/${identifier}`; } responseData = await ghostApiRequest.call(this, 'GET', endpoint, {}, qs); - - returnData.push.apply(returnData, responseData.posts); + responseData = responseData.posts; } if (operation === 'getAll') { @@ -284,8 +279,6 @@ export class Ghost implements INodeType { responseData = await ghostApiRequest.call(this, 'GET', '/admin/posts', {}, qs); responseData = responseData.posts; } - - returnData.push.apply(returnData, responseData); } if (operation === 'update') { @@ -343,19 +336,30 @@ export class Ghost implements INodeType { { posts: [post] }, qs, ); - - returnData.push.apply(returnData, responseData.posts); + responseData = responseData.posts; } } } + + responseData = this.helpers.returnJsonArray(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Github/Github.node.ts b/packages/nodes-base/nodes/Github/Github.node.ts index f567c7b088..84e84b1bc4 100644 --- a/packages/nodes-base/nodes/Github/Github.node.ts +++ b/packages/nodes-base/nodes/Github/Github.node.ts @@ -5,6 +5,7 @@ import { INodeExecutionData, INodeType, INodeTypeDescription, + IPairedItemData, NodeOperationError, } from 'n8n-workflow'; @@ -1609,7 +1610,7 @@ export class Github implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let returnAll = false; @@ -2102,6 +2103,7 @@ export class Github implements INodeType { }); } + const asBinaryProperty = this.getNodeParameter('asBinaryProperty', i, false) as boolean; if (returnAll === true) { responseData = await githubApiRequestAllItems.call( this, @@ -2115,10 +2117,8 @@ export class Github implements INodeType { } if (fullOperation === 'file:get') { - const asBinaryProperty = this.getNodeParameter('asBinaryProperty', i); - if (asBinaryProperty === true) { - if (Array.isArray(responseData)) { + if (Array.isArray(responseData) && responseData.length > 1) { throw new NodeOperationError(this.getNode(), 'File Path is a folder, not a file.', { itemIndex: i, }); @@ -2135,27 +2135,34 @@ export class Github implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary as object, items[i].binary!); } + const { content, path } = responseData[i].json; newItem.binary![binaryPropertyName] = await this.helpers.prepareBinaryData( - Buffer.from(responseData.content, 'base64'), - responseData.path, + Buffer.from(content as string, 'base64'), + path as string, ); items[i] = newItem; - return this.prepareOutputData(items); + return [items]; } } + if (fullOperation === 'release:delete') { responseData = { success: true }; } - if (overwriteDataOperations.includes(fullOperation)) { - returnData.push(responseData); - } else if (overwriteDataOperationsArray.includes(fullOperation)) { - returnData.push.apply(returnData, responseData); + if ( + overwriteDataOperations.includes(fullOperation) || + overwriteDataOperationsArray.includes(fullOperation) + ) { + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { @@ -2163,7 +2170,17 @@ export class Github implements INodeType { overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation) ) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + [ + { + json: { + error: error.message, + }, + }, + ], + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } else { items[i].json = { error: error.message }; } @@ -2178,10 +2195,10 @@ export class Github implements INodeType { overwriteDataOperationsArray.includes(fullOperation) ) { // Return data gets replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } else { // For all other ones simply return the unchanged items - return this.prepareOutputData(items); + return [items]; } } } diff --git a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts index a63fbd9252..73009780a3 100644 --- a/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts +++ b/packages/nodes-base/nodes/Gitlab/Gitlab.node.ts @@ -976,7 +976,7 @@ export class Gitlab implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let credentials; @@ -1232,7 +1232,9 @@ export class Gitlab implements INodeType { endpoint = `/users/${owner}/projects`; } } else { - throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`); + throw new NodeOperationError(this.getNode(), `The resource "${resource}" is not known!`, { + itemIndex: i, + }); } if (returnAll === true) { @@ -1247,18 +1249,22 @@ export class Gitlab implements INodeType { responseData = await gitlabApiRequest.call(this, requestMethod, endpoint, body, qs); } - if (overwriteDataOperations.includes(fullOperation)) { - returnData.push(responseData); - } else if (overwriteDataOperationsArray.includes(fullOperation)) { - returnData.push.apply(returnData, responseData); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { if ( overwriteDataOperations.includes(fullOperation) || overwriteDataOperationsArray.includes(fullOperation) ) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } else { items[i].json = { error: error.message }; } @@ -1273,7 +1279,7 @@ export class Gitlab implements INodeType { overwriteDataOperationsArray.includes(fullOperation) ) { // Return data gets replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } else { // For all other ones simply return the unchanged items return this.prepareOutputData(items); diff --git a/packages/nodes-base/nodes/GoToWebinar/GoToWebinar.node.ts b/packages/nodes-base/nodes/GoToWebinar/GoToWebinar.node.ts index bd23e91e27..16272c0729 100644 --- a/packages/nodes-base/nodes/GoToWebinar/GoToWebinar.node.ts +++ b/packages/nodes-base/nodes/GoToWebinar/GoToWebinar.node.ts @@ -154,7 +154,7 @@ export class GoToWebinar implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const { oauthTokenData } = (await this.getCredentials('goToWebinarOAuth2Api')) as { oauthTokenData: { account_key: string; organizer_key: string }; @@ -636,18 +636,25 @@ export class GoToWebinar implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts b/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts index d1ff27806c..2e5e9e7d60 100644 --- a/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts +++ b/packages/nodes-base/nodes/Google/Analytics/GoogleAnalytics.node.ts @@ -140,7 +140,7 @@ export class GoogleAnalytics implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -276,19 +276,24 @@ export class GoogleAnalytics implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/BigQuery/GoogleBigQuery.node.ts b/packages/nodes-base/nodes/Google/BigQuery/GoogleBigQuery.node.ts index 002e2f286e..b20c69dea8 100644 --- a/packages/nodes-base/nodes/Google/BigQuery/GoogleBigQuery.node.ts +++ b/packages/nodes-base/nodes/Google/BigQuery/GoogleBigQuery.node.ts @@ -137,7 +137,7 @@ export class GoogleBigQuery implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -192,7 +192,7 @@ export class GoogleBigQuery implements INodeType { returnData.push(responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json: { error: error.message } }); } else { throw new NodeApiError(this.getNode(), error); } @@ -226,13 +226,6 @@ export class GoogleBigQuery implements INodeType { const options = this.getNodeParameter('options', i) as IDataObject; Object.assign(qs, options); - // if (qs.useInt64Timestamp !== undefined) { - // qs.formatOptions = { - // useInt64Timestamp: qs.useInt64Timestamp, - // }; - // delete qs.useInt64Timestamp; - // } - if (qs.selectedFields) { fields = (qs.selectedFields as string).split(','); } @@ -246,10 +239,6 @@ export class GoogleBigQuery implements INodeType { {}, qs, ); - returnData.push.apply( - returnData, - simple ? simplify(responseData, fields) : responseData, - ); } else { qs.maxResults = this.getNodeParameter('limit', i) as number; responseData = await googleApiRequest.call( @@ -259,22 +248,30 @@ export class GoogleBigQuery implements INodeType { {}, qs, ); - returnData.push.apply( - returnData, - simple ? simplify(responseData.rows, fields) : responseData.rows, - ); } + + responseData = simple ? simplify(responseData.rows, fields) : responseData.rows; + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } - throw new NodeApiError(this.getNode(), error); + throw new NodeApiError(this.getNode(), error, { itemIndex: i }); } } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts b/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts index 607fa99f45..436e6d47b5 100644 --- a/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts +++ b/packages/nodes-base/nodes/Google/Books/GoogleBooks.node.ts @@ -343,7 +343,7 @@ export class GoogleBooks implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); const length = items.length; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; const qs: IDataObject = {}; @@ -499,19 +499,24 @@ export class GoogleBooks implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(responseData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts index 80d0aba7ba..84b7c9bf3e 100644 --- a/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts +++ b/packages/nodes-base/nodes/Google/Calendar/GoogleCalendar.node.ts @@ -150,7 +150,7 @@ export class GoogleCalendar implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -188,7 +188,9 @@ export class GoogleCalendar implements INodeType { ); if (responseData.calendars[calendarId].errors) { - throw new NodeApiError(this.getNode(), responseData.calendars[calendarId]); + throw new NodeApiError(this.getNode(), responseData.calendars[calendarId], { + itemIndex: i, + }); } if (outputFormat === 'availability') { @@ -580,23 +582,24 @@ export class GoogleCalendar implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail() !== true) { throw error; } else { - // Return the actual reason as error - returnData.push({ - error: (error as JsonObject).message, - }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Chat/GoogleChat.node.ts b/packages/nodes-base/nodes/Google/Chat/GoogleChat.node.ts index 41939f0596..038bc51faa 100644 --- a/packages/nodes-base/nodes/Google/Chat/GoogleChat.node.ts +++ b/packages/nodes-base/nodes/Google/Chat/GoogleChat.node.ts @@ -196,7 +196,7 @@ export class GoogleChat implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -239,7 +239,7 @@ export class GoogleChat implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -535,18 +535,23 @@ export class GoogleChat implements INodeType { responseData = await googleApiRequest.call(this, 'POST', '', body, qs, uri, true); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { // Return the actual reason as error if (operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } continue; } @@ -559,7 +564,7 @@ export class GoogleChat implements INodeType { return this.prepareOutputData(items); } else { // For all other ones does the output get replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts b/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts index 464a4bd744..39949691c5 100644 --- a/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts +++ b/packages/nodes-base/nodes/Google/Contacts/GoogleContacts.node.ts @@ -19,7 +19,6 @@ import { import { contactFields, contactOperations } from './ContactDescription'; import moment from 'moment'; -import { IData } from '../Analytics/Interfaces'; export class GoogleContacts implements INodeType { description: INodeTypeDescription = { @@ -88,7 +87,7 @@ export class GoogleContacts implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -504,19 +503,25 @@ export class GoogleContacts implements INodeType { responseData.contactId = responseData.resourceName.split('/')[1]; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Docs/GoogleDocs.node.ts b/packages/nodes-base/nodes/Google/Docs/GoogleDocs.node.ts index 76900d120f..83c968c024 100644 --- a/packages/nodes-base/nodes/Google/Docs/GoogleDocs.node.ts +++ b/packages/nodes-base/nodes/Google/Docs/GoogleDocs.node.ts @@ -196,7 +196,7 @@ export class GoogleDocs implements INodeType { }; async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; @@ -503,17 +503,23 @@ export class GoogleDocs implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts index 1aeef25646..3159d1fe11 100644 --- a/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts +++ b/packages/nodes-base/nodes/Google/Drive/GoogleDrive.node.ts @@ -1930,7 +1930,7 @@ export class GoogleDrive implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -1963,11 +1963,14 @@ export class GoogleDrive implements INodeType { Object.assign(body, options); - const response = await googleApiRequest.call(this, 'POST', `/drive/v3/drives`, body, { - requestId: uuid(), - }); + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/drives`, body, { requestId: uuid() }); - returnData.push(response as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'delete') { // ---------------------------------- @@ -1978,7 +1981,12 @@ export class GoogleDrive implements INodeType { await googleApiRequest.call(this, 'DELETE', `/drive/v3/drives/${driveId}`); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'get') { // ---------------------------------- @@ -1991,15 +1999,14 @@ export class GoogleDrive implements INodeType { Object.assign(qs, options); - const response = await googleApiRequest.call( - this, - 'GET', - `/drive/v3/drives/${driveId}`, - {}, - qs, + const response = await googleApiRequest.call(this, 'GET', `/drive/v3/drives/${driveId}`, {}, qs); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, ); - returnData.push(response as IDataObject); + returnData.push(...executionData); } if (operation === 'list') { // ---------------------------------- @@ -2028,7 +2035,12 @@ export class GoogleDrive implements INodeType { response = data.drives as IDataObject[]; } - returnData.push.apply(returnData, response); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'update') { // ---------------------------------- @@ -2041,14 +2053,14 @@ export class GoogleDrive implements INodeType { Object.assign(body, options); - const response = await googleApiRequest.call( - this, - 'PATCH', - `/drive/v3/drives/${driveId}`, - body, + const response = await googleApiRequest.call(this, 'PATCH', `/drive/v3/drives/${driveId}`, body); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, ); - returnData.push(response as IDataObject); + returnData.push(...executionData); } } if (resource === 'file') { @@ -2074,15 +2086,14 @@ export class GoogleDrive implements INodeType { supportsAllDrives: true, }; - const response = await googleApiRequest.call( - this, - 'POST', - `/drive/v3/files/${fileId}/copy`, - body, - qs, + const response = await googleApiRequest.call(this, 'POST', `/drive/v3/files/${fileId}/copy`, body, qs); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, ); - returnData.push(response as IDataObject); + returnData.push(...executionData); } else if (operation === 'download') { // ---------------------------------- // download @@ -2281,11 +2292,16 @@ export class GoogleDrive implements INodeType { const version = this.getNode().typeVersion; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(files), + { itemData: { item: i } }, + ); + if (version === 1) { - return [this.helpers.returnJsonArray(files as IDataObject[])]; - } else { - returnData.push(...files); + return [executionData]; } + + returnData.push(...executionData); } else if (operation === 'upload') { // ---------------------------------- // upload @@ -2416,7 +2432,11 @@ export class GoogleDrive implements INodeType { ); } - returnData.push(response as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // file:update @@ -2454,7 +2474,12 @@ export class GoogleDrive implements INodeType { body, qs, ); - returnData.push(responseData as IDataObject); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } if (resource === 'folder') { @@ -2478,7 +2503,11 @@ export class GoogleDrive implements INodeType { const response = await googleApiRequest.call(this, 'POST', '/drive/v3/files', body, qs); - returnData.push(response as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } if (['file', 'folder'].includes(resource)) { @@ -2498,10 +2527,15 @@ export class GoogleDrive implements INodeType { ); // If we are still here it did succeed - returnData.push({ - fileId, - success: true, - }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ + fileId, + success: true, + }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'share') { const fileId = this.getNodeParameter('fileId', i) as string; @@ -2530,7 +2564,11 @@ export class GoogleDrive implements INodeType { qs, ); - returnData.push(response as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } catch (error) { @@ -2538,7 +2576,7 @@ export class GoogleDrive implements INodeType { if (resource === 'file' && operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + returnData.push({ json: {error: error.message} }); } continue; } @@ -2550,7 +2588,7 @@ export class GoogleDrive implements INodeType { return this.prepareOutputData(items); } else { // For all other ones does the output items get replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Google/Firebase/CloudFirestore/GoogleFirebaseCloudFirestore.node.ts b/packages/nodes-base/nodes/Google/Firebase/CloudFirestore/GoogleFirebaseCloudFirestore.node.ts index 4157cb3799..078da3bb92 100644 --- a/packages/nodes-base/nodes/Google/Firebase/CloudFirestore/GoogleFirebaseCloudFirestore.node.ts +++ b/packages/nodes-base/nodes/Google/Firebase/CloudFirestore/GoogleFirebaseCloudFirestore.node.ts @@ -90,7 +90,7 @@ export class GoogleFirebaseCloudFirestore implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -120,18 +120,20 @@ export class GoogleFirebaseCloudFirestore implements INodeType { return element; }); - if (simple === false) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push.apply( - returnData, - responseData - .map((element: IDataObject) => { - return fullDocumentToJson(element.found as IDataObject); - }) - .filter((el: IDataObject) => !!el), - ); + if (simple) { + responseData = responseData + .map((element: IDataObject) => { + return fullDocumentToJson(element.found as IDataObject); + }) + .filter((el: IDataObject) => !!el); } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { const projectId = this.getNodeParameter('projectId', 0) as string; const database = this.getNodeParameter('database', 0) as string; @@ -162,11 +164,16 @@ export class GoogleFirebaseCloudFirestore implements INodeType { responseData.id = (responseData.name as string).split('/').pop(); - if (simple === false) { - returnData.push(responseData); - } else { - returnData.push(fullDocumentToJson(responseData as IDataObject)); + if (simple) { + responseData = fullDocumentToJson(responseData); } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); }), ); } else if (operation === 'getAll') { @@ -194,21 +201,25 @@ export class GoogleFirebaseCloudFirestore implements INodeType { )) as IDataObject; responseData = getAllResponse.documents; } + responseData = responseData.map((element: IDataObject) => { element.id = (element.name as string).split('/').pop(); return element; }); - if (simple === false) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push.apply( - returnData, - responseData.map((element: IDataObject) => fullDocumentToJson(element as IDataObject)), + + if (simple) { + responseData = responseData.map((element: IDataObject) => + fullDocumentToJson(element as IDataObject), ); } - } else if (operation === 'delete') { - const responseData: IDataObject[] = []; + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); + } else if (operation === 'delete') { await Promise.all( items.map(async (item: IDataObject, i: number) => { const projectId = this.getNodeParameter('projectId', i) as string; @@ -222,10 +233,14 @@ export class GoogleFirebaseCloudFirestore implements INodeType { `/${projectId}/databases/${database}/documents/${collection}/${documentId}`, ); - responseData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); }), ); - returnData.push.apply(returnData, responseData); } else if (operation === 'upsert') { const projectId = this.getNodeParameter('projectId', 0) as string; const database = this.getNodeParameter('database', 0) as string; @@ -272,10 +287,14 @@ export class GoogleFirebaseCloudFirestore implements INodeType { for (let i = 0; i < writeResults.length; i++) { writeResults[i]['status'] = status[i]; Object.assign(writeResults[i], items[i].json); - responseData.push(writeResults[i]); - } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(writeResults[i]), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); + } // } else if (operation === 'update') { // const projectId = this.getNodeParameter('projectId', 0) as string; @@ -333,19 +352,20 @@ export class GoogleFirebaseCloudFirestore implements INodeType { }, ); - if (simple === false) { - returnData.push.apply(returnData, responseData); - } else { - //@ts-ignore - returnData.push.apply( - returnData, - responseData - .map((element: IDataObject) => { - return fullDocumentToJson(element.document as IDataObject); - }) - .filter((element: IDataObject) => !!element), - ); + if (simple) { + responseData = responseData + .map((element: IDataObject) => { + return fullDocumentToJson(element.document as IDataObject); + }) + .filter((element: IDataObject) => !!element); } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); }), ); } @@ -376,10 +396,16 @@ export class GoogleFirebaseCloudFirestore implements INodeType { // @ts-ignore responseData = getAllResponse.collectionIds.map((o) => ({ name: o })); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/GoogleFirebaseRealtimeDatabase.node.ts b/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/GoogleFirebaseRealtimeDatabase.node.ts index 6eeddf81c6..1cb2d7e947 100644 --- a/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/GoogleFirebaseRealtimeDatabase.node.ts +++ b/packages/nodes-base/nodes/Google/Firebase/RealtimeDatabase/GoogleFirebaseRealtimeDatabase.node.ts @@ -164,7 +164,7 @@ export class GoogleFirebaseRealtimeDatabase implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const operation = this.getNodeParameter('operation', 0) as string; @@ -228,21 +228,29 @@ export class GoogleFirebaseRealtimeDatabase implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (typeof responseData === 'string' || typeof responseData === 'number') { - returnData.push({ + + if (typeof responseData === 'string' || typeof responseData === 'number') { + responseData = { [this.getNodeParameter('path', i) as string]: responseData, - } as IDataObject); - } else { - returnData.push(responseData as IDataObject); + }; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts index ae16722912..5f9c9d4b4c 100644 --- a/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts +++ b/packages/nodes-base/nodes/Google/GSuiteAdmin/GSuiteAdmin.node.ts @@ -109,7 +109,7 @@ export class GSuiteAdmin implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -419,14 +419,15 @@ export class GSuiteAdmin implements INodeType { ); } } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } - - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts index 4b898b292d..e698073472 100644 --- a/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts +++ b/packages/nodes-base/nodes/Google/Gmail/Gmail.node.ts @@ -173,7 +173,7 @@ export class Gmail implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -817,23 +817,25 @@ export class Gmail implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); + + let executionData = responseData as INodeExecutionData[]; + if (!['draft', 'message'].includes(resource) && !['get', 'getAll'].includes(operation)) { + executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; } } - if (['draft', 'message'].includes(resource) && ['get', 'getAll'].includes(operation)) { - //@ts-ignore - return this.prepareOutputData(returnData); - } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Perspective/GooglePerspective.node.ts b/packages/nodes-base/nodes/Google/Perspective/GooglePerspective.node.ts index 9883b70d30..b4c783b755 100644 --- a/packages/nodes-base/nodes/Google/Perspective/GooglePerspective.node.ts +++ b/packages/nodes-base/nodes/Google/Perspective/GooglePerspective.node.ts @@ -206,7 +206,7 @@ export class GooglePerspective implements INodeType { const operation = this.getNodeParameter('operation', 0); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; for (let i = 0; i < items.length; i++) { @@ -260,17 +260,24 @@ export class GooglePerspective implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(responseData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts b/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts index 86c30beadd..76250764e3 100644 --- a/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts +++ b/packages/nodes-base/nodes/Google/Slides/GoogleSlides.node.ts @@ -411,7 +411,12 @@ export class GoogleSlides implements INodeType { 'GET', `/presentations/${presentationId}/pages/${pageObjectId}`, ); - returnData.push({ json: responseData }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getThumbnail') { // ---------------------------------- // page: getThumbnail @@ -438,14 +443,26 @@ export class GoogleSlides implements INodeType { const fileName = pageObjectId + '.png'; const binaryData = await this.helpers.prepareBinaryData(data, fileName || fileName); - returnData.push({ - json: responseData, - binary: { - [binaryProperty]: binaryData, - }, - }); + const executionData = this.helpers.constructExecutionMetaData( + [ + { + json: responseData, + binary: { + [binaryProperty]: binaryData, + }, + }, + ], + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { - returnData.push({ json: responseData }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } else if (resource === 'presentation') { @@ -463,7 +480,13 @@ export class GoogleSlides implements INodeType { }; responseData = await googleApiRequest.call(this, 'POST', '/presentations', body); - returnData.push({ json: responseData }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'get') { // ---------------------------------- // presentation: get @@ -475,7 +498,13 @@ export class GoogleSlides implements INodeType { 'GET', `/presentations/${presentationId}`, ); - returnData.push({ json: responseData }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getSlides') { // ---------------------------------- // presentation: getSlides @@ -494,7 +523,13 @@ export class GoogleSlides implements INodeType { const limit = this.getNodeParameter('limit', i) as number; responseData = responseData.slice(0, limit); } - returnData.push(...this.helpers.returnJsonArray(responseData)); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'replaceText') { // ---------------------------------- // presentation: replaceText @@ -531,18 +566,28 @@ export class GoogleSlides implements INodeType { `/presentations/${presentationId}:batchUpdate`, { requests }, ); - returnData.push({ json: responseData }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [returnData]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts b/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts index b7707cd14d..920514445d 100644 --- a/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts +++ b/packages/nodes-base/nodes/Google/Task/GoogleTasks.node.ts @@ -79,7 +79,7 @@ export class GoogleTasks implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -251,19 +251,26 @@ export class GoogleTasks implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Google/Translate/GoogleTranslate.node.ts b/packages/nodes-base/nodes/Google/Translate/GoogleTranslate.node.ts index e10cee012a..870bdd151c 100644 --- a/packages/nodes-base/nodes/Google/Translate/GoogleTranslate.node.ts +++ b/packages/nodes-base/nodes/Google/Translate/GoogleTranslate.node.ts @@ -187,7 +187,7 @@ export class GoogleTranslate implements INodeType { const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; - const responseData = []; + const responseData: INodeExecutionData[] = []; for (let i = 0; i < length; i++) { if (resource === 'language') { if (operation === 'translate') { @@ -198,10 +198,19 @@ export class GoogleTranslate implements INodeType { q: text, target: translateTo, }); - responseData.push(response.data.translations[0]); + + const [translation] = response.data.translations; + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(translation), + { itemData: { item: i } }, + ); + + responseData.push(...executionData); } } } - return [this.helpers.returnJsonArray(responseData)]; + + return this.prepareOutputData(responseData); } } diff --git a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts index bc39c572a9..fd85371001 100644 --- a/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts +++ b/packages/nodes-base/nodes/Google/YouTube/YouTube.node.ts @@ -185,7 +185,7 @@ export class YouTube implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -1099,17 +1099,24 @@ export class YouTube implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Gotify/Gotify.node.ts b/packages/nodes-base/nodes/Gotify/Gotify.node.ts index d8224dd451..dd5345082e 100644 --- a/packages/nodes-base/nodes/Gotify/Gotify.node.ts +++ b/packages/nodes-base/nodes/Gotify/Gotify.node.ts @@ -159,7 +159,7 @@ export class Gotify implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -207,19 +207,21 @@ export class Gotify implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts index 3648d0890f..116fd1c358 100644 --- a/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts +++ b/packages/nodes-base/nodes/GraphQL/GraphQL.node.ts @@ -324,6 +324,7 @@ export class GraphQL implements INodeType { let requestOptions: OptionsWithUri & RequestPromiseOptions; const returnItems: INodeExecutionData[] = []; + const responseData: IDataObject | IDataObject[] = []; for (let itemIndex = 0; itemIndex < items.length; itemIndex++) { try { const requestMethod = this.getNodeParameter('requestMethod', itemIndex, 'POST') as string; @@ -334,7 +335,6 @@ export class GraphQL implements INodeType { 'graphql', ) as string; const responseFormat = this.getNodeParameter('responseFormat', 0) as string; - const { parameter }: { parameter?: Array<{ name: string; value: string }> } = this.getNodeParameter('headerParametersUi', itemIndex, {}) as IDataObject; const headerParameters = (parameter || []).reduce( @@ -433,8 +433,7 @@ export class GraphQL implements INodeType { } if (responseFormat === 'string') { const dataPropertyName = this.getNodeParameter('dataPropertyName', 0) as string; - - returnItems.push({ + responseData.push({ json: { [dataPropertyName]: response, }, @@ -458,12 +457,23 @@ export class GraphQL implements INodeType { 'Unexpected error'; throw new NodeApiError(this.getNode(), response.errors, { message }); } - - returnItems.push({ json: response }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: itemIndex } }, + ); + returnItems.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnItems.push({ json: { error: (error as JsonObject).message } }); + const errorData = this.helpers.returnJsonArray({ + $error: error, + json: this.getInputData(itemIndex), + itemIndex, + }); + const exectionErrorWithMetaData = this.helpers.constructExecutionMetaData(errorData, { + itemData: { item: itemIndex }, + }); + returnItems.push(...exectionErrorWithMetaData); continue; } throw error; diff --git a/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts b/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts index 4f38854175..148570b16c 100644 --- a/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts +++ b/packages/nodes-base/nodes/HackerNews/HackerNews.node.ts @@ -263,7 +263,7 @@ export class HackerNews implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -342,20 +342,25 @@ export class HackerNews implements INodeType { delete responseData.children; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/HaloPSA/HaloPSA.node.ts b/packages/nodes-base/nodes/HaloPSA/HaloPSA.node.ts index dcb6930a21..bd853ec85c 100644 --- a/packages/nodes-base/nodes/HaloPSA/HaloPSA.node.ts +++ b/packages/nodes-base/nodes/HaloPSA/HaloPSA.node.ts @@ -218,7 +218,7 @@ export class HaloPSA implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const tokens = await getAccessTokens.call(this); @@ -664,20 +664,25 @@ export class HaloPSA implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else if (responseData !== undefined) { - returnData.push(responseData); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Harvest/Harvest.node.ts b/packages/nodes-base/nodes/Harvest/Harvest.node.ts index 7e6923db91..1dc7db7eee 100644 --- a/packages/nodes-base/nodes/Harvest/Harvest.node.ts +++ b/packages/nodes-base/nodes/Harvest/Harvest.node.ts @@ -202,7 +202,7 @@ export class Harvest implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -229,13 +229,23 @@ export class Harvest implements INodeType { endpoint = `time_entries/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'time_entries', i); - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'createByStartEnd') { // ---------------------------------- // createByStartEnd @@ -258,7 +268,12 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'createByDuration') { // ---------------------------------- // createByDuration @@ -281,7 +296,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -292,7 +313,13 @@ export class Harvest implements INodeType { endpoint = `time_entries/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'deleteExternal') { // ---------------------------------- // deleteExternal @@ -303,7 +330,13 @@ export class Harvest implements INodeType { endpoint = `time_entries/${id}/external_reference`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'restartTime') { // ---------------------------------- // restartTime @@ -314,7 +347,13 @@ export class Harvest implements INodeType { endpoint = `time_entries/${id}/restart`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'stopTime') { // ---------------------------------- // stopTime @@ -325,7 +364,13 @@ export class Harvest implements INodeType { endpoint = `time_entries/${id}/stop`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -345,7 +390,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -365,14 +416,26 @@ export class Harvest implements INodeType { endpoint = `clients/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'clients', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -393,7 +456,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -413,7 +482,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -424,7 +499,13 @@ export class Harvest implements INodeType { endpoint = `clients/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -444,14 +525,26 @@ export class Harvest implements INodeType { endpoint = `projects/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'projects', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -476,7 +569,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -496,7 +595,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -507,7 +612,13 @@ export class Harvest implements INodeType { endpoint = `projects/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -527,14 +638,26 @@ export class Harvest implements INodeType { endpoint = `users/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'users', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'me') { // ---------------------------------- // me @@ -545,7 +668,13 @@ export class Harvest implements INodeType { endpoint = `users/me`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -568,7 +697,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -588,7 +723,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -599,7 +740,13 @@ export class Harvest implements INodeType { endpoint = `users/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -619,14 +766,26 @@ export class Harvest implements INodeType { endpoint = `contacts/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'contacts', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -648,7 +807,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -668,7 +833,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -679,7 +850,13 @@ export class Harvest implements INodeType { endpoint = `contacts/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -697,7 +874,13 @@ export class Harvest implements INodeType { endpoint = `company`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -717,14 +900,26 @@ export class Harvest implements INodeType { endpoint = `tasks/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'tasks', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -745,7 +940,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -765,7 +966,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -776,7 +983,13 @@ export class Harvest implements INodeType { endpoint = `tasks/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -796,14 +1009,26 @@ export class Harvest implements INodeType { endpoint = `invoices/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'invoices', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -824,7 +1049,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -844,7 +1075,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -855,7 +1092,13 @@ export class Harvest implements INodeType { endpoint = `invoices/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -875,14 +1118,26 @@ export class Harvest implements INodeType { endpoint = `expenses/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'expenses', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -905,7 +1160,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -925,7 +1186,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -936,7 +1203,13 @@ export class Harvest implements INodeType { endpoint = `expenses/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -956,14 +1229,26 @@ export class Harvest implements INodeType { endpoint = `estimates/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'getAll') { // ---------------------------------- // getAll // ---------------------------------- const responseData: IDataObject[] = await getAllResource.call(this, 'estimates', i); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'create') { // ---------------------------------- // create @@ -984,7 +1269,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'update') { // ---------------------------------- // update @@ -1004,7 +1295,13 @@ export class Harvest implements INodeType { endpoint, body, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (operation === 'delete') { // ---------------------------------- // delete @@ -1015,7 +1312,13 @@ export class Harvest implements INodeType { endpoint = `estimates/${id}`; const responseData = await harvestApiRequest.call(this, requestMethod, qs, endpoint); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { throw new NodeOperationError( this.getNode(), @@ -1030,13 +1333,18 @@ export class Harvest implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts b/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts index d19a076671..70a6b0a9ec 100644 --- a/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts +++ b/packages/nodes-base/nodes/HelpScout/HelpScout.node.ts @@ -147,7 +147,7 @@ export class HelpScout implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -559,17 +559,24 @@ export class HelpScout implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts index e77aff9e1f..a57cf2d321 100644 --- a/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts +++ b/packages/nodes-base/nodes/Hubspot/Hubspot.node.ts @@ -929,7 +929,7 @@ export class Hubspot implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -979,7 +979,7 @@ export class Hubspot implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + returnData.push({ json: { error: (error as JsonObject).message } }); } else { throw error; } @@ -1367,6 +1367,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.contacts; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developers.hubspot.com/docs/methods/contacts/get_recently_created_contacts if (operation === 'getRecentlyCreatedUpdated') { @@ -1402,6 +1406,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.contacts; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developers.hubspot.com/docs/methods/contacts/delete_contact if (operation === 'delete') { @@ -1462,6 +1470,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } //https://developers.hubspot.com/docs/methods/companies/companies-overview @@ -1956,6 +1968,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.companies; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developers.hubspot.com/docs/methods/companies/get_companies_modified if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { @@ -1984,6 +2000,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developers.hubspot.com/docs/methods/companies/search_companies_by_domain if (operation === 'searchByDomain') { @@ -2010,6 +2030,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developers.hubspot.com/docs/methods/companies/delete_company if (operation === 'delete') { @@ -2194,6 +2218,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.deals; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'getRecentlyCreated' || operation === 'getRecentlyModified') { let endpoint; @@ -2224,6 +2252,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'delete') { const dealId = this.getNodeParameter('dealId', i) as string; @@ -2283,6 +2315,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'POST', endpoint, body, qs); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } if (resource === 'engagement') { @@ -2369,6 +2405,10 @@ export class Hubspot implements INodeType { responseData = await hubspotApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.results; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } //https://developers.hubspot.com/docs/methods/forms/forms_overview @@ -2723,20 +2763,20 @@ export class Hubspot implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + returnData.push({ json: { error: (error as JsonObject).message } }); continue; } throw error; } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Hunter/Hunter.node.ts b/packages/nodes-base/nodes/Hunter/Hunter.node.ts index 15f57573f8..dfa149dddf 100644 --- a/packages/nodes-base/nodes/Hunter/Hunter.node.ts +++ b/packages/nodes-base/nodes/Hunter/Hunter.node.ts @@ -268,7 +268,7 @@ export class Hunter implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -359,19 +359,26 @@ export class Hunter implements INodeType { responseData = await hunterApiRequest.call(this, 'GET', '/email-verifier', {}, qs); responseData = responseData.data; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Intercom/Intercom.node.ts b/packages/nodes-base/nodes/Intercom/Intercom.node.ts index 64a9c64470..eefa1835c4 100644 --- a/packages/nodes-base/nodes/Intercom/Intercom.node.ts +++ b/packages/nodes-base/nodes/Intercom/Intercom.node.ts @@ -101,7 +101,7 @@ export class Intercom implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let qs: IDataObject; let responseData; @@ -613,19 +613,26 @@ export class Intercom implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts index 0a4af25b5d..4d0006cdc7 100644 --- a/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts +++ b/packages/nodes-base/nodes/InvoiceNinja/InvoiceNinja.node.ts @@ -217,7 +217,7 @@ export class InvoiceNinja implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -883,19 +883,26 @@ export class InvoiceNinja implements INodeType { responseData = responseData.data; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Jira/Jira.node.ts b/packages/nodes-base/nodes/Jira/Jira.node.ts index f5d159cfa7..1dab46e0a1 100644 --- a/packages/nodes-base/nodes/Jira/Jira.node.ts +++ b/packages/nodes-base/nodes/Jira/Jira.node.ts @@ -441,7 +441,7 @@ export class Jira implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -547,7 +547,13 @@ export class Jira implements INodeType { } body.fields = fields; responseData = await jiraSoftwareCloudApiRequest.call(this, '/api/2/issue', 'POST', body); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-put @@ -655,7 +661,12 @@ export class Jira implements INodeType { 'PUT', body, ); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get @@ -704,9 +715,19 @@ export class Jira implements INodeType { (a, b) => (b === null ? a : b), ); } - returnData.push(simplifyIssueOutput(responseData)); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(simplifyIssueOutput(responseData)), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } @@ -748,7 +769,13 @@ export class Jira implements INodeType { ); responseData = responseData.issues; } - returnData.push(...responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-changelog-get @@ -774,7 +801,13 @@ export class Jira implements INodeType { ); responseData = responseData.values; } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-notify-post @@ -874,7 +907,13 @@ export class Jira implements INodeType { body, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-transitions-get @@ -899,7 +938,13 @@ export class Jira implements INodeType { qs, ); responseData = responseData.transitions; - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-delete @@ -915,7 +960,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push({ success: true }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } @@ -965,7 +1016,13 @@ export class Jira implements INodeType { }, }, ); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-attachment-id-delete @@ -979,7 +1036,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push({ success: true }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-attachments/#api-rest-api-3-attachment-id-get @@ -994,7 +1057,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push({ json: responseData }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (download) { const binaryPropertyName = this.getNodeParameter('binaryProperty', 0) as string; @@ -1042,7 +1111,13 @@ export class Jira implements INodeType { responseData = responseData.slice(0, limit); } responseData = responseData.map((data: IDataObject) => ({ json: data })); - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (download) { const binaryPropertyName = this.getNodeParameter('binaryProperty', 0) as string; @@ -1130,7 +1205,13 @@ export class Jira implements INodeType { body, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v2/#api-rest-api-2-issue-issueIdOrKey-get @@ -1147,7 +1228,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-get @@ -1179,7 +1266,13 @@ export class Jira implements INodeType { ); responseData = responseData.comments; } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-id-delete @@ -1194,7 +1287,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push({ success: true }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } //https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-issue-comments/#api-rest-api-3-issue-issueidorkey-comment-id-put @@ -1251,7 +1350,13 @@ export class Jira implements INodeType { body, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } @@ -1279,7 +1384,13 @@ export class Jira implements INodeType { body, {}, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else if (operation === 'delete') { // https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-users/#api-rest-api-3-user-delete @@ -1292,7 +1403,13 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push({ success: true }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else if (operation === 'get') { // https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-users/#api-rest-api-3-user-get @@ -1312,15 +1429,17 @@ export class Jira implements INodeType { {}, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } - if (resource === 'issueAttachment' && (operation === 'getAll' || operation === 'get')) { - return this.prepareOutputData(returnData as unknown as INodeExecutionData[]); - } else { - return [this.helpers.returnJsonArray(returnData)]; - } + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Keap/Keap.node.ts b/packages/nodes-base/nodes/Keap/Keap.node.ts index ed8691ee8c..ad47dcac19 100644 --- a/packages/nodes-base/nodes/Keap/Keap.node.ts +++ b/packages/nodes-base/nodes/Keap/Keap.node.ts @@ -245,7 +245,7 @@ export class Keap implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -858,12 +858,15 @@ export class Keap implements INodeType { responseData = await keapApiRequest.call(this, 'POST', '/files', body); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Kitemaker/Kitemaker.node.ts b/packages/nodes-base/nodes/Kitemaker/Kitemaker.node.ts index 29bddeff27..a11ca066f2 100644 --- a/packages/nodes-base/nodes/Kitemaker/Kitemaker.node.ts +++ b/packages/nodes-base/nodes/Kitemaker/Kitemaker.node.ts @@ -174,7 +174,7 @@ export class Kitemaker implements INodeType { const operation = this.getNodeParameter('operation', 0); let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; // https://github.com/kitemakerhq/docs/blob/main/kitemaker.graphql @@ -193,7 +193,7 @@ export class Kitemaker implements INodeType { query: getOrganization, }); - returnData.push(responseData.data.organization); + responseData = responseData.data.organization; } } else if (resource === 'space') { // ********************************************************************* @@ -210,7 +210,7 @@ export class Kitemaker implements INodeType { variables: {}, }); - returnData.push(...allItems); + responseData = allItems; } } else if (resource === 'user') { // ********************************************************************* @@ -227,7 +227,7 @@ export class Kitemaker implements INodeType { variables: {}, }); - returnData.push(...allItems); + responseData = allItems; } } else if (resource === 'workItem') { // ********************************************************************* @@ -263,7 +263,7 @@ export class Kitemaker implements INodeType { variables: { input }, }); - returnData.push(responseData.data.createWorkItem.workItem); + responseData = responseData.data.createWorkItem.workItem; } else if (operation === 'get') { // ---------------------------------- // workItem: get @@ -276,7 +276,7 @@ export class Kitemaker implements INodeType { variables: { workItemId }, }); - returnData.push(responseData.data.workItem); + responseData = responseData.data.workItem; } else if (operation === 'getAll') { // ---------------------------------- // workItem: getAll @@ -289,7 +289,7 @@ export class Kitemaker implements INodeType { }, }); - returnData.push(...allItems); + responseData = allItems; } else if (operation === 'update') { // ---------------------------------- // workItem: update @@ -316,11 +316,18 @@ export class Kitemaker implements INodeType { variables: { input }, }); - returnData.push(responseData.data.editWorkItem.workItem); + responseData = responseData.data.editWorkItem.workItem; } } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Lemlist/Lemlist.node.ts b/packages/nodes-base/nodes/Lemlist/Lemlist.node.ts index 4b49b23865..1aad1d4ef9 100644 --- a/packages/nodes-base/nodes/Lemlist/Lemlist.node.ts +++ b/packages/nodes-base/nodes/Lemlist/Lemlist.node.ts @@ -1,6 +1,12 @@ import { IExecuteFunctions } from 'n8n-core'; -import { IDataObject, ILoadOptionsFunctions, INodeType, INodeTypeDescription } from 'n8n-workflow'; +import { + IDataObject, + ILoadOptionsFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, +} from 'n8n-workflow'; import { activityFields, @@ -101,7 +107,7 @@ export class Lemlist implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -282,18 +288,25 @@ export class Lemlist implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.toString() }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Line/Line.node.ts b/packages/nodes-base/nodes/Line/Line.node.ts index b66cf3d408..ee5460fa09 100644 --- a/packages/nodes-base/nodes/Line/Line.node.ts +++ b/packages/nodes-base/nodes/Line/Line.node.ts @@ -60,7 +60,7 @@ export class Line implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -143,19 +143,24 @@ export class Line implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Linear/Linear.node.ts b/packages/nodes-base/nodes/Linear/Linear.node.ts index 7052ffe041..4aab27ccc8 100644 --- a/packages/nodes-base/nodes/Linear/Linear.node.ts +++ b/packages/nodes-base/nodes/Linear/Linear.node.ts @@ -156,7 +156,7 @@ export class Linear implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -237,21 +237,25 @@ export class Linear implements INodeType { responseData = responseData?.data?.issueUpdate?.issue; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ - error: (error as JsonObject).message, - }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Magento/Magento2.node.ts b/packages/nodes-base/nodes/Magento/Magento2.node.ts index 4441b771b4..9de582f327 100644 --- a/packages/nodes-base/nodes/Magento/Magento2.node.ts +++ b/packages/nodes-base/nodes/Magento/Magento2.node.ts @@ -312,7 +312,7 @@ export class Magento2 implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const timezone = this.getTimezone(); let responseData; @@ -378,7 +378,7 @@ export class Magento2 implements INodeType { body.password = password; } - Object.assign(body.customer, rest); + Object.assign(body.customer!, rest); responseData = await magentoApiRequest.call(this, 'POST', '/rest/V1/customers', body); } @@ -524,7 +524,7 @@ export class Magento2 implements INodeType { body.password = password; } - Object.assign(body.customer, rest); + Object.assign(body.customer!, rest); responseData = await magentoApiRequest.call( this, @@ -675,7 +675,7 @@ export class Magento2 implements INodeType { body.product!.custom_attributes = customAttributes?.customAttribute || {}; - Object.assign(body.product, rest); + Object.assign(body.product!, rest); responseData = await magentoApiRequest.call( this, @@ -790,7 +790,7 @@ export class Magento2 implements INodeType { body.product!.custom_attributes = customAttributes?.customAttribute || {}; - Object.assign(body.product, rest); + Object.assign(body.product!, rest); responseData = await magentoApiRequest.call( this, @@ -801,18 +801,25 @@ export class Magento2 implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts index f41a49d542..17c72f7c69 100644 --- a/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts +++ b/packages/nodes-base/nodes/Mailchimp/Mailchimp.node.ts @@ -1674,7 +1674,7 @@ export class Mailchimp implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -2185,19 +2185,19 @@ export class Mailchimp implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts index 1e10572d41..2c0d73197f 100644 --- a/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts +++ b/packages/nodes-base/nodes/MailerLite/MailerLite.node.ts @@ -73,7 +73,7 @@ export class MailerLite implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -183,17 +183,24 @@ export class MailerLite implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts index faef4f5aae..2cb22c085c 100644 --- a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts +++ b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts @@ -184,12 +184,19 @@ export class Mailgun implements INodeType { throw new NodeApiError(this.getNode(), error); } - returnData.push({ - json: responseData, - }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: itemIndex } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: itemIndex } }, + ); + returnData.push(...executionErrorData); continue; } throw error; diff --git a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts index 01f7d4bb89..9232b4763a 100644 --- a/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts +++ b/packages/nodes-base/nodes/Mailjet/Mailjet.node.ts @@ -95,7 +95,7 @@ export class Mailjet implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const resource = this.getNodeParameter('resource', 0) as string; @@ -303,19 +303,26 @@ export class Mailjet implements INodeType { responseData = await mailjetApiRequest.call(this, 'POST', '/v4/sms-send', body); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts b/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts index 69e6b576fd..4752805f2f 100644 --- a/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts +++ b/packages/nodes-base/nodes/Mandrill/Mandrill.node.ts @@ -711,7 +711,7 @@ export class Mandrill implements INodeType { }; async execute(this: IExecuteFunctions): Promise { - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const items = this.getInputData(); let responseData; let emailSentResponse; @@ -884,19 +884,25 @@ export class Mandrill implements INodeType { responseData = await emailSentResponse; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Marketstack/Marketstack.node.ts b/packages/nodes-base/nodes/Marketstack/Marketstack.node.ts index 2fb0740c22..3abf8dc1b4 100644 --- a/packages/nodes-base/nodes/Marketstack/Marketstack.node.ts +++ b/packages/nodes-base/nodes/Marketstack/Marketstack.node.ts @@ -88,7 +88,7 @@ export class Marketstack implements INodeType { const operation = this.getNodeParameter('operation', 0) as Operation; let responseData: any; // tslint:disable-line: no-any - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -163,17 +163,24 @@ export class Marketstack implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Mattermost/v1/actions/router.ts b/packages/nodes-base/nodes/Mattermost/v1/actions/router.ts index 5acf0db323..6dbaef17d2 100644 --- a/packages/nodes-base/nodes/Mattermost/v1/actions/router.ts +++ b/packages/nodes-base/nodes/Mattermost/v1/actions/router.ts @@ -1,6 +1,9 @@ import { IExecuteFunctions } from 'n8n-core'; -import { INodeExecutionData } from 'n8n-workflow'; +import { + IDataObject, + INodeExecutionData, +} from 'n8n-workflow'; import * as channel from './channel'; import * as message from './message'; @@ -11,6 +14,7 @@ import { Mattermost } from './Interfaces'; export async function router(this: IExecuteFunctions): Promise { const items = this.getInputData(); const operationResult: INodeExecutionData[] = []; + let responseData: IDataObject | IDataObject[] = []; for (let i = 0; i < items.length; i++) { const resource = this.getNodeParameter('resource', i); @@ -28,14 +32,20 @@ export async function router(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let qs: IDataObject; let responseData; @@ -1018,20 +1018,20 @@ export class Mautic implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + returnData.push({ json: { error: (error as JsonObject).message }}); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.ts b/packages/nodes-base/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.ts index 9ba08ba056..925294c3fb 100644 --- a/packages/nodes-base/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Dynamics/MicrosoftDynamicsCrm.node.ts @@ -146,7 +146,7 @@ export class MicrosoftDynamicsCrm implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -277,20 +277,25 @@ export class MicrosoftDynamicsCrm implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push(...responseData); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts b/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts index 19ed434ccd..295178adca 100644 --- a/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Excel/MicrosoftExcel.node.ts @@ -164,7 +164,7 @@ export class MicrosoftExcel implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let qs: IDataObject = {}; const result: IDataObject[] = []; @@ -235,14 +235,19 @@ export class MicrosoftExcel implements INodeType { { 'workbook-session-id': id }, ); - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: 0 } }, + ); + returnData.push(...executionErrorData); } else { throw error; } @@ -291,14 +296,19 @@ export class MicrosoftExcel implements INodeType { responseData = { [dataProperty]: responseData }; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -361,15 +371,29 @@ export class MicrosoftExcel implements INodeType { for (let y = 0; y < columns.length; y++) { object[columns[y]] = responseData[i].values[0][y]; } - returnData.push({ ...object }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ ...object }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else { const dataProperty = this.getNodeParameter('dataProperty', i) as string; - returnData.push({ [dataProperty]: responseData }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ [dataProperty]: responseData }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -427,16 +451,30 @@ export class MicrosoftExcel implements INodeType { responseData = result.filter((data: IDataObject) => { return data[lookupColumn]?.toString() === lookupValue; }); - returnData.push.apply(returnData, responseData as IDataObject[]); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else { responseData = result.find((data: IDataObject) => { return data[lookupColumn]?.toString() === lookupValue; }); - returnData.push(responseData as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData as IDataObject), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -510,13 +548,27 @@ export class MicrosoftExcel implements INodeType { } if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -591,16 +643,30 @@ export class MicrosoftExcel implements INodeType { for (let y = 0; y < keyValues.length; y++) { object[keyValues[y]] = responseData.values[i][y]; } - returnData.push({ ...object }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ ...object }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } else { const dataProperty = this.getNodeParameter('dataProperty', i) as string; - returnData.push({ [dataProperty]: responseData }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ [dataProperty]: responseData }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -608,6 +674,6 @@ export class MicrosoftExcel implements INodeType { } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts index 070df98c7d..9b24420fea 100644 --- a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts +++ b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts @@ -63,7 +63,7 @@ export class MicrosoftOneDrive implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -95,14 +95,12 @@ export class MicrosoftOneDrive implements INodeType { { json: true, resolveWithFullResponse: true }, ); responseData = { location: responseData.headers.location }; - returnData.push(responseData as IDataObject); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online if (operation === 'delete') { const fileId = this.getNodeParameter('fileId', i) as string; responseData = await microsoftApiRequest.call(this, 'DELETE', `/drive/items/${fileId}`); responseData = { success: true }; - returnData.push(responseData as IDataObject); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online if (operation === 'download') { @@ -150,7 +148,7 @@ export class MicrosoftOneDrive implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -167,7 +165,6 @@ export class MicrosoftOneDrive implements INodeType { if (operation === 'get') { const fileId = this.getNodeParameter('fileId', i) as string; responseData = await microsoftApiRequest.call(this, 'GET', `/drive/items/${fileId}`); - returnData.push(responseData as IDataObject); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online if (operation === 'search') { @@ -179,7 +176,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/root/search(q='${query}')`, ); responseData = responseData.filter((item: IDataObject) => item.file); - returnData.push.apply(returnData, responseData as IDataObject[]); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online if (operation === 'share') { @@ -196,7 +192,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/items/${fileId}/createLink`, body, ); - returnData.push(responseData); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_put_content?view=odsp-graph-online#example-upload-a-new-file if (operation === 'upload') { @@ -244,7 +239,7 @@ export class MicrosoftOneDrive implements INodeType { {}, ); - returnData.push(JSON.parse(responseData) as IDataObject); + responseData = JSON.parse(responseData); } else { const body = this.getNodeParameter('fileContent', i) as string; if (fileName === '') { @@ -262,7 +257,6 @@ export class MicrosoftOneDrive implements INodeType { undefined, { 'Content-Type': 'text/plain' }, ); - returnData.push(responseData as IDataObject); } } } @@ -289,7 +283,6 @@ export class MicrosoftOneDrive implements INodeType { } parentFolderId = responseData.id; } - returnData.push(responseData); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_delete?view=odsp-graph-online if (operation === 'delete') { @@ -300,7 +293,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/items/${folderId}`, ); responseData = { success: true }; - returnData.push(responseData as IDataObject); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_list_children?view=odsp-graph-online if (operation === 'getChildren') { @@ -311,7 +303,6 @@ export class MicrosoftOneDrive implements INodeType { 'GET', `/drive/items/${folderId}/children`, ); - returnData.push.apply(returnData, responseData as IDataObject[]); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_search?view=odsp-graph-online if (operation === 'search') { @@ -323,7 +314,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/root/search(q='${query}')`, ); responseData = responseData.filter((item: IDataObject) => item.folder); - returnData.push.apply(returnData, responseData as IDataObject[]); } //https://docs.microsoft.com/en-us/onedrive/developer/rest-api/api/driveitem_createlink?view=odsp-graph-online if (operation === 'share') { @@ -340,7 +330,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/items/${folderId}/createLink`, body, ); - returnData.push(responseData); } } if (resource === 'file' || resource === 'folder') { @@ -354,7 +343,6 @@ export class MicrosoftOneDrive implements INodeType { `/drive/items/${itemId}`, body, ); - returnData.push(responseData as IDataObject); } } } catch (error) { @@ -362,18 +350,28 @@ export class MicrosoftOneDrive implements INodeType { if (resource === 'file' && operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } continue; } throw error; } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (resource === 'file' && operation === 'download') { // For file downloads the files get attached to the existing items return this.prepareOutputData(items); - } else { - return [this.helpers.returnJsonArray(returnData)]; } + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts index 3db94d95f4..a415689f39 100644 --- a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts @@ -452,7 +452,7 @@ export class MicrosoftOutlook implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -783,7 +783,7 @@ export class MicrosoftOutlook implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; diff --git a/packages/nodes-base/nodes/Microsoft/Sql/MicrosoftSql.node.ts b/packages/nodes-base/nodes/Microsoft/Sql/MicrosoftSql.node.ts index df1326ec09..fe0bebb7e0 100644 --- a/packages/nodes-base/nodes/Microsoft/Sql/MicrosoftSql.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Sql/MicrosoftSql.node.ts @@ -234,7 +234,8 @@ export class MicrosoftSql implements INodeType { const pool = new mssql.ConnectionPool(config); await pool.connect(); - let returnItems = []; + const returnItems: INodeExecutionData[] = []; + let responseData: IDataObject | IDataObject[] = []; const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0) as string; @@ -254,7 +255,7 @@ export class MicrosoftSql implements INodeType { ? flatten(queryResult.recordsets) : queryResult.recordsets[0]; - returnItems = this.helpers.returnJsonArray(result as IDataObject[]); + responseData = result; } else if (operation === 'insert') { // ---------------------------------- // insert @@ -281,7 +282,7 @@ export class MicrosoftSql implements INodeType { }, ); - returnItems = items; + responseData = items; } else if (operation === 'update') { // ---------------------------------- // update @@ -318,7 +319,7 @@ export class MicrosoftSql implements INodeType { }, ); - returnItems = items; + responseData = items; } else if (operation === 'delete') { // ---------------------------------- // delete @@ -368,9 +369,7 @@ export class MicrosoftSql implements INodeType { 0, ); - returnItems = this.helpers.returnJsonArray({ - rowsDeleted, - } as IDataObject); + responseData = rowsDeleted; } else { await pool.close(); throw new NodeOperationError( @@ -380,7 +379,7 @@ export class MicrosoftSql implements INodeType { } } catch (error) { if (this.continueOnFail() === true) { - returnItems = items; + responseData = items; } else { await pool.close(); throw error; @@ -389,7 +388,12 @@ export class MicrosoftSql implements INodeType { // Close the connection await pool.close(); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + returnItems.push(...executionData); return this.prepareOutputData(returnItems); } } diff --git a/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts b/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts index 447253832a..540b08602a 100644 --- a/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Teams/MicrosoftTeams.node.ts @@ -260,7 +260,7 @@ export class MicrosoftTeams implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -626,19 +626,25 @@ export class MicrosoftTeams implements INodeType { responseData = { success: true }; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Microsoft/ToDo/MicrosoftToDo.node.ts b/packages/nodes-base/nodes/Microsoft/ToDo/MicrosoftToDo.node.ts index 24579c948c..182a27f44e 100644 --- a/packages/nodes-base/nodes/Microsoft/ToDo/MicrosoftToDo.node.ts +++ b/packages/nodes-base/nodes/Microsoft/ToDo/MicrosoftToDo.node.ts @@ -91,7 +91,7 @@ export class MicrosoftToDo implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -399,15 +399,23 @@ export class MicrosoftToDo implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Misp/Misp.node.ts b/packages/nodes-base/nodes/Misp/Misp.node.ts index 33bdad94c6..76c9d0ecfd 100644 --- a/packages/nodes-base/nodes/Misp/Misp.node.ts +++ b/packages/nodes-base/nodes/Misp/Misp.node.ts @@ -169,7 +169,7 @@ export class Misp implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -729,17 +729,24 @@ export class Misp implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts b/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts index 41464e37f2..e083152107 100644 --- a/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts +++ b/packages/nodes-base/nodes/MondayCom/MondayCom.node.ts @@ -227,7 +227,7 @@ export class MondayCom implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -728,19 +728,25 @@ export class MondayCom implements INodeType { responseData = responseData.data.move_item_to_group; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts b/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts index 79664d8fc4..7bb4c4ea83 100644 --- a/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts +++ b/packages/nodes-base/nodes/MongoDb/MongoDb.node.ts @@ -36,7 +36,8 @@ export class MongoDb implements INodeType { const mdb = client.db(database as string); - let returnItems = []; + const returnItems: INodeExecutionData[] = []; + let responseData: IDataObject | IDataObject[] = []; const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0) as string; @@ -57,12 +58,11 @@ export class MongoDb implements INodeType { .collection(this.getNodeParameter('collection', 0) as string) .aggregate(queryParameter); - const queryResult = await query.toArray(); + responseData = await query.toArray(); - returnItems = this.helpers.returnJsonArray(queryResult as IDataObject[]); } catch (error) { if (this.continueOnFail()) { - returnItems = this.helpers.returnJsonArray({ error: (error as JsonObject).message }); + responseData = [ { error: (error as JsonObject).message } ]; } else { throw error; } @@ -77,10 +77,10 @@ export class MongoDb implements INodeType { .collection(this.getNodeParameter('collection', 0) as string) .deleteMany(JSON.parse(this.getNodeParameter('query', 0) as string)); - returnItems = this.helpers.returnJsonArray([{ deletedCount }]); + responseData = [{ deletedCount }]; } catch (error) { if (this.continueOnFail()) { - returnItems = this.helpers.returnJsonArray({ error: (error as JsonObject).message }); + responseData = [{ error: (error as JsonObject).message }]; } else { throw error; } @@ -116,10 +116,10 @@ export class MongoDb implements INodeType { } const queryResult = await query.toArray(); - returnItems = this.helpers.returnJsonArray(queryResult as IDataObject[]); + responseData = queryResult; } catch (error) { if (this.continueOnFail()) { - returnItems = this.helpers.returnJsonArray({ error: (error as JsonObject).message }); + responseData = [{ error: (error as JsonObject).message }]; } else { throw error; } @@ -150,16 +150,14 @@ export class MongoDb implements INodeType { // Add the id to the data for (const i of Object.keys(insertedIds)) { - returnItems.push({ - json: { - ...insertItems[parseInt(i, 10)], - id: insertedIds[parseInt(i, 10)] as string, - }, + responseData.push({ + ...insertItems[parseInt(i, 10)], + id: insertedIds[parseInt(i, 10)] as string, }); } } catch (error) { if (this.continueOnFail()) { - returnItems = this.helpers.returnJsonArray({ error: (error as JsonObject).message }); + responseData = [{ error: (error as JsonObject).message }]; } else { throw error; } @@ -219,21 +217,25 @@ export class MongoDb implements INodeType { throw error; } } - returnItems = this.helpers.returnJsonArray(updateItems as IDataObject[]); + + responseData = updateItems; } else { if (this.continueOnFail()) { - returnItems = this.helpers.returnJsonArray({ - json: { error: `The operation "${operation}" is not supported!` }, - }); + responseData = [{ error: `The operation "${operation}" is not supported!` }]; } else { - throw new NodeOperationError( - this.getNode(), - `The operation "${operation}" is not supported!`, - ); + throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not supported!`, {itemIndex: 0}); } } client.close(); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnItems.push(...executionData); + return this.prepareOutputData(returnItems); } } diff --git a/packages/nodes-base/nodes/MonicaCrm/MonicaCrm.node.ts b/packages/nodes-base/nodes/MonicaCrm/MonicaCrm.node.ts index a549bf8121..e6229d88a8 100644 --- a/packages/nodes-base/nodes/MonicaCrm/MonicaCrm.node.ts +++ b/packages/nodes-base/nodes/MonicaCrm/MonicaCrm.node.ts @@ -209,7 +209,7 @@ export class MonicaCrm implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -1150,7 +1150,11 @@ export class MonicaCrm implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } @@ -1161,11 +1165,14 @@ export class MonicaCrm implements INodeType { responseData = responseData.data; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/MySql/MySql.node.ts b/packages/nodes-base/nodes/MySql/MySql.node.ts index b2d86c7c2a..75885d598e 100644 --- a/packages/nodes-base/nodes/MySql/MySql.node.ts +++ b/packages/nodes-base/nodes/MySql/MySql.node.ts @@ -228,7 +228,7 @@ export class MySql implements INodeType { const connection = await mysql2.createConnection(baseCredentials); const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0) as string; - let returnItems = []; + let returnItems: INodeExecutionData[] = []; if (operation === 'executeQuery') { // ---------------------------------- @@ -242,22 +242,19 @@ export class MySql implements INodeType { return connection.query(rawQuery); }); - const queryResult = ((await Promise.all(queryQueue)) as mysql2.OkPacket[][]).reduce( - (collection, result) => { - const [rows, fields] = result; + returnItems = (await Promise.all(queryQueue) as mysql2.OkPacket[][]).reduce((collection, result, index) => { + const [rows] = result; - if (Array.isArray(rows)) { - return collection.concat(rows); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(rows as unknown as IDataObject[]), + { itemData: { item: index } }, + ); - collection.push(rows); + collection.push(...executionData); - return collection; - }, - [], - ); + return collection; + }, [] as INodeExecutionData[]); - returnItems = this.helpers.returnJsonArray(queryResult as unknown as IDataObject[]); } catch (error) { if (this.continueOnFail()) { returnItems = this.helpers.returnJsonArray({ error: error.message }); diff --git a/packages/nodes-base/nodes/Nasa/Nasa.node.ts b/packages/nodes-base/nodes/Nasa/Nasa.node.ts index b5c6c7a471..5aabdae0b2 100644 --- a/packages/nodes-base/nodes/Nasa/Nasa.node.ts +++ b/packages/nodes-base/nodes/Nasa/Nasa.node.ts @@ -848,7 +848,7 @@ export class Nasa implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; @@ -1060,7 +1060,7 @@ export class Nasa implements INodeType { }; if (items[i].binary !== undefined) { - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -1093,7 +1093,7 @@ export class Nasa implements INodeType { Object.assign(newItem.json, responseData); if (items[i].binary !== undefined) { - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -1105,11 +1105,12 @@ export class Nasa implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { if (resource === 'earthImagery' && operation === 'get') { @@ -1121,7 +1122,11 @@ export class Nasa implements INodeType { ) { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } continue; } @@ -1138,7 +1143,7 @@ export class Nasa implements INodeType { ) { return this.prepareOutputData(items); } else { - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Netlify/Netlify.node.ts b/packages/nodes-base/nodes/Netlify/Netlify.node.ts index c700069bbd..79ab74817f 100644 --- a/packages/nodes-base/nodes/Netlify/Netlify.node.ts +++ b/packages/nodes-base/nodes/Netlify/Netlify.node.ts @@ -81,7 +81,7 @@ export class Netlify implements INodeType { const items = this.getInputData(); const length = items.length; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const qs: IDataObject = {}; const body: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; @@ -187,20 +187,26 @@ export class Netlify implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts index 9100150cdd..7644ce1ba8 100644 --- a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts +++ b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts @@ -378,66 +378,63 @@ export class NocoDB implements INodeType { const data = []; const downloadAttachments = this.getNodeParameter('downloadAttachments', 0) as boolean; try { - for (let i = 0; i < items.length; i++) { - requestMethod = 'GET'; + for (let i = 0; i < items.length; i++) { + requestMethod = 'GET'; - if (version === 1) { - endPoint = `/nc/${projectId}/api/v1/${table}`; - } else if (version === 2) { - endPoint = `/api/v1/db/data/noco/${projectId}/${table}`; + if (version === 1) { + endPoint = `/nc/${projectId}/api/v1/${table}`; + } else if (version === 2) { + endPoint = `/api/v1/db/data/noco/${projectId}/${table}`; + } + + returnAll = this.getNodeParameter('returnAll', 0) as boolean; + qs = this.getNodeParameter('options', i, {}) as IDataObject; + + if (qs.sort) { + const properties = (qs.sort as IDataObject).property as Array<{ field: string, direction: string }>; + qs.sort = properties.map(prop => `${prop.direction === 'asc' ? '' : '-'}${prop.field}`).join(','); + } + + if (qs.fields) { + qs.fields = (qs.fields as IDataObject[]).join(','); + } + + if (returnAll === true) { + responseData = await apiRequestAllItems.call(this, requestMethod, endPoint, {}, qs); + } else { + qs.limit = this.getNodeParameter('limit', 0) as number; + responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs); + if (version === 2) { + responseData = responseData.list; + } + } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + + if (downloadAttachments === true) { + const downloadFieldNames = (this.getNodeParameter('downloadFieldNames', 0) as string).split(','); + const response = await downloadRecordAttachments.call(this, responseData, downloadFieldNames); + data.push(...response); + } } - returnAll = this.getNodeParameter('returnAll', 0) as boolean; - qs = this.getNodeParameter('options', i, {}) as IDataObject; - - if (qs.sort) { - const properties = (qs.sort as IDataObject).property as Array<{ - field: string; - direction: string; - }>; - qs.sort = properties - .map((prop) => `${prop.direction === 'asc' ? '' : '-'}${prop.field}`) - .join(','); + if (downloadAttachments) { + return [data]; } - if (qs.fields) { - qs.fields = (qs.fields as IDataObject[]).join(','); - } - - if (returnAll === true) { - responseData = await apiRequestAllItems.call(this, requestMethod, endPoint, {}, qs); + } catch (error) { + if (this.continueOnFail()) { + returnData.push({ json:{ error: error.toString() } }); } else { - qs.limit = this.getNodeParameter('limit', 0) as number; - responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs); - if (version === 2) { - responseData = responseData.list; - } + throw error; } - - returnData.push.apply(returnData, responseData); - - if (downloadAttachments === true) { - const downloadFieldNames = ( - this.getNodeParameter('downloadFieldNames', 0) as string - ).split(','); - const response = await downloadRecordAttachments.call( - this, - responseData, - downloadFieldNames, - ); - data.push(...response); - } - } - - if (downloadAttachments) { - return [data]; - } - } catch (error) { - if (this.continueOnFail()) { - returnData.push({ error: error.toString() }); - } - throw error; } + + return this.prepareOutputData(returnData as INodeExecutionData[]); } if (operation === 'get') { @@ -445,64 +442,66 @@ export class NocoDB implements INodeType { const newItems: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { - try { - const id = this.getNodeParameter('id', i) as string; + try { + const id = this.getNodeParameter('id', i) as string; - if (version === 1) { - endPoint = `/nc/${projectId}/api/v1/${table}/${id}`; - } else if (version === 2) { - endPoint = `/api/v1/db/data/noco/${projectId}/${table}/${id}`; - } - - responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs); - - let newItem: INodeExecutionData = { json: {} }; - - if (version === 1) { - newItem = { json: responseData }; - } else if (version === 2) { - if (Object.keys(responseData).length === 0) { - // Get did fail - const errorMessage = `The row with the ID "${id}" could not be queried. It probably doesn't exist.`; - if (this.continueOnFail()) { - newItem = { - json: { error: errorMessage }, - }; + if (version === 1) { + endPoint = `/nc/${projectId}/api/v1/${table}/${id}`; + } else if (version === 2) { + endPoint = `/api/v1/db/data/noco/${projectId}/${table}/${id}`; } - throw new NodeApiError( - this.getNode(), - { message: errorMessage }, - { message: errorMessage, itemIndex: i }, + + responseData = await apiRequest.call(this, requestMethod, endPoint, {}, qs); + + if (version === 2 ) { + if (Object.keys(responseData).length === 0) { + // Get did fail + const errorMessage = `The row with the ID "${id}" could not be queried. It probably doesn't exist.`; + if (this.continueOnFail()) { + newItems.push({ json: {error: errorMessage }}); + continue; + } + throw new NodeApiError(this.getNode(), { message: errorMessage }, { message: errorMessage, itemIndex: i }); + } + } + + const downloadAttachments = this.getNodeParameter('downloadAttachments', i) as boolean; + + if (downloadAttachments === true) { + const downloadFieldNames = (this.getNodeParameter('downloadFieldNames', i) as string).split(','); + const data = await downloadRecordAttachments.call(this, [responseData], downloadFieldNames); + const newItem = { + binary: data[0].binary, + json: {}, + }; + + const executionData = this.helpers.constructExecutionMetaData( + [newItem] as INodeExecutionData[], + { itemData: { item: i } }, + ); + + newItems.push(...executionData); + } else { + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + newItems.push(...executionData); + } + + } catch (error) { + if (this.continueOnFail()) { + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.toString()}), + { itemData: { item: i } }, ); - } else { - // Get did work - newItem = { json: responseData }; - } - } - // const newItem: INodeExecutionData = { json: responseData }; - const downloadAttachments = this.getNodeParameter('downloadAttachments', i) as boolean; - - if (downloadAttachments === true) { - const downloadFieldNames = ( - this.getNodeParameter('downloadFieldNames', i) as string - ).split(','); - const data = await downloadRecordAttachments.call( - this, - [responseData], - downloadFieldNames, - ); - newItem.binary = data[0].binary; + newItems.push(...executionData); + continue; + } + throw new NodeApiError(this.getNode(), error, {itemIndex: i}); } - - newItems.push(newItem); - } catch (error) { - if (this.continueOnFail()) { - newItems.push({ json: { error: error.toString() } }); - continue; - } - throw new NodeApiError(this.getNode(), error); - } } return this.prepareOutputData(newItems); } diff --git a/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts b/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts index b2ce8dc7ac..c9cfc42ff0 100644 --- a/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts +++ b/packages/nodes-base/nodes/Notion/v1/NotionV1.node.ts @@ -241,7 +241,7 @@ export class NotionV1 implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -265,7 +265,12 @@ export class NotionV1 implements INodeType { `/blocks/${blockId}/children`, body, ); - returnData.push(block); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(block), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -292,7 +297,12 @@ export class NotionV1 implements INodeType { ); responseData = responseData.results; } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -302,7 +312,12 @@ export class NotionV1 implements INodeType { for (let i = 0; i < length; i++) { const databaseId = extractDatabaseId(this.getNodeParameter('databaseId', i) as string); responseData = await notionApiRequest.call(this, 'GET', `/databases/${databaseId}`); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -325,7 +340,12 @@ export class NotionV1 implements INodeType { responseData = await notionApiRequest.call(this, 'POST', `/search`, body); responseData = responseData.results; } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -355,10 +375,12 @@ export class NotionV1 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -378,12 +400,12 @@ export class NotionV1 implements INodeType { if (filters.multipleCondition) { const { or, and } = (filters.multipleCondition as IDataObject).condition as IDataObject; if (Array.isArray(or) && or.length !== 0) { - Object.assign(body.filter, { + Object.assign(body.filter!, { or: (or as IDataObject[]).map((data) => mapFilters([data], timezone)), }); } if (Array.isArray(and) && and.length !== 0) { - Object.assign(body.filter, { + Object.assign(body.filter!, { and: (and as IDataObject[]).map((data) => mapFilters([data], timezone)), }); } @@ -418,7 +440,12 @@ export class NotionV1 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -442,10 +469,12 @@ export class NotionV1 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } } @@ -455,7 +484,12 @@ export class NotionV1 implements INodeType { for (let i = 0; i < length; i++) { const userId = this.getNodeParameter('userId', i) as string; responseData = await notionApiRequest.call(this, 'GET', `/users/${userId}`); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } if (operation === 'getAll') { @@ -468,7 +502,12 @@ export class NotionV1 implements INodeType { responseData = await notionApiRequestAllItems.call(this, 'results', 'GET', '/users'); responseData = responseData.splice(0, qs.limit); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -491,10 +530,12 @@ export class NotionV1 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -506,10 +547,12 @@ export class NotionV1 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -558,10 +601,14 @@ export class NotionV1 implements INodeType { responseData = simplifyObjects(responseData, false, 1); } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts b/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts index 0a32df5f12..76da9cd210 100644 --- a/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts +++ b/packages/nodes-base/nodes/Notion/v2/NotionV2.node.ts @@ -250,7 +250,7 @@ export class NotionV2 implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -275,7 +275,12 @@ export class NotionV2 implements INodeType { `/blocks/${blockId}/children`, body, ); - returnData.push(block); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(block), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -310,7 +315,11 @@ export class NotionV2 implements INodeType { ..._data, })); - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -324,7 +333,12 @@ export class NotionV2 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, download)[0]; } - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -351,7 +365,12 @@ export class NotionV2 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, download); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } @@ -399,7 +418,11 @@ export class NotionV2 implements INodeType { responseData = simplifyObjects(responseData, download); } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -452,10 +475,12 @@ export class NotionV2 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -490,11 +515,11 @@ export class NotionV2 implements INodeType { if (filterType === 'manual') { const matchType = this.getNodeParameter('matchType', 0) as string; if (matchType === 'anyFilter') { - Object.assign(body.filter, { + Object.assign(body.filter!, { or: conditions.map((data) => mapFilters([data], timezone)), }); } else if (matchType === 'allFilters') { - Object.assign(body.filter, { + Object.assign(body.filter!, { and: conditions.map((data) => mapFilters([data], timezone)), }); } @@ -579,7 +604,12 @@ export class NotionV2 implements INodeType { for (let i = 0; i < length; i++) { const userId = this.getNodeParameter('userId', i) as string; responseData = await notionApiRequest.call(this, 'GET', `/users/${userId}`); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } if (operation === 'getAll') { @@ -592,7 +622,12 @@ export class NotionV2 implements INodeType { responseData = await notionApiRequestAllItems.call(this, 'results', 'GET', '/users'); responseData = responseData.splice(0, qs.limit); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } @@ -608,10 +643,12 @@ export class NotionV2 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, download); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -632,10 +669,12 @@ export class NotionV2 implements INodeType { if (simple === true) { responseData = simplifyObjects(responseData, download); } - returnData.push.apply( - returnData, - Array.isArray(responseData) ? responseData : [responseData], + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, ); + returnData.push(...executionData); } } @@ -682,13 +721,20 @@ export class NotionV2 implements INodeType { responseData = simplifyObjects(responseData, download); } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } } + if (download === true) { - return this.prepareOutputData(returnData as INodeExecutionData[]); + const rawData = returnData.map((data) => data.json); + return this.prepareOutputData(rawData as INodeExecutionData[]); } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts b/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts index bf27b12853..86a3d3ef47 100644 --- a/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts +++ b/packages/nodes-base/nodes/OpenThesaurus/OpenThesaurus.node.ts @@ -135,7 +135,7 @@ export class OpenThesaurus implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -160,19 +160,25 @@ export class OpenThesaurus implements INodeType { ); responseData = responseData.synsets; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/OpenWeatherMap/OpenWeatherMap.node.ts b/packages/nodes-base/nodes/OpenWeatherMap/OpenWeatherMap.node.ts index 30894e3486..9ecc0c5404 100644 --- a/packages/nodes-base/nodes/OpenWeatherMap/OpenWeatherMap.node.ts +++ b/packages/nodes-base/nodes/OpenWeatherMap/OpenWeatherMap.node.ts @@ -195,7 +195,7 @@ export class OpenWeatherMap implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const credentials = await this.getCredentials('openWeatherMapApi'); @@ -274,7 +274,11 @@ export class OpenWeatherMap implements INodeType { throw new NodeApiError(this.getNode(), error); } - returnData.push(responseData as IDataObject); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { returnData.push({ json: { error: error.message } }); @@ -284,6 +288,6 @@ export class OpenWeatherMap implements INodeType { } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Orbit/Orbit.node.ts b/packages/nodes-base/nodes/Orbit/Orbit.node.ts index 5e8193627a..e2aeef3008 100644 --- a/packages/nodes-base/nodes/Orbit/Orbit.node.ts +++ b/packages/nodes-base/nodes/Orbit/Orbit.node.ts @@ -111,7 +111,7 @@ export class Orbit implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -523,19 +523,25 @@ export class Orbit implements INodeType { responseData = { success: true }; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Paddle/Paddle.node.ts b/packages/nodes-base/nodes/Paddle/Paddle.node.ts index 3bfcc3cd30..2366e31fa3 100644 --- a/packages/nodes-base/nodes/Paddle/Paddle.node.ts +++ b/packages/nodes-base/nodes/Paddle/Paddle.node.ts @@ -165,7 +165,7 @@ export class Paddle implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const body: IDataObject = {}; @@ -527,17 +527,22 @@ export class Paddle implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as unknown as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts b/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts index cc9c7d0e5c..1cee3902a3 100644 --- a/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts +++ b/packages/nodes-base/nodes/PagerDuty/PagerDuty.node.ts @@ -203,7 +203,7 @@ export class PagerDuty implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -454,19 +454,25 @@ export class PagerDuty implements INodeType { responseData = responseData.user; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/PayPal/PayPal.node.ts b/packages/nodes-base/nodes/PayPal/PayPal.node.ts index 6b6235292c..35894ecabd 100644 --- a/packages/nodes-base/nodes/PayPal/PayPal.node.ts +++ b/packages/nodes-base/nodes/PayPal/PayPal.node.ts @@ -130,7 +130,7 @@ export class PayPal implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -234,19 +234,25 @@ export class PayPal implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts index 80bc1be5ad..78dc7bf930 100644 --- a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts +++ b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts @@ -4019,7 +4019,7 @@ export class Pipedrive implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; // For Post let body: IDataObject; @@ -4844,7 +4844,7 @@ export class Pipedrive implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -4874,20 +4874,23 @@ export class Pipedrive implements INodeType { } } - if (Array.isArray(responseData.data)) { - returnData.push.apply(returnData, responseData.data as IDataObject[]); - } else if (responseData.data === true) { - returnData.push({ success: true }); - } else { - returnData.push(responseData.data as IDataObject); + responseData = responseData.data; + if (responseData.data === true) { + responseData = {success: true}; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } catch (error) { if (this.continueOnFail()) { if (resource === 'file' && operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + returnData.push({json:{ error: error.message }}); } continue; } @@ -4906,7 +4909,7 @@ export class Pipedrive implements INodeType { return this.prepareOutputData(items); } else { // For all other ones does the output items get replaced - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Postgres/Postgres.node.functions.ts b/packages/nodes-base/nodes/Postgres/Postgres.node.functions.ts index 361bec8ac8..0af3371451 100644 --- a/packages/nodes-base/nodes/Postgres/Postgres.node.functions.ts +++ b/packages/nodes-base/nodes/Postgres/Postgres.node.functions.ts @@ -1,3 +1,4 @@ +import { IExecuteFunctions } from 'n8n-core'; import { IDataObject, INodeExecutionData, JsonObject } from 'n8n-workflow'; import pgPromise from 'pg-promise'; import pg from 'pg-promise/typescript/pg-subset'; @@ -156,6 +157,93 @@ export async function pgQuery( throw new Error('multiple, independently or transaction are valid options'); } +export async function pgQueryV2( + this: IExecuteFunctions, + pgp: pgPromise.IMain<{}, pg.IClient>, + db: pgPromise.IDatabase<{}, pg.IClient>, + items: INodeExecutionData[], + continueOnFail: boolean, + overrideMode?: string, +): Promise { + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; + + let valuesArray = [] as string[][]; + if (additionalFields.queryParams) { + const propertiesString = additionalFields.queryParams as string; + const properties = propertiesString.split(',').map((column) => column.trim()); + const paramsItems = getItemsCopy(items, properties); + valuesArray = paramsItems.map((row) => properties.map((col) => row[col])) as string[][]; + } + + type QueryWithValues = { query: string; values?: string[] }; + const allQueries = new Array(); + for (let i = 0; i < items.length; i++) { + const query = this.getNodeParameter('query', i) as string; + const values = valuesArray[i]; + const queryFormat = { query, values }; + allQueries.push(queryFormat); + } + + const mode = overrideMode ? overrideMode : ((additionalFields.mode ?? 'multiple') as string); + if (mode === 'multiple') { + (await db.multi(pgp.helpers.concat(allQueries))) + .map((result, i) => { + return this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray([...result]), { + itemData: { item: i }, + }); + }) + .flat(); + } else if (mode === 'transaction') { + return db.tx(async (t) => { + const result: INodeExecutionData[] = []; + for (let i = 0; i < allQueries.length; i++) { + try { + const transactionResult = await t.any(allQueries[i].query, allQueries[i].values); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(transactionResult), + { itemData: { item: i } }, + ); + result.push(...executionData); + } catch (err) { + if (continueOnFail === false) throw err; + result.push({ + json: { ...items[i].json }, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + pairedItem: { item: i }, + } as INodeExecutionData); + return result; + } + } + return result; + }); + } else if (mode === 'independently') { + return db.task(async (t) => { + const result: INodeExecutionData[] = []; + for (let i = 0; i < allQueries.length; i++) { + try { + const transactionResult = await t.any(allQueries[i].query, allQueries[i].values); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(transactionResult), + { itemData: { item: i } }, + ); + result.push(...executionData); + } catch (err) { + if (continueOnFail === false) throw err; + result.push({ + json: { ...items[i].json }, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + pairedItem: { item: i }, + } as INodeExecutionData); + } + } + return result; + }); + } + throw new Error('multiple, independently or transaction are valid options'); +} + /** * Inserts the given items into the database. * @@ -245,6 +333,112 @@ export async function pgInsert( throw new Error('multiple, independently or transaction are valid options'); } +/** + * Inserts the given items into the database. + * + * @param {Function} getNodeParam The getter for the Node's parameters + * @param {pgPromise.IMain<{}, pg.IClient>} pgp The pgPromise instance + * @param {pgPromise.IDatabase<{}, pg.IClient>} db The pgPromise database connection + * @param {INodeExecutionData[]} items The items to be inserted + * @returns Promise> + */ +export async function pgInsertV2( + this: IExecuteFunctions, + pgp: pgPromise.IMain<{}, pg.IClient>, + db: pgPromise.IDatabase<{}, pg.IClient>, + items: INodeExecutionData[], + continueOnFail: boolean, + overrideMode?: string, +): Promise { + const table = this.getNodeParameter('table', 0) as string; + const schema = this.getNodeParameter('schema', 0) as string; + const columnString = this.getNodeParameter('columns', 0) as string; + const guardedColumns: { [key: string]: string } = {}; + + const columns = columnString + .split(',') + .map((column) => column.trim().split(':')) + .map(([name, cast], i) => { + guardedColumns[`column${i}`] = name; + return { name, cast, prop: `column${i}` }; + }); + + const columnNames = columns.map((column) => column.name); + + const cs = new pgp.helpers.ColumnSet(columns, { table: { table, schema } }); + + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; + const mode = overrideMode ? overrideMode : ((additionalFields.mode ?? 'multiple') as string); + + const returning = generateReturning(pgp, this.getNodeParameter('returnFields', 0) as string); + if (mode === 'multiple') { + const query = + pgp.helpers.insert(getItemsCopy(items, columnNames, guardedColumns), cs) + returning; + return (await db.any(query)) + .map((result, i) => { + return this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray([...result]), { + itemData: { item: i }, + }); + }) + .flat(); + } else if (mode === 'transaction') { + return db.tx(async (t) => { + const result: IDataObject[] = []; + for (let i = 0; i < items.length; i++) { + const itemCopy = getItemCopy(items[i], columnNames, guardedColumns); + try { + const insertResult = await t.one(pgp.helpers.insert(itemCopy, cs) + returning); + result.push( + ...this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(insertResult), { + itemData: { item: i }, + }), + ); + } catch (err) { + if (continueOnFail === false) throw err; + result.push({ + json: { ...itemCopy }, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + pairedItem: { item: i }, + } as INodeExecutionData); + return result; + } + } + return result; + }); + } else if (mode === 'independently') { + return db.task(async (t) => { + const result: IDataObject[] = []; + for (let i = 0; i < items.length; i++) { + const itemCopy = getItemCopy(items[i], columnNames, guardedColumns); + try { + const insertResult = await t.oneOrNone(pgp.helpers.insert(itemCopy, cs) + returning); + if (insertResult !== null) { + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(insertResult), + { itemData: { item: i } }, + ); + result.push(...executionData); + } + } catch (err) { + if (continueOnFail === false) { + throw err; + } + result.push({ + json: { ...itemCopy }, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + pairedItem: { item: i }, + } as INodeExecutionData); + } + } + return result; + }); + } + + throw new Error('multiple, independently or transaction are valid options'); +} + /** * Updates the given items in the database. * @@ -367,3 +561,132 @@ export async function pgUpdate( } throw new Error('multiple, independently or transaction are valid options'); } + +/** + * Updates the given items in the database. + * + * @param {Function} getNodeParam The getter for the Node's parameters + * @param {pgPromise.IMain<{}, pg.IClient>} pgp The pgPromise instance + * @param {pgPromise.IDatabase<{}, pg.IClient>} db The pgPromise database connection + * @param {INodeExecutionData[]} items The items to be updated + * @returns Promise> + */ +export async function pgUpdateV2( + this: IExecuteFunctions, + pgp: pgPromise.IMain<{}, pg.IClient>, + db: pgPromise.IDatabase<{}, pg.IClient>, + items: INodeExecutionData[], + continueOnFail = false, +): Promise { + const table = this.getNodeParameter('table', 0) as string; + const schema = this.getNodeParameter('schema', 0) as string; + const updateKey = this.getNodeParameter('updateKey', 0) as string; + const columnString = this.getNodeParameter('columns', 0) as string; + const guardedColumns: { [key: string]: string } = {}; + + const columns: Array<{ name: string; cast: string; prop: string }> = columnString + .split(',') + .map((column) => column.trim().split(':')) + .map(([name, cast], i) => { + guardedColumns[`column${i}`] = name; + return { name, cast, prop: `column${i}` }; + }); + + const updateKeys = updateKey.split(',').map((key, i) => { + const [name, cast] = key.trim().split(':'); + const targetCol = columns.find((column) => column.name === name); + const updateColumn = { name, cast, prop: targetCol ? targetCol.prop : `updateColumn${i}` }; + if (!targetCol) { + guardedColumns[updateColumn.prop] = name; + columns.unshift(updateColumn); + } else if (!targetCol.cast) { + targetCol.cast = updateColumn.cast || targetCol.cast; + } + return updateColumn; + }); + + const additionalFields = this.getNodeParameter('additionalFields', 0) as IDataObject; + const mode = additionalFields.mode ?? ('multiple' as string); + + const cs = new pgp.helpers.ColumnSet(columns, { table: { table, schema } }); + + // Prepare the data to update and copy it to be returned + const columnNames = columns.map((column) => column.name); + const updateItems = getItemsCopy(items, columnNames, guardedColumns); + + const returning = generateReturning(pgp, this.getNodeParameter('returnFields', 0) as string); + if (mode === 'multiple') { + const query = + pgp.helpers.update(updateItems, cs) + + ' WHERE ' + + updateKeys + .map((updateKey) => { + const key = pgp.as.name(updateKey.name); + return 'v.' + key + ' = t.' + key; + }) + .join(' AND ') + + returning; + const updateResult = await db.any(query); + return updateResult; + } else { + const where = + ' WHERE ' + + updateKeys + .map((updateKey) => pgp.as.name(updateKey.name) + ' = ${' + updateKey.prop + '}') + .join(' AND '); + if (mode === 'transaction') { + return db.tx(async (t) => { + const result: IDataObject[] = []; + for (let i = 0; i < items.length; i++) { + const itemCopy = getItemCopy(items[i], columnNames, guardedColumns); + try { + const transactionResult = await t.any( + pgp.helpers.update(itemCopy, cs) + pgp.as.format(where, itemCopy) + returning, + ); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(transactionResult), + { itemData: { item: i } }, + ); + result.push(...executionData); + } catch (err) { + if (continueOnFail === false) throw err; + result.push({ + ...itemCopy, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + }); + return result; + } + } + return result; + }); + } else if (mode === 'independently') { + return db.task(async (t) => { + const result: IDataObject[] = []; + for (let i = 0; i < items.length; i++) { + const itemCopy = getItemCopy(items[i], columnNames, guardedColumns); + try { + const independentResult = await t.any( + pgp.helpers.update(itemCopy, cs) + pgp.as.format(where, itemCopy) + returning, + ); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(independentResult), + { itemData: { item: i } }, + ); + result.push(...executionData); + } catch (err) { + if (continueOnFail === false) throw err; + result.push({ + json: { ...items[i].json }, + code: (err as JsonObject).code, + message: (err as JsonObject).message, + pairedItem: { item: i }, + } as INodeExecutionData); + } + } + return result; + }); + } + } + throw new Error('multiple, independently or transaction are valid options'); +} diff --git a/packages/nodes-base/nodes/Postgres/Postgres.node.ts b/packages/nodes-base/nodes/Postgres/Postgres.node.ts index 582aa9ecdd..20a9ad51fd 100644 --- a/packages/nodes-base/nodes/Postgres/Postgres.node.ts +++ b/packages/nodes-base/nodes/Postgres/Postgres.node.ts @@ -9,7 +9,7 @@ import { import pgPromise from 'pg-promise'; -import { pgInsert, pgQuery, pgUpdate } from './Postgres.node.functions'; +import { pgInsert, pgInsertV2, pgQuery, pgQueryV2, pgUpdate } from './Postgres.node.functions'; export class Postgres implements INodeType { description: INodeTypeDescription = { @@ -312,7 +312,7 @@ export class Postgres implements INodeType { const db = pgp(config); - let returnItems = []; + let returnItems: INodeExecutionData[] = []; const items = this.getInputData(); const operation = this.getNodeParameter('operation', 0) as string; @@ -322,33 +322,29 @@ export class Postgres implements INodeType { // executeQuery // ---------------------------------- - const queryResult = await pgQuery( - this.getNodeParameter, + const queryResult = await pgQueryV2.call( + this, pgp, db, items, this.continueOnFail(), ); - - returnItems = this.helpers.returnJsonArray(queryResult); + returnItems = queryResult as INodeExecutionData[]; } else if (operation === 'insert') { // ---------------------------------- // insert // ---------------------------------- - const insertData = await pgInsert( - this.getNodeParameter, + const insertData = await pgInsertV2.call( + this, pgp, db, items, this.continueOnFail(), ); - for (let i = 0; i < insertData.length; i++) { - returnItems.push({ - json: insertData[i], - }); - } + // returnItems = this.helpers.returnJsonArray(insertData); + returnItems = insertData as INodeExecutionData[]; } else if (operation === 'update') { // ---------------------------------- // update diff --git a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts index 8eca14132f..cbe768b115 100644 --- a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts +++ b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts @@ -372,7 +372,7 @@ export class Pushbullet implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -503,20 +503,25 @@ export class Pushbullet implements INodeType { }); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts b/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts index 7c8f15fcb6..ba959b6995 100644 --- a/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts +++ b/packages/nodes-base/nodes/QuickBase/QuickBase.node.ts @@ -117,7 +117,7 @@ export class QuickBase implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; const headers: IDataObject = {}; @@ -148,7 +148,12 @@ export class QuickBase implements INodeType { responseData = responseData.splice(0, limit); } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } @@ -170,7 +175,12 @@ export class QuickBase implements INodeType { `/files/${tableId}/${recordId}/${fieldId}/${versionNumber}`, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } @@ -193,7 +203,7 @@ export class QuickBase implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -284,11 +294,12 @@ export class QuickBase implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } if (operation === 'delete') { @@ -304,7 +315,12 @@ export class QuickBase implements INodeType { responseData = await quickbaseApiRequest.call(this, 'DELETE', '/records', body); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } @@ -364,7 +380,12 @@ export class QuickBase implements INodeType { responseData.push(data); } } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } @@ -440,11 +461,12 @@ export class QuickBase implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } if (operation === 'upsert') { @@ -522,11 +544,12 @@ export class QuickBase implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: 0 } }, + ); + + returnData.push(...executionData); } } @@ -577,7 +600,13 @@ export class QuickBase implements INodeType { responseData.push(data); } } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } @@ -597,10 +626,16 @@ export class QuickBase implements INodeType { qs, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts b/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts index 60e7b0f5dc..4701741e1c 100644 --- a/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts +++ b/packages/nodes-base/nodes/QuickBooks/QuickBooks.node.ts @@ -192,7 +192,7 @@ export class QuickBooks implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const { oauthTokenData } = (await this.getCredentials( 'quickBooksOAuth2Api', @@ -1137,16 +1137,22 @@ export class QuickBooks implements INodeType { responseData[i].json = { error: error.message }; } } else { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); } continue; } throw error; } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + returnData.push(...executionData); } const download = this.getNodeParameter('download', 0, false) as boolean; @@ -1158,7 +1164,7 @@ export class QuickBooks implements INodeType { ) { return this.prepareOutputData(responseData); } else { - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } } diff --git a/packages/nodes-base/nodes/Reddit/Reddit.node.ts b/packages/nodes-base/nodes/Reddit/Reddit.node.ts index bd8b3d05ff..3f21c4170c 100644 --- a/packages/nodes-base/nodes/Reddit/Reddit.node.ts +++ b/packages/nodes-base/nodes/Reddit/Reddit.node.ts @@ -95,7 +95,7 @@ export class Reddit implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -421,18 +421,25 @@ export class Reddit implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/S3/S3.node.ts b/packages/nodes-base/nodes/S3/S3.node.ts index c5da48b189..5f51f20566 100644 --- a/packages/nodes-base/nodes/S3/S3.node.ts +++ b/packages/nodes-base/nodes/S3/S3.node.ts @@ -81,7 +81,7 @@ export class S3 implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const qs: IDataObject = {}; let responseData; const resource = this.getNodeParameter('resource', 0) as string; @@ -155,7 +155,12 @@ export class S3 implements INodeType { headers, ); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ success: true }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // returnData.push({ success: true }); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListBuckets.html if (operation === 'getAll') { @@ -250,11 +255,17 @@ export class S3 implements INodeType { ); responseData = responseData.ListBucketResult.Contents; } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData); - } else { - returnData.push(responseData); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // if (Array.isArray(responseData)) { + // returnData.push.apply(returnData, responseData); + // } else { + // returnData.push(responseData); + // } } } if (resource === 'folder') { @@ -282,18 +293,13 @@ export class S3 implements INodeType { const region = responseData.LocationConstraint._; - responseData = await s3ApiRequestSOAP.call( - this, - bucketName, - 'PUT', - path, - '', - qs, - headers, - {}, - region, + responseData = await s3ApiRequestSOAP.call(this, bucketName, 'PUT', path, '', qs, headers, {}, region); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({success: true}), + { itemData: { item: i } }, ); - returnData.push({ success: true }); + returnData.push(...executionData); + // returnData.push({ success: true }); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html if (operation === 'delete') { @@ -373,7 +379,12 @@ export class S3 implements INodeType { responseData = { deleted: responseData.DeleteResult.Deleted }; } - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html if (operation === 'getAll') { @@ -433,8 +444,13 @@ export class S3 implements INodeType { if (qs.limit) { responseData = responseData.splice(0, qs.limit as number); } - returnData.push.apply(returnData, responseData); } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } } if (resource === 'file') { @@ -541,7 +557,12 @@ export class S3 implements INodeType { {}, region, ); - returnData.push(responseData.CopyObjectResult); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.CopyObjectResult), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // returnData.push(responseData.CopyObjectResult); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_GetObject.html if (operation === 'download') { @@ -590,7 +611,7 @@ export class S3 implements INodeType { // Create a shallow copy of the binary data so that the old // data references which do not get changed still stay behind // but the incoming data does not get changed. - Object.assign(newItem.binary, items[i].binary); + Object.assign(newItem.binary!, items[i].binary); } items[i] = newItem; @@ -638,7 +659,12 @@ export class S3 implements INodeType { region, ); - returnData.push({ success: true }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({success: true}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // returnData.push({ success: true }); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_ListObjectsV2.html if (operation === 'getAll') { @@ -700,8 +726,13 @@ export class S3 implements INodeType { if (qs.limit) { responseData = responseData.splice(0, qs.limit as number); } - returnData.push.apply(returnData, responseData); } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } //https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html if (operation === 'upload') { @@ -849,7 +880,13 @@ export class S3 implements INodeType { region, ); } - returnData.push({ success: true }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({success: true}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // returnData.push({ success: true }); } } } catch (error) { @@ -857,7 +894,12 @@ export class S3 implements INodeType { if (resource === 'file' && operation === 'download') { items[i].json = { error: error.message }; } else { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); + // returnData.push({ error: error.message }); } continue; } @@ -867,8 +909,8 @@ export class S3 implements INodeType { if (resource === 'file' && operation === 'download') { // For file downloads the files get attached to the existing items return this.prepareOutputData(items); - } else { - return [this.helpers.returnJsonArray(returnData)]; } + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts index b91b28ae5f..3e52d174b5 100644 --- a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts +++ b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts @@ -1062,7 +1062,7 @@ export class Salesforce implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const qs: IDataObject = {}; const resource = this.getNodeParameter('resource', 0) as string; @@ -3073,27 +3073,34 @@ export class Salesforce implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - if (responseData === undefined) { - // Make sure that always valid JSON gets returned which also matches the - // Salesforce default response - responseData = { - errors: [], - success: true, - }; - } - returnData.push(responseData as IDataObject); + + if (!Array.isArray(responseData) && responseData === undefined) { + // Make sure that always valid JSON gets returned which also matches the + // Salesforce default response + responseData = { + errors: [], + success: true, + }; } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts b/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts index 749675b462..2a4c7bfa48 100644 --- a/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts +++ b/packages/nodes-base/nodes/Salesmate/Salesmate.node.ts @@ -133,7 +133,7 @@ export class Salesmate implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -783,12 +783,15 @@ export class Salesmate implements INodeType { responseData = await salesmateApiRequest.call(this, 'DELETE', `/v1/deals/${dealId}`); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts b/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts index ed76ab986b..86071be397 100644 --- a/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts +++ b/packages/nodes-base/nodes/SeaTable/SeaTable.node.ts @@ -133,7 +133,7 @@ export class SeaTable implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let responseData; const resource = this.getNodeParameter('resource', 0) as string; @@ -226,10 +226,19 @@ export class SeaTable implements INodeType { tableColumns.map(({ name }) => name).concat(['_id', '_ctime', '_mtime']), ); - returnData.push(row); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(row), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -248,10 +257,20 @@ export class SeaTable implements INodeType { {}, { table_id: tableId, convert: true }, )) as IDataObject; - returnData.push(response); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -265,8 +284,8 @@ export class SeaTable implements INodeType { const tableName = this.getNodeParameter('tableName', 0) as string; const tableColumns = await getTableColumns.call(this, tableName); - try { - for (let i = 0; i < items.length; i++) { + for (let i = 0; i < items.length; i++) { + try { const endpoint = `/dtable-server/api/v1/dtables/{{dtable_uuid}}/rows/`; qs.table_name = tableName; const filters = this.getNodeParameter('filters', i) as IDataObject; @@ -298,13 +317,22 @@ export class SeaTable implements INodeType { ), ); - returnData.push(...rows); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(rows), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); + } catch (error) { + if (this.continueOnFail()) { + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); + } + throw error; } - } catch (error) { - if (this.continueOnFail()) { - returnData.push({ error: error.message }); - } - throw error; } } else if (operation === 'delete') { for (let i = 0; i < items.length; i++) { @@ -323,10 +351,20 @@ export class SeaTable implements INodeType { body, qs, )) as IDataObject; - returnData.push(response); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(response), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -381,10 +419,19 @@ export class SeaTable implements INodeType { body, ); - returnData.push({ _id: rowId, ...responseData }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ _id: rowId, ...responseData }), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -394,6 +441,6 @@ export class SeaTable implements INodeType { throw new NodeOperationError(this.getNode(), `The operation "${operation}" is not known!`); } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts index 28fba2bc01..a58fbf3882 100644 --- a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts +++ b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts @@ -137,7 +137,7 @@ export class SendGrid implements INodeType { const qs: IDataObject = {}; let responseData; const timezone = this.getTimezone(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; // https://sendgrid.com/docs/api-reference/ @@ -167,10 +167,18 @@ export class SendGrid implements INodeType { const limit = this.getNodeParameter('limit', i) as number; responseData = responseData.splice(0, limit); } - returnData.push.apply(returnData, responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: {item: i} }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: {item: i} }, + ); + returnData.push(...executionData); continue; } throw error; @@ -199,10 +207,19 @@ export class SendGrid implements INodeType { if (Array.isArray(responseData)) { responseData = responseData[0]; } - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: {item: i} }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: {item: i} }, + ); + returnData.push(...executionData); continue; } throw error; @@ -290,7 +307,7 @@ export class SendGrid implements INodeType { returnData.push(responseData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json:{ error: error.message } }); } else { throw error; } @@ -311,10 +328,19 @@ export class SendGrid implements INodeType { {}, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: {item: i} }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: {item: i} }, + ); + returnData.push(...executionData); continue; } throw error; @@ -339,10 +365,19 @@ export class SendGrid implements INodeType { const limit = this.getNodeParameter('limit', i) as number; responseData = responseData.splice(0, limit); } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: {item: i} }, + ); + returnData.push(...executionData); continue; } throw error; @@ -361,10 +396,19 @@ export class SendGrid implements INodeType { {}, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: {item: i} }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: {item: i} }, + ); + returnData.push(...executionData); continue; } throw error; @@ -382,10 +426,19 @@ export class SendGrid implements INodeType { { name }, qs, ); - returnData.push(responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; @@ -405,10 +458,18 @@ export class SendGrid implements INodeType { qs, ); responseData = { success: true }; - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; @@ -427,10 +488,18 @@ export class SendGrid implements INodeType { { name }, qs, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({error: error.message}), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; @@ -572,10 +641,18 @@ export class SendGrid implements INodeType { resolveWithFullResponse: true, }); - returnData.push({ messageId: data!.headers['x-message-id'] }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ messageId: data!.headers['x-message-id'] }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; @@ -583,6 +660,6 @@ export class SendGrid implements INodeType { } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts b/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts index eaf06b9c65..dfcacd3bf6 100644 --- a/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts +++ b/packages/nodes-base/nodes/SentryIo/SentryIo.node.ts @@ -283,7 +283,7 @@ export class SentryIo implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -726,19 +726,24 @@ export class SentryIo implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts index 1ede584d80..4a5f7f7e9b 100644 --- a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts +++ b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts @@ -506,7 +506,7 @@ export class ServiceNow implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData = {}; let qs: IDataObject; @@ -1151,16 +1151,23 @@ export class ServiceNow implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (resource === 'attachment') { @@ -1168,6 +1175,6 @@ export class ServiceNow implements INodeType { return this.prepareOutputData(returnData as INodeExecutionData[]); } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Shopify/Shopify.node.ts b/packages/nodes-base/nodes/Shopify/Shopify.node.ts index d4bbe23abf..44a3ad6aa8 100644 --- a/packages/nodes-base/nodes/Shopify/Shopify.node.ts +++ b/packages/nodes-base/nodes/Shopify/Shopify.node.ts @@ -161,7 +161,7 @@ export class Shopify implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -464,19 +464,25 @@ export class Shopify implements INodeType { responseData = responseData.product; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Slack/Slack.node.ts b/packages/nodes-base/nodes/Slack/Slack.node.ts index 583b8565d4..b45548afa9 100644 --- a/packages/nodes-base/nodes/Slack/Slack.node.ts +++ b/packages/nodes-base/nodes/Slack/Slack.node.ts @@ -273,7 +273,7 @@ export class Slack implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let qs: IDataObject; let responseData; @@ -1367,19 +1367,20 @@ export class Slack implements INodeType { responseData = responseData.profile; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + returnData.push({ json: { error: (error as JsonObject).message } }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Spotify/Spotify.node.ts b/packages/nodes-base/nodes/Spotify/Spotify.node.ts index 36be7c118b..7ad1a45f38 100644 --- a/packages/nodes-base/nodes/Spotify/Spotify.node.ts +++ b/packages/nodes-base/nodes/Spotify/Spotify.node.ts @@ -777,7 +777,7 @@ export class Spotify implements INodeType { async execute(this: IExecuteFunctions): Promise { // Get all of the incoming input data to loop through const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; // For Post let body: IDataObject; @@ -1302,20 +1302,24 @@ export class Spotify implements INodeType { ); } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Stackby/Stackby.node.ts b/packages/nodes-base/nodes/Stackby/Stackby.node.ts index 8116682f5d..8b1b075055 100644 --- a/packages/nodes-base/nodes/Stackby/Stackby.node.ts +++ b/packages/nodes-base/nodes/Stackby/Stackby.node.ts @@ -173,7 +173,7 @@ export class Stackby implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -193,7 +193,11 @@ export class Stackby implements INodeType { ); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -216,10 +220,20 @@ export class Stackby implements INodeType { qs, ); responseData = responseData.records; - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; @@ -271,7 +285,11 @@ export class Stackby implements INodeType { ); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: 0 } }, + ); + returnData.push(...executionErrorData); } else { throw error; } @@ -317,13 +335,17 @@ export class Stackby implements INodeType { ); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts b/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts index 06cba1cfed..105ed3a410 100644 --- a/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts +++ b/packages/nodes-base/nodes/Storyblok/Storyblok.node.ts @@ -150,7 +150,7 @@ export class Storyblok implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -343,19 +343,25 @@ export class Storyblok implements INodeType { } } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Strapi/Strapi.node.ts b/packages/nodes-base/nodes/Strapi/Strapi.node.ts index ce9c0e268c..09588c5a60 100644 --- a/packages/nodes-base/nodes/Strapi/Strapi.node.ts +++ b/packages/nodes-base/nodes/Strapi/Strapi.node.ts @@ -104,7 +104,7 @@ export class Strapi implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; const headers: IDataObject = {}; @@ -145,7 +145,12 @@ export class Strapi implements INodeType { headers, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'delete') { @@ -163,7 +168,12 @@ export class Strapi implements INodeType { headers, ); - returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'getAll') { @@ -260,7 +270,13 @@ export class Strapi implements INodeType { ); } } - returnData.push.apply(returnData, responseData); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'get') { @@ -277,9 +293,17 @@ export class Strapi implements INodeType { undefined, headers, ); - apiVersion === 'v4' - ? returnData.push(responseData.data) - : returnData.push(responseData); + + if (apiVersion === 'v4') { + responseData = responseData.data; + } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } if (operation === 'update') { @@ -312,19 +336,31 @@ export class Strapi implements INodeType { undefined, headers, ); - apiVersion === 'v4' - ? returnData.push(responseData.data) - : returnData.push(responseData); + + if (apiVersion === 'v4') { + responseData = responseData.data; + } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Strava/Strava.node.ts b/packages/nodes-base/nodes/Strava/Strava.node.ts index 22796eafeb..3ea98d4ea7 100644 --- a/packages/nodes-base/nodes/Strava/Strava.node.ts +++ b/packages/nodes-base/nodes/Strava/Strava.node.ts @@ -49,7 +49,7 @@ export class Strava implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -177,20 +177,26 @@ export class Strava implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Stripe/Stripe.node.ts b/packages/nodes-base/nodes/Stripe/Stripe.node.ts index 7cb284bae5..1e056a53ba 100644 --- a/packages/nodes-base/nodes/Stripe/Stripe.node.ts +++ b/packages/nodes-base/nodes/Stripe/Stripe.node.ts @@ -137,7 +137,7 @@ export class Stripe implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -466,18 +466,25 @@ export class Stripe implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/SyncroMSP/v1/actions/router.ts b/packages/nodes-base/nodes/SyncroMSP/v1/actions/router.ts index 4e35bb8d69..53a27c2fcd 100644 --- a/packages/nodes-base/nodes/SyncroMSP/v1/actions/router.ts +++ b/packages/nodes-base/nodes/SyncroMSP/v1/actions/router.ts @@ -16,6 +16,7 @@ export async function router(this: IExecuteFunctions): Promise('resource', i); let operation = this.getNodeParameter('operation', i); + let responseData: INodeExecutionData[] = []; if (operation === 'del') { operation = 'delete'; } @@ -27,22 +28,32 @@ export async function router(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as Resource; const operation = this.getNodeParameter('operation', 0) as Operation; @@ -563,18 +563,25 @@ export class Taiga implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts b/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts index 46c8e8874b..8a6c130aa4 100644 --- a/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts +++ b/packages/nodes-base/nodes/Tapfiliate/Tapfiliate.node.ts @@ -95,7 +95,7 @@ export class Tapfiliate implements INodeType { const length = items.length; const qs: IDataObject = {}; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as string; const operation = this.getNodeParameter('operation', 0) as string; for (let i = 0; i < length; i++) { @@ -141,7 +141,7 @@ export class Tapfiliate implements INodeType { 'DELETE', `/affiliates/${affiliateId}/`, ); - returnData.push({ success: true }); + responseData = { success: true }; } if (operation === 'get') { //https://tapfiliate.com/docs/rest/#affiliates-affiliate-get @@ -151,7 +151,6 @@ export class Tapfiliate implements INodeType { 'GET', `/affiliates/${affiliateId}/`, ); - returnData.push(responseData); } if (operation === 'getAll') { //https://tapfiliate.com/docs/rest/#affiliates-affiliates-collection-get @@ -171,7 +170,6 @@ export class Tapfiliate implements INodeType { responseData = await tapfiliateApiRequest.call(this, 'GET', `/affiliates/`, {}, qs); responseData = responseData.splice(0, limit); } - returnData.push.apply(returnData, responseData); } } if (resource === 'affiliateMetadata') { @@ -194,7 +192,7 @@ export class Tapfiliate implements INodeType { { value }, ); } - returnData.push({ success: true }); + responseData = { success: true }; } if (operation === 'remove') { //https://tapfiliate.com/docs/rest/#affiliates-meta-data-key-delete @@ -205,7 +203,7 @@ export class Tapfiliate implements INodeType { 'DELETE', `/affiliates/${affiliateId}/meta-data/${key}/`, ); - returnData.push({ success: true }); + responseData = { success: true }; } if (operation === 'update') { //https://tapfiliate.com/docs/rest/#affiliates-notes-collection-get @@ -218,7 +216,6 @@ export class Tapfiliate implements INodeType { `/affiliates/${affiliateId}/meta-data/`, { [key]: value }, ); - returnData.push(responseData); } } if (resource === 'programAffiliate') { @@ -240,7 +237,6 @@ export class Tapfiliate implements INodeType { `/programs/${programId}/affiliates/`, body, ); - returnData.push(responseData); } if (operation === 'approve') { //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-put @@ -251,7 +247,6 @@ export class Tapfiliate implements INodeType { 'PUT', `/programs/${programId}/affiliates/${affiliateId}/approved/`, ); - returnData.push(responseData); } if (operation === 'disapprove') { //https://tapfiliate.com/docs/rest/#programs-approve-an-affiliate-for-a-program-delete @@ -262,7 +257,6 @@ export class Tapfiliate implements INodeType { 'DELETE', `/programs/${programId}/affiliates/${affiliateId}/approved/`, ); - returnData.push(responseData); } if (operation === 'get') { //https://tapfiliate.com/docs/rest/#programs-affiliate-in-program-get @@ -273,7 +267,6 @@ export class Tapfiliate implements INodeType { 'GET', `/programs/${programId}/affiliates/${affiliateId}/`, ); - returnData.push(responseData); } if (operation === 'getAll') { //https://tapfiliate.com/docs/rest/#programs-program-affiliates-collection-get @@ -300,17 +293,27 @@ export class Tapfiliate implements INodeType { ); responseData = responseData.splice(0, limit); } - returnData.push.apply(returnData, responseData); } } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Telegram/Telegram.node.ts b/packages/nodes-base/nodes/Telegram/Telegram.node.ts index 26e4fa3cce..827d300d3e 100644 --- a/packages/nodes-base/nodes/Telegram/Telegram.node.ts +++ b/packages/nodes-base/nodes/Telegram/Telegram.node.ts @@ -2047,24 +2047,28 @@ export class Telegram implements INodeType { binary: { data: binaryData, }, + pairedItem: { item: i }, }); continue; } } else if (resource === 'chat' && operation === 'administrators') { - returnData.push(...this.helpers.returnJsonArray(responseData.result)); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData.result), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } - // if (resource === 'bot' && operation === 'info') { - // responseData = { - // user: responseData.result[0].message.from, - // chat: responseData.result[0].message.chat, - // }; - // } - returnData.push({ json: responseData }); + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ json: { error: error.message } }); + returnData.push({ json: { }, error: error.message }); continue; } throw error; diff --git a/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts b/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts index d800f8bdc4..c70c761b43 100644 --- a/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts +++ b/packages/nodes-base/nodes/TravisCi/TravisCi.node.ts @@ -48,7 +48,7 @@ export class TravisCi implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -151,19 +151,25 @@ export class TravisCi implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Trello/Trello.node.ts b/packages/nodes-base/nodes/Trello/Trello.node.ts index e22c5754ff..1dbe726e0b 100644 --- a/packages/nodes-base/nodes/Trello/Trello.node.ts +++ b/packages/nodes-base/nodes/Trello/Trello.node.ts @@ -117,7 +117,7 @@ export class Trello implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const operation = this.getNodeParameter('operation', 0) as string; const resource = this.getNodeParameter('resource', 0) as string; @@ -775,20 +775,24 @@ export class Trello implements INodeType { } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray({ error: error.message }), + { itemData: { item: i } }, + ); + returnData.push(...executionData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Twitter/Twitter.node.ts b/packages/nodes-base/nodes/Twitter/Twitter.node.ts index 2a2055e885..badf00deec 100644 --- a/packages/nodes-base/nodes/Twitter/Twitter.node.ts +++ b/packages/nodes-base/nodes/Twitter/Twitter.node.ts @@ -6,6 +6,7 @@ import { INodePropertyOptions, INodeType, INodeTypeDescription, + JsonObject, } from 'n8n-workflow'; import { directMessageFields, directMessageOperations } from './DirectMessageDescription'; @@ -91,7 +92,7 @@ export class Twitter implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const resource = this.getNodeParameter('resource', 0) as string; @@ -312,19 +313,25 @@ export class Twitter implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else if (responseData !== undefined) { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = { + json: { + error: (error as JsonObject).message, + }, + }; + returnData.push(executionErrorData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/UnleashedSoftware/UnleashedSoftware.node.ts b/packages/nodes-base/nodes/UnleashedSoftware/UnleashedSoftware.node.ts index 403eee6cae..5a871a1f69 100644 --- a/packages/nodes-base/nodes/UnleashedSoftware/UnleashedSoftware.node.ts +++ b/packages/nodes-base/nodes/UnleashedSoftware/UnleashedSoftware.node.ts @@ -63,7 +63,7 @@ export class UnleashedSoftware implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -111,8 +111,11 @@ export class UnleashedSoftware implements INodeType { responseData = await unleashedApiRequest.call(this, 'GET', `/SalesOrders`, {}, qs, 1); responseData = responseData.Items; } - convertNETDates(responseData); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } @@ -154,6 +157,10 @@ export class UnleashedSoftware implements INodeType { } convertNETDates(responseData); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'get') { @@ -162,14 +169,13 @@ export class UnleashedSoftware implements INodeType { convertNETDates(responseData); } } - - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Webflow/Webflow.node.ts b/packages/nodes-base/nodes/Webflow/Webflow.node.ts index 67894654e0..73ffe575b3 100644 --- a/packages/nodes-base/nodes/Webflow/Webflow.node.ts +++ b/packages/nodes-base/nodes/Webflow/Webflow.node.ts @@ -137,7 +137,7 @@ export class Webflow implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; const qs: IDataObject = {}; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -239,6 +239,10 @@ export class Webflow implements INodeType { ); responseData = responseData.items; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------- // item: update @@ -275,19 +279,20 @@ export class Webflow implements INodeType { ); } } - - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json: { error: error.message } }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts b/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts index d71d472324..8e79f6cd2b 100644 --- a/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts +++ b/packages/nodes-base/nodes/WooCommerce/WooCommerce.node.ts @@ -122,7 +122,7 @@ export class WooCommerce implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -208,6 +208,10 @@ export class WooCommerce implements INodeType { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await woocommerceApiRequest.call(this, 'GET', '/customers', {}, qs); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // customer: update @@ -369,6 +373,10 @@ export class WooCommerce implements INodeType { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await woocommerceApiRequest.call(this, 'GET', '/products', {}, qs); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://woocommerce.github.io/woocommerce-rest-api-docs/#delete-a-product if (operation === 'delete') { @@ -568,6 +576,10 @@ export class WooCommerce implements INodeType { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await woocommerceApiRequest.call(this, 'GET', '/orders', {}, qs); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://woocommerce.github.io/woocommerce-rest-api-docs/#delete-an-order if (operation === 'delete') { @@ -581,12 +593,12 @@ export class WooCommerce implements INodeType { ); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts b/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts index b7334f37a6..781405a94e 100644 --- a/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts +++ b/packages/nodes-base/nodes/Wordpress/Wordpress.node.ts @@ -119,7 +119,7 @@ export class Wordpress implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; let responseData; const qs: IDataObject = {}; @@ -288,6 +288,10 @@ export class Wordpress implements INodeType { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await wordpressApiRequest.call(this, 'GET', '/posts', {}, qs); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.wordpress.org/rest-api/reference/posts/#delete-a-post if (operation === 'delete') { @@ -410,6 +414,10 @@ export class Wordpress implements INodeType { qs.per_page = this.getNodeParameter('limit', i) as number; responseData = await wordpressApiRequest.call(this, 'GET', '/users', {}, qs); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.wordpress.org/rest-api/reference/users/#delete-a-user if (operation === 'delete') { @@ -419,19 +427,19 @@ export class Wordpress implements INodeType { responseData = await wordpressApiRequest.call(this, 'DELETE', `/users/me`, {}, qs); } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const exectutionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...exectutionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json: { error: error.message } }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Xero/Xero.node.ts b/packages/nodes-base/nodes/Xero/Xero.node.ts index 143248a565..7649961730 100644 --- a/packages/nodes-base/nodes/Xero/Xero.node.ts +++ b/packages/nodes-base/nodes/Xero/Xero.node.ts @@ -210,7 +210,7 @@ export class Xero implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -456,6 +456,10 @@ export class Xero implements INodeType { responseData = responseData.Invoices; responseData = responseData.splice(0, limit); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } if (resource === 'contact') { @@ -609,6 +613,10 @@ export class Xero implements INodeType { responseData = responseData.Contacts; responseData = responseData.splice(0, limit); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'update') { const organizationId = this.getNodeParameter('organizationId', i) as string; @@ -718,19 +726,19 @@ export class Xero implements INodeType { responseData = responseData.Contacts; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: (error as JsonObject).message }); + returnData.push({ json: { error: (error as JsonObject).message } }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Zammad/Zammad.node.ts b/packages/nodes-base/nodes/Zammad/Zammad.node.ts index bfe21ed805..b14df485b4 100644 --- a/packages/nodes-base/nodes/Zammad/Zammad.node.ts +++ b/packages/nodes-base/nodes/Zammad/Zammad.node.ts @@ -323,7 +323,7 @@ export class Zammad implements INodeType { const operation = this.getNodeParameter('operation', 0) as string; let responseData; - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; for (let i = 0; i < items.length; i++) { try { @@ -651,6 +651,10 @@ export class Zammad implements INodeType { {}, limit, ); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } else if (resource === 'ticket') { // ********************************************************************** @@ -745,18 +749,19 @@ export class Zammad implements INodeType { } } - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json: { error: error.message } }); continue; } throw error; } } - - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts b/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts index c11e280afa..69cf6fa006 100644 --- a/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts +++ b/packages/nodes-base/nodes/Zendesk/Zendesk.node.ts @@ -264,7 +264,7 @@ export class Zendesk implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const length = items.length; const qs: IDataObject = {}; let responseData; @@ -455,6 +455,10 @@ export class Zendesk implements INodeType { responseData = await zendeskApiRequest.call(this, 'GET', endpoint, {}, qs); responseData = responseData.results || responseData.suspended_tickets; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.zendesk.com/rest_api/docs/support/tickets#delete-ticket //https://developer.zendesk.com/api-reference/ticketing/tickets/suspended_tickets/#delete-suspended-ticket @@ -520,6 +524,10 @@ export class Zendesk implements INodeType { ); responseData = responseData.slice(0, limit); } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } } //https://developer.zendesk.com/api-reference/ticketing/users/users/ @@ -605,6 +613,10 @@ export class Zendesk implements INodeType { responseData = await zendeskApiRequest.call(this, 'GET', `/users`, {}, qs); responseData = responseData.users; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.zendesk.com/api-reference/ticketing/organizations/organizations/#list-organizations if (operation === 'getOrganizations') { @@ -639,6 +651,10 @@ export class Zendesk implements INodeType { responseData = await zendeskApiRequest.call(this, 'GET', `/users/search`, {}, qs); responseData = responseData.users; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.zendesk.com/api-reference/ticketing/users/users/#delete-user if (operation === 'delete') { @@ -738,6 +754,10 @@ export class Zendesk implements INodeType { responseData = await zendeskApiRequest.call(this, 'GET', `/organizations`, {}, qs); responseData = responseData.organizations; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } //https://developer.zendesk.com/api-reference/ticketing/organizations/organizations/#show-organizations-related-information if (operation === 'getRelatedData') { @@ -787,19 +807,19 @@ export class Zendesk implements INodeType { responseData = responseData.organization; } } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ json: { error: error.message } }); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts index 5144e2ce22..4b779573c6 100644 --- a/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts +++ b/packages/nodes-base/nodes/Zoho/ZohoCrm.node.ts @@ -66,6 +66,7 @@ import { vendorFields, vendorOperations, } from './descriptions'; +import { exchangeFields } from '../Marketstack/descriptions'; export class ZohoCrm implements INodeType { description: INodeTypeDescription = { @@ -331,7 +332,7 @@ export class ZohoCrm implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; const resource = this.getNodeParameter('resource', 0) as CamelCaseResource; const operation = this.getNodeParameter('operation', 0) as string; @@ -403,6 +404,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/accounts', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // account: update @@ -496,6 +501,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/contacts', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // contact: update @@ -588,6 +597,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/deals', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // deal: update @@ -686,6 +699,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/invoices', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // invoice: update @@ -781,6 +798,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/leads', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'getFields') { // ---------------------------------------- // lead: getFields @@ -887,6 +908,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/products', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // product: update @@ -986,6 +1011,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/purchase_orders', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // purchaseOrder: update @@ -1086,6 +1115,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/quotes', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // quote: update @@ -1185,6 +1218,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/sales_orders', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // salesOrder: update @@ -1282,6 +1319,10 @@ export class ZohoCrm implements INodeType { addGetAllFilterOptions(qs, options); responseData = await handleListing.call(this, 'GET', '/vendors', {}, qs); + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } else if (operation === 'update') { // ---------------------------------------- // vendor: update @@ -1322,18 +1363,18 @@ export class ZohoCrm implements INodeType { } } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + returnData.push({ error: error.message, json: {} }); continue; } - throw error; } - - Array.isArray(responseData) - ? returnData.push(...responseData) - : returnData.push(responseData); + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/nodes-base/nodes/Zoom/Zoom.node.ts b/packages/nodes-base/nodes/Zoom/Zoom.node.ts index 684092e91a..dfc3f8998d 100644 --- a/packages/nodes-base/nodes/Zoom/Zoom.node.ts +++ b/packages/nodes-base/nodes/Zoom/Zoom.node.ts @@ -153,7 +153,7 @@ export class Zoom implements INodeType { async execute(this: IExecuteFunctions): Promise { const items = this.getInputData(); - const returnData: IDataObject[] = []; + const returnData: INodeExecutionData[] = []; let qs: IDataObject = {}; let responseData; const resource = this.getNodeParameter('resource', 0) as string; @@ -202,6 +202,10 @@ export class Zoom implements INodeType { responseData = await zoomApiRequest.call(this, 'GET', '/users/me/meetings', {}, qs); responseData = responseData.meetings; } + responseData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(responseData), + { itemData: { item: i } }, + ); } if (operation === 'delete') { //https://marketplace.zoom.us/docs/api-reference/zoom-api/meetings/meetingdelete @@ -773,20 +777,25 @@ export class Zoom implements INodeType { // ); // } // } - if (Array.isArray(responseData)) { - returnData.push.apply(returnData, responseData as IDataObject[]); - } else { - returnData.push(responseData as IDataObject); - } + const executionData = this.helpers.constructExecutionMetaData( + this.helpers.returnJsonArray(returnData), + { itemData: { item: i } }, + ); + returnData.push(...executionData); } catch (error) { if (this.continueOnFail()) { - returnData.push({ error: error.message }); + const executionErrorData = { + json: {} as IDataObject, + error: error.message, + itemIndex: i, + }; + returnData.push(executionErrorData as INodeExecutionData); continue; } throw error; } } - return [this.helpers.returnJsonArray(returnData)]; + return this.prepareOutputData(returnData); } } diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 964f6cd72c..aaf4743c54 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -1005,7 +1005,9 @@ export interface ITriggerResponse { export interface INodeType { description: INodeTypeDescription; - execute?(this: IExecuteFunctions): Promise; + execute?( + this: IExecuteFunctions, + ): Promise; executeSingle?(this: IExecuteSingleFunctions): Promise; poll?(this: IPollFunctions): Promise; trigger?(this: ITriggerFunctions): Promise; @@ -1631,3 +1633,7 @@ export type PublicInstalledNode = { latestVersion: string; package: PublicInstalledPackage; }; + +export interface NodeExecutionWithMetadata extends INodeExecutionData { + pairedItem: IPairedItemData | IPairedItemData[]; +}