From 5eb0d524591ef699ebd2631b042982170b5055a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=A4=95=E0=A4=BE=E0=A4=B0=E0=A4=A4=E0=A5=8B=E0=A4=AB?= =?UTF-8?q?=E0=A5=8D=E0=A4=AB=E0=A5=87=E0=A4=B2=E0=A4=B8=E0=A5=8D=E0=A4=95?= =?UTF-8?q?=E0=A5=8D=E0=A4=B0=E0=A4=BF=E0=A4=AA=E0=A5=8D=E0=A4=9F=E2=84=A2?= Date: Mon, 6 Mar 2023 17:33:32 +0100 Subject: [PATCH] refactor: Unify binary-data assertion across all nodes (no-changelog) (#5624) --- packages/core/src/NodeExecuteFunctions.ts | 33 ++++++- .../Aws/Rekognition/AwsRekognition.node.ts | 37 ++------ .../nodes-base/nodes/Aws/S3/AwsS3.node.ts | 33 ++----- .../nodes-base/nodes/Aws/SQS/AwsSqs.node.ts | 28 ++---- .../nodes/Aws/Textract/AwsTextract.node.ts | 26 +----- .../employeeDocument/upload/execute.ts | 41 ++------- .../v1/actions/file/upload/execute.ts | 37 ++------ packages/nodes-base/nodes/Box/Box.node.ts | 23 +---- .../nodes/Cisco/Webex/CiscoWebex.node.ts | 17 +--- .../nodes/Cisco/Webex/GenericFunctions.ts | 4 +- .../nodes/Citrix/ADC/CitrixAdc.node.ts | 20 +---- .../nodes/Compression/Compression.node.ts | 40 ++------- .../nodes-base/nodes/Cortex/Cortex.node.ts | 68 ++------------- .../nodes-base/nodes/Dropbox/Dropbox.node.ts | 26 +----- .../nodes/EditImage/EditImage.node.ts | 36 ++------ .../nodes/EmailSend/v1/EmailSendV1.node.ts | 9 +- .../nodes/EmailSend/v2/send.operation.ts | 6 +- .../nodes/Facebook/FacebookGraphApi.node.ts | 24 +----- packages/nodes-base/nodes/Ftp/Ftp.node.ts | 56 +++--------- .../nodes-base/nodes/Github/Github.node.ts | 27 ++---- .../nodes-base/nodes/Gitlab/Gitlab.node.ts | 27 ++---- .../Google/CloudStorage/ObjectDescription.ts | 16 +--- .../nodes/Google/Drive/GoogleDrive.node.ts | 39 +++------ .../nodes/Google/Gmail/GenericFunctions.ts | 12 +-- .../nodes/Google/Gmail/v1/GmailV1.node.ts | 71 +++++++-------- .../nodes/Google/YouTube/YouTube.node.ts | 53 ++---------- packages/nodes-base/nodes/Html/Html.node.ts | 18 +--- .../nodes/HtmlExtract/HtmlExtract.node.ts | 16 +--- .../HttpRequest/V1/HttpRequestV1.node.ts | 42 +++------ .../HttpRequest/V2/HttpRequestV2.node.ts | 44 +++------- .../HttpRequest/V3/HttpRequestV3.node.ts | 20 +---- .../nodes/HumanticAI/HumanticAi.node.ts | 43 +--------- packages/nodes-base/nodes/Jira/Jira.node.ts | 16 +--- packages/nodes-base/nodes/Keap/Keap.node.ts | 61 +++---------- packages/nodes-base/nodes/Line/Line.node.ts | 29 +------ .../nodes/LinkedIn/LinkedIn.node.ts | 25 +----- .../nodes-base/nodes/Mailgun/Mailgun.node.ts | 6 +- .../nodes/Matrix/GenericFunctions.ts | 34 +++----- .../OneDrive/MicrosoftOneDrive.node.ts | 21 +---- .../Microsoft/Outlook/GenericFunctions.ts | 20 +---- .../Outlook/MicrosoftOutlook.node.ts | 18 +--- .../nodes-base/nodes/Mindee/Mindee.node.ts | 42 ++------- .../nodes/NextCloud/NextCloud.node.ts | 26 +----- .../nodes-base/nodes/NocoDB/NocoDB.node.ts | 31 +------ .../nodes/Pipedrive/Pipedrive.node.ts | 25 ++---- .../nodes/Pushbullet/Pushbullet.node.ts | 20 +---- .../nodes/Pushover/Pushover.node.ts | 25 +----- .../nodes/Raindrop/Raindrop.node.ts | 17 +--- .../nodes-base/nodes/ReadPdf/ReadPDF.node.ts | 7 +- .../RespondToWebhook/RespondToWebhook.node.ts | 14 +-- packages/nodes-base/nodes/S3/S3.node.ts | 21 +---- .../nodes/Salesforce/Salesforce.node.ts | 43 ++++------ .../nodes/SendGrid/SendGrid.node.ts | 19 +--- .../nodes/SendInBlue/GenericFunctions.ts | 18 +--- .../nodes/ServiceNow/ServiceNow.node.ts | 17 +--- .../nodes-base/nodes/Signl4/Signl4.node.ts | 46 ++++------ .../nodes-base/nodes/Slack/V1/SlackV1.node.ts | 25 ++---- .../nodes-base/nodes/Slack/V2/SlackV2.node.ts | 32 ++----- .../SpreadsheetFile/SpreadsheetFile.node.ts | 19 ++-- packages/nodes-base/nodes/Ssh/Ssh.node.ts | 24 +----- .../nodes-base/nodes/TheHive/TheHive.node.ts | 86 ++----------------- packages/nodes-base/nodes/Twist/Twist.node.ts | 83 ++---------------- .../nodes/Twitter/GenericFunctions.ts | 39 +++------ .../nodes-base/nodes/Twitter/Twitter.node.ts | 8 +- .../nodes/WhatsApp/MediaFunctions.ts | 11 +-- .../WriteBinaryFile/WriteBinaryFile.node.ts | 33 +++---- packages/nodes-base/nodes/Zulip/Zulip.node.ts | 25 ++---- packages/workflow/src/Interfaces.ts | 2 + packages/workflow/src/NodeHelpers.ts | 4 +- 69 files changed, 411 insertions(+), 1573 deletions(-) diff --git a/packages/core/src/NodeExecuteFunctions.ts b/packages/core/src/NodeExecuteFunctions.ts index b7179460ec..96a752adcf 100644 --- a/packages/core/src/NodeExecuteFunctions.ts +++ b/packages/core/src/NodeExecuteFunctions.ts @@ -844,6 +844,30 @@ export function getBinaryStream(binaryDataId: string, chunkSize?: number): Reada return BinaryDataManager.getInstance().getBinaryStream(binaryDataId, chunkSize); } +export function assertBinaryData( + inputData: ITaskDataConnections, + node: INode, + itemIndex: number, + propertyName: string, + inputIndex: number, +): IBinaryData { + const binaryKeyData = inputData.main[inputIndex]![itemIndex]!.binary; + if (binaryKeyData === undefined) { + throw new NodeOperationError(node, 'No binary data exists on item!', { + itemIndex, + }); + } + + const binaryPropertyData = binaryKeyData[propertyName]; + if (binaryPropertyData === undefined) { + throw new NodeOperationError(node, `Item has no binary property called "${propertyName}"`, { + itemIndex, + }); + } + + return binaryPropertyData; +} + /** * Returns binary data buffer for given item index and property name. */ @@ -2327,8 +2351,11 @@ export function getExecuteFunctions( ...getRequestHelperFunctions(workflow, node, additionalData), ...getFileSystemHelperFunctions(node), ...getBinaryHelperFunctions(additionalData), - getBinaryDataBuffer: async (itemIndex, propertyName, inputIndex = 0) => - getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex), + assertBinaryData: (itemIndex, propertyName) => + assertBinaryData(inputData, node, itemIndex, propertyName, 0), + getBinaryDataBuffer: async (itemIndex, propertyName) => + getBinaryDataBuffer(inputData, itemIndex, propertyName, 0), + returnJsonArray, normalizeItems, constructExecutionMetaData, @@ -2465,6 +2492,8 @@ export function getExecuteSingleFunctions( ...getRequestHelperFunctions(workflow, node, additionalData), ...getBinaryHelperFunctions(additionalData), + assertBinaryData: (propertyName, inputIndex = 0) => + assertBinaryData(inputData, node, itemIndex, propertyName, inputIndex), getBinaryDataBuffer: async (propertyName, inputIndex = 0) => getBinaryDataBuffer(inputData, itemIndex, propertyName, inputIndex), }, diff --git a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts index fa028bfcd3..a5a94fd202 100644 --- a/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts +++ b/packages/nodes-base/nodes/Aws/Rekognition/AwsRekognition.node.ts @@ -1,13 +1,10 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { awsApiRequestREST, keysTPascalCase } from './GenericFunctions'; @@ -104,7 +101,7 @@ export class AwsRekognition implements INodeType { resource: ['image'], }, }, - description: 'Whether the image to analize should be taken from binary field', + description: 'Whether the image to analyze should be taken from binary field', }, { displayName: 'Binary Property', @@ -364,9 +361,9 @@ export class AwsRekognition implements INodeType { action = 'RekognitionService.DetectFaces'; // TODO: Add a later point make it possible to activate via option. - // If activated add an index to each of the found faces/tages/... + // If activated add an index to each of the found faces/tags/... // to not loose the reference to the image it got found on if - // multilpe ones got supplied. + // multiple ones got supplied. // property = 'FaceDetails'; if (additionalFields.attributes) { @@ -412,27 +409,10 @@ export class AwsRekognition implements INodeType { body.Filters.WordFilter = keysTPascalCase(wordFilter); } - const binaryData = this.getNodeParameter('binaryData', 0); - - if (binaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; - + const isBinaryData = this.getNodeParameter('binaryData', i); + if (isBinaryData) { + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + const binaryPropertyData = this.helpers.assertBinaryData(i, binaryPropertyName); Object.assign(body, { Image: { Bytes: binaryPropertyData.data, @@ -440,7 +420,6 @@ export class AwsRekognition implements INodeType { }); } else { const bucket = this.getNodeParameter('bucket', i) as string; - const name = this.getNodeParameter('name', i) as string; Object.assign(body, { diff --git a/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts b/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts index f34b1642ae..b39940377e 100644 --- a/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts +++ b/packages/nodes-base/nodes/Aws/S3/AwsS3.node.ts @@ -4,11 +4,9 @@ import { createHash } from 'crypto'; import { Builder } from 'xml2js'; -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -221,8 +219,8 @@ export class AwsS3 implements INodeType { qs['encoding-type'] = additionalFields.encodingType as string; } - if (additionalFields.delmiter) { - qs.delimiter = additionalFields.delmiter as string; + if (additionalFields.delimiter) { + qs.delimiter = additionalFields.delimiter as string; } if (additionalFields.fetchOwner) { @@ -593,7 +591,7 @@ export class AwsS3 implements INodeType { if (fileKey.substring(fileKey.length - 1) === '/') { throw new NodeOperationError( this.getNode(), - 'Downloding a whole directory is not yet supported, please provide a file key', + 'Downloading a whole directory is not yet supported, please provide a file key', ); } @@ -836,23 +834,8 @@ export class AwsS3 implements INodeType { const region = responseData.LocationConstraint._; if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + const binaryPropertyData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( i, binaryPropertyName, @@ -860,7 +843,7 @@ export class AwsS3 implements INodeType { body = binaryDataBuffer; - headers['Content-Type'] = binaryData.mimeType; + headers['Content-Type'] = binaryPropertyData.mimeType; headers['Content-MD5'] = createHash('md5').update(body).digest('base64'); @@ -868,7 +851,7 @@ export class AwsS3 implements INodeType { this, `${bucketName}.s3`, 'PUT', - `${path}${fileName || binaryData.fileName}`, + `${path}${fileName || binaryPropertyData.fileName}`, body, qs, headers, diff --git a/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts b/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts index 436615a406..ccb9dd1430 100644 --- a/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts +++ b/packages/nodes-base/nodes/Aws/SQS/AwsSqs.node.ts @@ -1,7 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeParameters, @@ -10,7 +9,7 @@ import type { INodeTypeDescription, JsonObject, } from 'n8n-workflow'; -import { NodeApiError, NodeOperationError } from 'n8n-workflow'; +import { NodeApiError } from 'n8n-workflow'; import { URL } from 'url'; @@ -341,29 +340,12 @@ export class AwsSqs implements INodeType { this.getNodeParameter('options.messageAttributes.binary', i, []) as INodeParameters[] ).forEach((attribute) => { attributeCount++; + const dataPropertyName = attribute.dataPropertyName as string; - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data set. So message attribute cannot be added!', - { itemIndex: i }, - ); - } - - if (item.binary[dataPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `The binary property "${dataPropertyName}" does not exist. So message attribute cannot be added!`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[dataPropertyName].data; + const binaryData = this.helpers.assertBinaryData(i, dataPropertyName); params.push(`MessageAttribute.${attributeCount}.Name=${attribute.name}`); - params.push(`MessageAttribute.${attributeCount}.Value.BinaryValue=${binaryData}`); + params.push(`MessageAttribute.${attributeCount}.Value.BinaryValue=${binaryData.data}`); params.push(`MessageAttribute.${attributeCount}.Value.DataType=Binary`); }); diff --git a/packages/nodes-base/nodes/Aws/Textract/AwsTextract.node.ts b/packages/nodes-base/nodes/Aws/Textract/AwsTextract.node.ts index ab89528b97..3ee983f843 100644 --- a/packages/nodes-base/nodes/Aws/Textract/AwsTextract.node.ts +++ b/packages/nodes-base/nodes/Aws/Textract/AwsTextract.node.ts @@ -1,17 +1,14 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, ICredentialDataDecryptedObject, ICredentialsDecrypted, ICredentialTestFunctions, IDataObject, + IExecuteFunctions, INodeCredentialTestResult, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import type { IExpenseDocument } from './GenericFunctions'; import { awsApiRequestREST, simplify, validateCredentials } from './GenericFunctions'; @@ -116,28 +113,13 @@ export class AwsTextract implements INodeType { try { //https://docs.aws.amazon.com/textract/latest/dg/API_AnalyzeExpense.html if (operation === 'analyzeExpense') { - const binaryProperty = this.getNodeParameter('binaryPropertyName', i); const simple = this.getNodeParameter('simple', i) as boolean; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - if ((items[i].binary as IBinaryKeyData)[binaryProperty] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - - const binaryPropertyData = (items[i].binary as IBinaryKeyData)[binaryProperty]; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const body: IDataObject = { Document: { - Bytes: binaryPropertyData.data, + Bytes: binaryData.data, }, }; diff --git a/packages/nodes-base/nodes/BambooHr/v1/actions/employeeDocument/upload/execute.ts b/packages/nodes-base/nodes/BambooHr/v1/actions/employeeDocument/upload/execute.ts index defb028535..db4a48a9d2 100644 --- a/packages/nodes-base/nodes/BambooHr/v1/actions/employeeDocument/upload/execute.ts +++ b/packages/nodes-base/nodes/BambooHr/v1/actions/employeeDocument/upload/execute.ts @@ -1,7 +1,4 @@ -import type { IExecuteFunctions } from 'n8n-core'; - -import type { IBinaryKeyData, IDataObject } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; +import type { IDataObject, IExecuteFunctions } from 'n8n-workflow'; import { apiRequest } from '../../../transport'; @@ -9,34 +6,12 @@ export async function upload(this: IExecuteFunctions, index: number) { let body: IDataObject = {}; const requestMethod = 'POST'; - const items = this.getInputData(); - + const id: string = this.getNodeParameter('employeeId', index) as string; const category = this.getNodeParameter('categoryId', index) as string; const options = this.getNodeParameter('options', index); - - if (items[index].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: index, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', index); - - if (items[index]!.binary![propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: index }, - ); - } - - const item = items[index].binary as IBinaryKeyData; - - const binaryData = item[propertyNameUpload]; - - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(index, propertyNameUpload); - - const id: string = this.getNodeParameter('employeeId', index) as string; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', index); + const { fileName, mimeType } = this.helpers.assertBinaryData(index, binaryPropertyName); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(index, binaryPropertyName); body = { json: false, @@ -44,11 +19,11 @@ export async function upload(this: IExecuteFunctions, index: number) { file: { value: binaryDataBuffer, options: { - filename: binaryData.fileName, - contentType: binaryData.mimeType, + filename: fileName, + contentType: mimeType, }, }, - fileName: binaryData.fileName, + fileName, category, }, resolveWithFullResponse: true, diff --git a/packages/nodes-base/nodes/BambooHr/v1/actions/file/upload/execute.ts b/packages/nodes-base/nodes/BambooHr/v1/actions/file/upload/execute.ts index 3644ae4537..1c6224fb49 100644 --- a/packages/nodes-base/nodes/BambooHr/v1/actions/file/upload/execute.ts +++ b/packages/nodes-base/nodes/BambooHr/v1/actions/file/upload/execute.ts @@ -1,7 +1,4 @@ -import type { IExecuteFunctions } from 'n8n-core'; - -import type { IBinaryKeyData, IDataObject } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; +import type { IDataObject, IExecuteFunctions } from 'n8n-workflow'; import { apiRequest } from '../../../transport'; @@ -9,32 +6,12 @@ export async function upload(this: IExecuteFunctions, index: number) { let body: IDataObject = {}; const requestMethod = 'POST'; - const items = this.getInputData(); - const category = this.getNodeParameter('categoryId', index) as string; const share = this.getNodeParameter('options.share', index, true) as boolean; - if (items[index].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: index, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', index); - - if (items[index]!.binary![propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: index }, - ); - } - - const item = items[index].binary as IBinaryKeyData; - - const binaryData = item[propertyNameUpload]; - - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(index, propertyNameUpload); + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', index); + const { fileName, mimeType } = this.helpers.assertBinaryData(index, binaryPropertyName); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(index, binaryPropertyName); body = { json: false, @@ -42,11 +19,11 @@ export async function upload(this: IExecuteFunctions, index: number) { file: { value: binaryDataBuffer, options: { - filename: binaryData.fileName, - contentType: binaryData.mimeType, + filename: fileName, + contentType: mimeType, }, }, - fileName: binaryData.fileName, + fileName, category, }, resolveWithFullResponse: true, diff --git a/packages/nodes-base/nodes/Box/Box.node.ts b/packages/nodes-base/nodes/Box/Box.node.ts index c24cbb902b..b509526ad1 100644 --- a/packages/nodes-base/nodes/Box/Box.node.ts +++ b/packages/nodes-base/nodes/Box/Box.node.ts @@ -1,8 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -277,23 +275,8 @@ export class Box implements INodeType { } if (isBinaryData) { - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( i, binaryPropertyName, diff --git a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts index 8ce1a5b930..6ff81b3939 100644 --- a/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts +++ b/packages/nodes-base/nodes/Cisco/Webex/CiscoWebex.node.ts @@ -1,16 +1,14 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; -import { getAttachemnts, webexApiRequest, webexApiRequestAllItems } from './GenericFunctions'; +import { getAttachments, webexApiRequest, webexApiRequestAllItems } from './GenericFunctions'; import { meetingFields, @@ -156,7 +154,7 @@ export class CiscoWebex implements INodeType { body.text = this.getNodeParameter('text', i); - body.attachments = getAttachemnts( + body.attachments = getAttachments( this.getNodeParameter( 'additionalFields.attachmentsUi.attachmentValues', i, @@ -168,15 +166,8 @@ export class CiscoWebex implements INodeType { const isBinaryData = file.fileLocation === 'binaryData' ? true : false; if (isBinaryData) { - if (!items[i].binary) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = file.binaryPropertyName as string; - - const binaryData = items[i].binary![binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( i, binaryPropertyName, diff --git a/packages/nodes-base/nodes/Cisco/Webex/GenericFunctions.ts b/packages/nodes-base/nodes/Cisco/Webex/GenericFunctions.ts index 77e6a0be3c..7eba4e7091 100644 --- a/packages/nodes-base/nodes/Cisco/Webex/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Cisco/Webex/GenericFunctions.ts @@ -135,9 +135,9 @@ function removeEmptyProperties(rest: { [key: string]: any }) { .reduce((a, k) => ({ ...a, [k]: rest[k] }), {}); } -export function getAttachemnts(attachements: IDataObject[]) { +export function getAttachments(attachments: IDataObject[]) { const _attachments: IDataObject[] = []; - for (const attachment of attachements) { + for (const attachment of attachments) { const body: IDataObject[] = []; const actions: IDataObject[] = []; for (const element of ((attachment?.elementsUi as IDataObject) diff --git a/packages/nodes-base/nodes/Citrix/ADC/CitrixAdc.node.ts b/packages/nodes-base/nodes/Citrix/ADC/CitrixAdc.node.ts index 5822ce0701..121409ece0 100644 --- a/packages/nodes-base/nodes/Citrix/ADC/CitrixAdc.node.ts +++ b/packages/nodes-base/nodes/Citrix/ADC/CitrixAdc.node.ts @@ -1,13 +1,11 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, JsonObject, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { citrixADCApiRequest } from './GenericFunctions'; @@ -74,24 +72,12 @@ export class CitrixAdc implements INodeType { const options = this.getNodeParameter('options', i); const endpoint = '/config/systemfile'; - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - - if (item.binary[binaryProperty] === undefined) { - throw new NodeOperationError( - this.getNode(), - `The binary data property "${binaryProperty}" does not exists on item!`, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const buffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); const body = { systemfile: { - filename: item.binary[binaryProperty].fileName, + filename: binaryData.fileName, filecontent: Buffer.from(buffer).toString('base64'), filelocation: fileLocation, fileencoding: 'BASE64', diff --git a/packages/nodes-base/nodes/Compression/Compression.node.ts b/packages/nodes-base/nodes/Compression/Compression.node.ts index da697216cf..e92d6c97a7 100644 --- a/packages/nodes-base/nodes/Compression/Compression.node.ts +++ b/packages/nodes-base/nodes/Compression/Compression.node.ts @@ -1,12 +1,10 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IBinaryKeyData, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import * as fflate from 'fflate'; @@ -158,7 +156,7 @@ export class Compression implements INodeType { outputFormat: ['gzip'], }, }, - description: 'Prefix use for all gzip compresed files', + description: 'Prefix use for all gzip compressed files', }, { displayName: 'Output Prefix', @@ -196,28 +194,14 @@ export class Compression implements INodeType { let zipIndex = 0; for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); if (binaryData.fileExtension === 'zip') { const files = await unzip(binaryDataBuffer); for (const key of Object.keys(files)) { - // when files are compresed using MACOSX for some reason they are duplicated under __MACOSX + // when files are compressed using MACOSX for some reason they are duplicated under __MACOSX if (key.includes('__MACOSX')) { continue; } @@ -267,21 +251,7 @@ export class Compression implements INodeType { const binaryObject: IBinaryKeyData = {}; for (const [index, binaryPropertyName] of binaryPropertyNames.entries()) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); if (outputFormat === 'zip') { diff --git a/packages/nodes-base/nodes/Cortex/Cortex.node.ts b/packages/nodes-base/nodes/Cortex/Cortex.node.ts index 495b415c9c..809467d354 100644 --- a/packages/nodes-base/nodes/Cortex/Cortex.node.ts +++ b/packages/nodes-base/nodes/Cortex/Cortex.node.ts @@ -1,18 +1,16 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import { cortexApiRequest, getEntityLabel, prepareParameters, splitTags } from './GenericFunctions'; import { analyzerFields, analyzersOperations } from './AnalyzerDescriptions'; import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { responderFields, respondersOperations } from './ResponderDescription'; @@ -193,24 +191,8 @@ export class Cortex implements INodeType { } if (observableType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const fileBufferData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); const options = { @@ -218,8 +200,8 @@ export class Cortex implements INodeType { data: { value: fileBufferData, options: { - contentType: item.binary[binaryPropertyName].mimeType, - filename: item.binary[binaryPropertyName].fileName, + contentType: binaryData.mimeType, + filename: binaryData.fileName, }, }, _json: JSON.stringify({ @@ -337,27 +319,8 @@ export class Cortex implements INodeType { element.data = artifactvalue.data as string; if (artifactvalue.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data exists on item!', - { itemIndex: i }, - ); - } - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; } @@ -373,24 +336,9 @@ export class Cortex implements INodeType { // deal with file observable if ((body.data as IDataObject).dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = (body.data as IDataObject) .binaryPropertyName as string; - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const fileBufferData = await this.helpers.getBinaryDataBuffer( i, binaryPropertyName, @@ -398,14 +346,14 @@ export class Cortex implements INodeType { const sha256 = createHash('sha256').update(fileBufferData).digest('hex'); (body.data as IDataObject).attachment = { - name: item.binary[binaryPropertyName].fileName, + name: binaryData.fileName, hashes: [ sha256, createHash('sha1').update(fileBufferData).digest('hex'), createHash('md5').update(fileBufferData).digest('hex'), ], size: fileBufferData.byteLength, - contentType: item.binary[binaryPropertyName].mimeType, + contentType: binaryData.mimeType, id: sha256, }; diff --git a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts index edcce4c51c..6d2e2bae1f 100644 --- a/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts +++ b/packages/nodes-base/nodes/Dropbox/Dropbox.node.ts @@ -1,7 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -760,26 +759,9 @@ export class Dropbox implements INodeType { options = { json: false }; if (this.getNodeParameter('binaryData', i)) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i); - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: i }, - ); - } - - body = await this.helpers.getBinaryDataBuffer(i, propertyNameUpload); + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + this.helpers.assertBinaryData(i, binaryPropertyName); + body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); } else { // Is text file body = Buffer.from(this.getNodeParameter('fileContent', i) as string, 'utf8'); diff --git a/packages/nodes-base/nodes/EditImage/EditImage.node.ts b/packages/nodes-base/nodes/EditImage/EditImage.node.ts index efb8409e82..52aba1a1ce 100644 --- a/packages/nodes-base/nodes/EditImage/EditImage.node.ts +++ b/packages/nodes-base/nodes/EditImage/EditImage.node.ts @@ -1,6 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeProperties, @@ -8,7 +8,7 @@ import type { INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { deepCopy, NodeOperationError } from 'n8n-workflow'; +import { deepCopy } from 'n8n-workflow'; import gm from 'gm'; import { file } from 'tmp-promise'; import { parse as pathParse } from 'path'; @@ -1058,20 +1058,7 @@ export class EditImage implements INodeType { if (operations[0].operation !== 'create') { // "create" generates a new image so does not require any incoming data. - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'Item does not contain any binary data.', { - itemIndex, - }); - } - - if (item.binary[dataPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item does not contain any binary data with the name "${dataPropertyName}".`, - { itemIndex }, - ); - } - + this.helpers.assertBinaryData(itemIndex, dataPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( itemIndex, dataPropertyName, @@ -1123,20 +1110,15 @@ export class EditImage implements INodeType { // eslint-disable-next-line @typescript-eslint/restrict-plus-operands (positionX >= 0 ? '+' : '') + positionX + (positionY >= 0 ? '+' : '') + positionY; - if (item.binary![operationData.dataPropertyNameComposite as string] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item does not contain any binary data with the name "${operationData.dataPropertyNameComposite}".`, - { itemIndex }, - ); - } + const binaryPropertyName = operationData.dataPropertyNameComposite as string; + this.helpers.assertBinaryData(itemIndex, binaryPropertyName); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( + itemIndex, + binaryPropertyName, + ); const { fd, path, cleanup } = await file(); cleanupFunctions.push(cleanup); - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( - itemIndex, - operationData.dataPropertyNameComposite as string, - ); await fsWriteFileAsync(fd, binaryDataBuffer); if (operations[0].operation === 'create') { diff --git a/packages/nodes-base/nodes/EmailSend/v1/EmailSendV1.node.ts b/packages/nodes-base/nodes/EmailSend/v1/EmailSendV1.node.ts index 1b6ece9de1..a6b467634d 100644 --- a/packages/nodes-base/nodes/EmailSend/v1/EmailSendV1.node.ts +++ b/packages/nodes-base/nodes/EmailSend/v1/EmailSendV1.node.ts @@ -1,8 +1,7 @@ /* eslint-disable n8n-nodes-base/node-filename-against-convention */ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeBaseDescription, @@ -211,11 +210,9 @@ export class EmailSendV1 implements INodeType { }); for (const propertyName of attachmentProperties) { - if (!item.binary.hasOwnProperty(propertyName)) { - continue; - } + const binaryData = this.helpers.assertBinaryData(itemIndex, propertyName); attachments.push({ - filename: item.binary[propertyName].fileName || 'unknown', + filename: binaryData.fileName || 'unknown', content: await this.helpers.getBinaryDataBuffer(itemIndex, propertyName), }); } diff --git a/packages/nodes-base/nodes/EmailSend/v2/send.operation.ts b/packages/nodes-base/nodes/EmailSend/v2/send.operation.ts index 7ef14a0bde..330aa7c7b7 100644 --- a/packages/nodes-base/nodes/EmailSend/v2/send.operation.ts +++ b/packages/nodes-base/nodes/EmailSend/v2/send.operation.ts @@ -223,11 +223,9 @@ export async function execute(this: IExecuteFunctions): Promise { const accumulator = await acc; if (cur.parameterType === 'formBinaryData') { - const binaryDataOnInput = items[itemIndex]?.binary; if (!cur.inputDataFieldName) return accumulator; - - if (!binaryDataOnInput?.[cur.inputDataFieldName]) { - throw new NodeOperationError( - this.getNode(), - `Input Data Field Name '${cur.inputDataFieldName}' could not be found in input`, - { - runIndex: itemIndex, - }, - ); - } - - if (!cur.inputDataFieldName) return accumulator; - - const binaryData = binaryDataOnInput[cur.inputDataFieldName]; + const binaryData = this.helpers.assertBinaryData(itemIndex, cur.inputDataFieldName); const buffer = await this.helpers.getBinaryDataBuffer(itemIndex, cur.inputDataFieldName); accumulator[cur.name] = { @@ -1143,6 +1128,7 @@ export class HttpRequestV3 implements INodeType { 'inputDataFieldName', itemIndex, ) as string; + this.helpers.assertBinaryData(itemIndex, inputDataFieldName); requestOptions.body = await this.helpers.getBinaryDataBuffer( itemIndex, inputDataFieldName, diff --git a/packages/nodes-base/nodes/HumanticAI/HumanticAi.node.ts b/packages/nodes-base/nodes/HumanticAI/HumanticAi.node.ts index de626c5344..0c8a99a1e0 100644 --- a/packages/nodes-base/nodes/HumanticAI/HumanticAi.node.ts +++ b/packages/nodes-base/nodes/HumanticAI/HumanticAi.node.ts @@ -1,13 +1,10 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { humanticAiApiRequest } from './GenericFunctions'; @@ -71,26 +68,9 @@ export class HumanticAi implements INodeType { if (sendResume) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - responseData = await humanticAiApiRequest.call( this, 'POST', @@ -144,26 +124,9 @@ export class HumanticAi implements INodeType { if (sendResume) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - responseData = await humanticAiApiRequest.call( this, 'POST', diff --git a/packages/nodes-base/nodes/Jira/Jira.node.ts b/packages/nodes-base/nodes/Jira/Jira.node.ts index 884e2f7cbf..8cd27494b6 100644 --- a/packages/nodes-base/nodes/Jira/Jira.node.ts +++ b/packages/nodes-base/nodes/Jira/Jira.node.ts @@ -1057,23 +1057,9 @@ export class Jira implements INodeType { for (let i = 0; i < length; i++) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const issueKey = this.getNodeParameter('issueKey', i) as string; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } let uploadData: Buffer | Readable; - const item = items[i].binary as IBinaryKeyData; - const binaryData = item[binaryPropertyName]; - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - if (binaryData.id) { uploadData = this.helpers.getBinaryStream(binaryData.id); } else { diff --git a/packages/nodes-base/nodes/Keap/Keap.node.ts b/packages/nodes-base/nodes/Keap/Keap.node.ts index d90467d44d..13e110a4ca 100644 --- a/packages/nodes-base/nodes/Keap/Keap.node.ts +++ b/packages/nodes-base/nodes/Keap/Keap.node.ts @@ -1,15 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { keapApiRequest, keapApiRequestAllItems, keysToSnakeCase } from './GenericFunctions'; @@ -742,30 +739,15 @@ export class Keap implements INodeType { keysToSnakeCase(attachmentsUi.attachmentsValues as IDataObject); attachments = attachmentsUi.attachmentsValues as IAttachment[]; } - if ( - attachmentsUi.attachmentsBinary && - (attachmentsUi.attachmentsBinary as IDataObject).length - ) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - for (const { property } of attachmentsUi.attachmentsBinary as IDataObject[]) { - const item = items[i].binary as IBinaryKeyData; - - if (item[property as string] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${property}"`, - { itemIndex: i }, - ); - } - + const attachmentsBinary = attachmentsUi.attachmentsBinary as Array<{ + property: string; + }>; + if (attachmentsBinary?.length) { + for (const { property } of attachmentsBinary) { + const binaryData = this.helpers.assertBinaryData(i, property); attachments.push({ - file_data: item[property as string].data, - file_name: item[property as string].fileName, + file_data: binaryData.data, + file_name: binaryData.fileName, }); } } @@ -815,7 +797,6 @@ export class Keap implements INodeType { } //https://developer.infusionsoft.com/docs/rest/#!/File/createFileUsingPOST if (operation === 'upload') { - const binaryData = this.getNodeParameter('binaryData', i); const fileAssociation = this.getNodeParameter('fileAssociation', i) as string; const isPublic = this.getNodeParameter('isPublic', i) as boolean; const body: IFile = { @@ -826,27 +807,11 @@ export class Keap implements INodeType { const contactId = parseInt(this.getNodeParameter('contactId', i) as string, 10); body.contact_id = contactId; } - if (binaryData) { + if (this.getNodeParameter('binaryData', i)) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - if (item[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - body.file_data = item[binaryPropertyName].data; - body.file_name = item[binaryPropertyName].fileName; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + body.file_data = binaryData.data; + body.file_name = binaryData.fileName; } else { const fileName = this.getNodeParameter('fileName', i) as string; const fileData = this.getNodeParameter('fileData', i) as string; diff --git a/packages/nodes-base/nodes/Line/Line.node.ts b/packages/nodes-base/nodes/Line/Line.node.ts index 377c901366..160bfd961f 100644 --- a/packages/nodes-base/nodes/Line/Line.node.ts +++ b/packages/nodes-base/nodes/Line/Line.node.ts @@ -1,13 +1,10 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { lineApiRequest } from './GenericFunctions'; @@ -97,27 +94,9 @@ export class Line implements INodeType { const image = (body.imageUi as IDataObject).imageValue as IDataObject; if (image && image.binaryData === true) { - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - //@ts-ignore - if (items[i].binary[image.binaryProperty] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${image.binaryProperty}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[ - image.binaryProperty as string - ]; - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( - i, - image.binaryProperty as string, - ); + const binaryProperty = image.binaryProperty as string; + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); body.imageFile = { value: binaryDataBuffer, diff --git a/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts b/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts index eee851e9d5..72ca14795b 100644 --- a/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts +++ b/packages/nodes-base/nodes/LinkedIn/LinkedIn.node.ts @@ -1,13 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { linkedInApiRequest } from './GenericFunctions'; import { postFields, postOperations } from './PostDescription'; @@ -137,27 +136,11 @@ export class LinkedIn implements INodeType { ].uploadUrl as string; const asset = registerObject.value.asset as string; - // Prepare binary file upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i); - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: i }, - ); - } + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + this.helpers.assertBinaryData(i, binaryPropertyName); // Buffer binary data - const buffer = await this.helpers.getBinaryDataBuffer(i, propertyNameUpload); + const buffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); // Upload image await linkedInApiRequest.call(this, 'POST', uploadUrl, buffer, true); diff --git a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts index f5f70fa92a..abb12690e0 100644 --- a/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts +++ b/packages/nodes-base/nodes/Mailgun/Mailgun.node.ts @@ -148,9 +148,7 @@ export class Mailgun implements INodeType { }); for (const propertyName of attachmentProperties) { - if (!item.binary.hasOwnProperty(propertyName)) { - continue; - } + const binaryData = this.helpers.assertBinaryData(itemIndex, propertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( itemIndex, propertyName, @@ -158,7 +156,7 @@ export class Mailgun implements INodeType { attachments.push({ value: binaryDataBuffer, options: { - filename: item.binary[propertyName].fileName || 'unknown', + filename: binaryData.fileName || 'unknown', }, }); } diff --git a/packages/nodes-base/nodes/Matrix/GenericFunctions.ts b/packages/nodes-base/nodes/Matrix/GenericFunctions.ts index 2711887537..a01b846934 100644 --- a/packages/nodes-base/nodes/Matrix/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Matrix/GenericFunctions.ts @@ -1,10 +1,14 @@ import type { OptionsWithUri } from 'request'; -import type { IDataObject, JsonObject } from 'n8n-workflow'; +import type { + IDataObject, + IExecuteFunctions, + IExecuteSingleFunctions, + ILoadOptionsFunctions, + JsonObject, +} from 'n8n-workflow'; import { NodeApiError, NodeOperationError } from 'n8n-workflow'; -import type { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions } from 'n8n-core'; - import { v4 as uuid } from 'uuid'; export async function matrixApiRequest( @@ -190,25 +194,11 @@ export async function handleMatrixCall( const qs: IDataObject = {}; const headers: IDataObject = {}; - if ( - item.binary === undefined || - //@ts-ignore - item.binary[binaryPropertyName] === undefined - ) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - ); - } - - // @ts-ignore - qs.filename = item.binary[binaryPropertyName].fileName; - //@ts-ignore - const filename = item.binary[binaryPropertyName].fileName; - + const { fileName, mimeType } = this.helpers.assertBinaryData(index, binaryPropertyName); body = await this.helpers.getBinaryDataBuffer(index, binaryPropertyName); - //@ts-ignore - headers['Content-Type'] = item.binary[binaryPropertyName].mimeType; + + qs.filename = fileName; + headers['Content-Type'] = mimeType; headers.accept = 'application/json,text/*;q=0.99'; const uploadRequestResult = await matrixApiRequest.call( @@ -226,7 +216,7 @@ export async function handleMatrixCall( body = { msgtype: `m.${mediaType}`, - body: filename, + body: fileName, url: uploadRequestResult.content_uri, }; const messageId = uuid(); diff --git a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts index c35b2dfc36..0b17f7a25e 100644 --- a/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts +++ b/packages/nodes-base/nodes/Microsoft/OneDrive/MicrosoftOneDrive.node.ts @@ -1,8 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -197,22 +195,7 @@ export class MicrosoftOneDrive implements INodeType { if (isBinaryData) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); let encodedFilename; diff --git a/packages/nodes-base/nodes/Microsoft/Outlook/GenericFunctions.ts b/packages/nodes-base/nodes/Microsoft/Outlook/GenericFunctions.ts index a8c8ace503..8389f8b6d3 100644 --- a/packages/nodes-base/nodes/Microsoft/Outlook/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Microsoft/Outlook/GenericFunctions.ts @@ -4,7 +4,7 @@ import type { IExecuteFunctions, IExecuteSingleFunctions, ILoadOptionsFunctions import { BINARY_ENCODING } from 'n8n-core'; import type { IDataObject, INodeExecutionData, JsonObject } from 'n8n-workflow'; -import { NodeApiError, NodeOperationError } from 'n8n-workflow'; +import { NodeApiError } from 'n8n-workflow'; export async function microsoftApiRequest( this: IExecuteFunctions | IExecuteSingleFunctions | ILoadOptionsFunctions, @@ -228,24 +228,8 @@ export async function binaryToAttachments( ) { return Promise.all( attachments.map(async (attachment) => { - const { binary } = items[i]; - - if (binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = attachment.binaryPropertyName as string; - if (binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = binary[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); return { '@odata.type': '#microsoft.graph.fileAttachment', diff --git a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts index c083dc1544..c37e7a52be 100644 --- a/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts +++ b/packages/nodes-base/nodes/Microsoft/Outlook/MicrosoftOutlook.node.ts @@ -1,8 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, @@ -643,19 +641,7 @@ export class MicrosoftOutlook implements INodeType { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); const additionalFields = this.getNodeParameter('additionalFields', i); - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); const fileName = diff --git a/packages/nodes-base/nodes/Mindee/Mindee.node.ts b/packages/nodes-base/nodes/Mindee/Mindee.node.ts index 30db7901f4..c7b2e79f48 100644 --- a/packages/nodes-base/nodes/Mindee/Mindee.node.ts +++ b/packages/nodes-base/nodes/Mindee/Mindee.node.ts @@ -1,8 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -160,27 +158,12 @@ export class Mindee implements INodeType { try { if (resource === 'receipt') { if (operation === 'predict') { + const rawData = this.getNodeParameter('rawData', i); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - const rawData = this.getNodeParameter('rawData', i); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - ); - } if (version === 1) { responseData = await mindeeApiRequest.call( this, @@ -233,27 +216,12 @@ export class Mindee implements INodeType { if (resource === 'invoice') { if (operation === 'predict') { + const rawData = this.getNodeParameter('rawData', i); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - const rawData = this.getNodeParameter('rawData', i); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - ); - } if (version === 1) { endpoint = '/invoices/v1/predict'; responseData = await mindeeApiRequest.call( diff --git a/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts b/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts index 25d1dd13a4..09be2137e6 100644 --- a/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts +++ b/packages/nodes-base/nodes/NextCloud/NextCloud.node.ts @@ -1,8 +1,7 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -902,26 +901,9 @@ export class NextCloud implements INodeType { endpoint = this.getNodeParameter('path', i) as string; if (this.getNodeParameter('binaryDataUpload', i) === true) { - // Is binary file to upload - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i); - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: i }, - ); - } - - body = await this.helpers.getBinaryDataBuffer(i, propertyNameUpload); + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + this.helpers.assertBinaryData(i, binaryPropertyName); + body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); } else { // Is text file body = this.getNodeParameter('fileContent', i) as string; diff --git a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts index 24c7ccaa09..71e139a92c 100644 --- a/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts +++ b/packages/nodes-base/nodes/NocoDB/NocoDB.node.ts @@ -1,8 +1,7 @@ /* eslint-disable n8n-nodes-base/node-filename-against-convention */ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeType, @@ -265,20 +264,8 @@ export class NocoDB implements INodeType { if (!field.binaryData) { newItem[field.fieldName] = field.fieldValue; } else if (field.binaryProperty) { - if (!items[i].binary) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } const binaryPropertyName = field.binaryProperty; - if (binaryPropertyName && !items[i].binary![binaryPropertyName]) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - const binaryData = items[i].binary![binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); const formData = { @@ -581,20 +568,8 @@ export class NocoDB implements INodeType { if (!field.binaryData) { newItem[field.fieldName] = field.fieldValue; } else if (field.binaryProperty) { - if (!items[i].binary) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } const binaryPropertyName = field.binaryProperty; - if (binaryPropertyName && !items[i].binary![binaryPropertyName]) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - const binaryData = items[i].binary![binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); const formData = { diff --git a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts index 5bca7f6d2f..306885acbc 100644 --- a/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts +++ b/packages/nodes-base/nodes/Pipedrive/Pipedrive.node.ts @@ -1,6 +1,7 @@ -import type { IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-core'; import type { IDataObject, + IExecuteFunctions, + ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, @@ -4337,31 +4338,15 @@ export class Pipedrive implements INodeType { requestMethod = 'POST'; endpoint = '/files'; - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const fileBufferData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); formData.file = { value: fileBufferData, options: { - contentType: item.binary[binaryPropertyName].mimeType, - filename: item.binary[binaryPropertyName].fileName, + contentType: binaryData.mimeType, + filename: binaryData.fileName, }, }; diff --git a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts index 55f9dd5d82..1c563f747d 100644 --- a/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts +++ b/packages/nodes-base/nodes/Pushbullet/Pushbullet.node.ts @@ -1,15 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { pushbulletApiRequest, pushbulletApiRequestAllItems } from './GenericFunctions'; @@ -408,20 +405,7 @@ export class Pushbullet implements INodeType { if (type === 'file') { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); //create upload url diff --git a/packages/nodes-base/nodes/Pushover/Pushover.node.ts b/packages/nodes-base/nodes/Pushover/Pushover.node.ts index a64142e81f..477e997d4a 100644 --- a/packages/nodes-base/nodes/Pushover/Pushover.node.ts +++ b/packages/nodes-base/nodes/Pushover/Pushover.node.ts @@ -1,15 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { pushoverApiRequest } from './GenericFunctions'; @@ -339,25 +336,7 @@ export class Pushover implements INodeType { if (attachment) { const binaryPropertyName = attachment.binaryPropertyName as string; - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryPropertyName]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); body.attachment = { diff --git a/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts b/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts index 956ded4f7f..dc3d5f167b 100644 --- a/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts +++ b/packages/nodes-base/nodes/Raindrop/Raindrop.node.ts @@ -315,23 +315,8 @@ export class Raindrop implements INodeType { // cover-specific endpoint if (updateFields.cover) { - if (!items[i].binary) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - if (!updateFields.cover) { - throw new NodeOperationError( - this.getNode(), - 'Please enter a binary property to upload a cover image.', - { itemIndex: i }, - ); - } - const binaryPropertyName = updateFields.cover as string; - - const binaryData = items[i].binary![binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); const formData = { diff --git a/packages/nodes-base/nodes/ReadPdf/ReadPDF.node.ts b/packages/nodes-base/nodes/ReadPdf/ReadPDF.node.ts index 5242246347..8fc6adb182 100644 --- a/packages/nodes-base/nodes/ReadPdf/ReadPDF.node.ts +++ b/packages/nodes-base/nodes/ReadPdf/ReadPDF.node.ts @@ -52,11 +52,14 @@ export class ReadPDF implements INodeType { item.binary = {}; } - const binaryData = await this.helpers.getBinaryDataBuffer(itemIndex, binaryPropertyName); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( + itemIndex, + binaryPropertyName, + ); returnData.push({ binary: item.binary, - json: (await pdf(binaryData)) as unknown as IDataObject, + json: (await pdf(binaryDataBuffer)) as unknown as IDataObject, }); } catch (error) { if (this.continueOnFail()) { diff --git a/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts b/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts index 8af6f7be06..3296d404c8 100644 --- a/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts +++ b/packages/nodes-base/nodes/RespondToWebhook/RespondToWebhook.node.ts @@ -1,7 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, IN8nHttpFullResponse, IN8nHttpResponse, INodeExecutionData, @@ -215,7 +214,7 @@ export class RespondToWebhook implements INodeType { } else if (respondWith === 'text') { responseBody = this.getNodeParameter('responseBody', 0) as string; } else if (respondWith === 'binary') { - const item = this.getInputData()[0]; + const item = items[0]; if (item.binary === undefined) { throw new NodeOperationError(this.getNode(), 'No binary data exists on the first item!'); @@ -235,19 +234,12 @@ export class RespondToWebhook implements INodeType { responseBinaryPropertyName = binaryKeys[0]; } - const binaryData = item.binary[responseBinaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(0, responseBinaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( 0, responseBinaryPropertyName, ); - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${responseBinaryPropertyName}"`, - ); - } - if (!headers['content-type']) { headers['content-type'] = binaryData.mimeType; } diff --git a/packages/nodes-base/nodes/S3/S3.node.ts b/packages/nodes-base/nodes/S3/S3.node.ts index 896ac5d36a..de9f08825c 100644 --- a/packages/nodes-base/nodes/S3/S3.node.ts +++ b/packages/nodes-base/nodes/S3/S3.node.ts @@ -4,11 +4,9 @@ import { createHash } from 'crypto'; import { Builder } from 'xml2js'; -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -837,22 +835,7 @@ export class S3 implements INodeType { if (isBinaryData) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', 0); - - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - if ((items[i].binary as IBinaryKeyData)[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); headers['Content-Type'] = binaryData.mimeType; diff --git a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts index 95997fcd7d..09c9bfdcbf 100644 --- a/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts +++ b/packages/nodes-base/nodes/Salesforce/Salesforce.node.ts @@ -1834,7 +1834,6 @@ export class Salesforce implements INodeType { const title = this.getNodeParameter('title', i) as string; const additionalFields = this.getNodeParameter('additionalFields', i); const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - let data; const body: { entity_content: { [key: string]: string } } = { entity_content: { Title: title, @@ -1848,34 +1847,26 @@ export class Salesforce implements INodeType { body.entity_content.FirstPublishLocationId = additionalFields.linkToObjectId as string; } - if (items[i].binary && items[i].binary![binaryPropertyName]) { - const binaryData = items[i].binary![binaryPropertyName]; - const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - body.entity_content.PathOnClient = `${title}.${ - additionalFields.fileExtension || binaryData.fileExtension - }`; - data = { - entity_content: { - value: JSON.stringify(body.entity_content), - options: { - contentType: 'application/json', - }, + body.entity_content.PathOnClient = `${title}.${ + additionalFields.fileExtension || binaryData.fileExtension + }`; + const data = { + entity_content: { + value: JSON.stringify(body.entity_content), + options: { + contentType: 'application/json', }, - VersionData: { - value: dataBuffer, - options: { - filename: body.entity_content.PathOnClient, - }, + }, + VersionData: { + value: dataBuffer, + options: { + filename: body.entity_content.PathOnClient, }, - }; - } else { - throw new NodeOperationError( - this.getNode(), - `The property ${binaryPropertyName} does not exist`, - { itemIndex: i }, - ); - } + }, + }; responseData = await salesforceApiRequest.call( this, 'POST', diff --git a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts index 09e8769da1..8409f7d526 100644 --- a/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts +++ b/packages/nodes-base/nodes/SendGrid/SendGrid.node.ts @@ -1,14 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { listFields, listOperations } from './ListDescription'; @@ -588,22 +586,13 @@ export class SendGrid implements INodeType { const binaryProperties = attachments.split(',').map((p) => p.trim()); for (const property of binaryProperties) { - if (!items[i].binary?.hasOwnProperty(property)) { - throw new NodeOperationError( - this.getNode(), - `The binary property ${property} does not exist`, - { itemIndex: i }, - ); - } - - const binaryProperty = items[i].binary![property]; - + const binaryData = this.helpers.assertBinaryData(i, property); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, property); attachmentsToSend.push({ content: dataBuffer.toString('base64'), - filename: binaryProperty.fileName || 'unknown', - type: binaryProperty.mimeType, + filename: binaryData.fileName || 'unknown', + type: binaryData.mimeType, }); } diff --git a/packages/nodes-base/nodes/SendInBlue/GenericFunctions.ts b/packages/nodes-base/nodes/SendInBlue/GenericFunctions.ts index 4520c02934..73ab3272cf 100644 --- a/packages/nodes-base/nodes/SendInBlue/GenericFunctions.ts +++ b/packages/nodes-base/nodes/SendInBlue/GenericFunctions.ts @@ -84,20 +84,8 @@ export namespace SendInBlueNode { const { binaryPropertyName } = dataPropertyList; const dataMappingList = (binaryPropertyName as string).split(','); for (const attachmentDataName of dataMappingList) { - const binaryPropertyAttachmentName = attachmentDataName; - - const item = this.getInputData(); - - if (item.binary![binaryPropertyAttachmentName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - ); - } - - const bufferFromIncomingData = await this.helpers.getBinaryDataBuffer( - binaryPropertyAttachmentName, - ); + const binaryData = this.helpers.assertBinaryData(attachmentDataName); + const bufferFromIncomingData = await this.helpers.getBinaryDataBuffer(attachmentDataName); const { data: content, @@ -111,7 +99,7 @@ export namespace SendInBlueNode { itemIndex, mimeType, fileExtension!, - fileName || item.binary!.data.fileName!, + fileName ?? binaryData.fileName!, ); attachment.push({ content, name }); diff --git a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts index c1f9f11491..0a60990513 100644 --- a/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts +++ b/packages/nodes-base/nodes/ServiceNow/ServiceNow.node.ts @@ -1,8 +1,7 @@ -import type { IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-core'; - import type { - IBinaryData, IDataObject, + IExecuteFunctions, + ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, @@ -605,17 +604,7 @@ export class ServiceNow implements INodeType { const inputDataFieldName = this.getNodeParameter('inputDataFieldName', i) as string; const options = this.getNodeParameter('options', i); - let binaryData: IBinaryData; - - if (items[i].binary && items[i].binary![inputDataFieldName]) { - binaryData = items[i].binary![inputDataFieldName]; - } else { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${inputDataFieldName}"`, - { itemIndex: i }, - ); - } + const binaryData = this.helpers.assertBinaryData(i, inputDataFieldName); const headers: IDataObject = { 'Content-Type': binaryData.mimeType, diff --git a/packages/nodes-base/nodes/Signl4/Signl4.node.ts b/packages/nodes-base/nodes/Signl4/Signl4.node.ts index ad40f54310..58bb4e6aab 100644 --- a/packages/nodes-base/nodes/Signl4/Signl4.node.ts +++ b/packages/nodes-base/nodes/Signl4/Signl4.node.ts @@ -1,8 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -279,39 +277,31 @@ export class Signl4 implements INodeType { // Attachments const attachments = additionalFields.attachmentsUi as IDataObject; - if (attachments) { - if (attachments.attachmentsBinary && items[i].binary) { - const propertyName = (attachments.attachmentsBinary as IDataObject) - .property as string; + if (attachments?.attachmentsBinary) { + const propertyName = (attachments.attachmentsBinary as IDataObject) + .property as string; - const binaryProperty = (items[i].binary as IBinaryKeyData)[propertyName]; + const binaryData = this.helpers.assertBinaryData(i, propertyName); - if (binaryProperty) { - const supportedFileExtension = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'mp3', 'wav']; + if (binaryData) { + const supportedFileExtension = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'mp3', 'wav']; - if (!supportedFileExtension.includes(binaryProperty.fileExtension as string)) { - throw new NodeOperationError( - this.getNode(), - `Invalid extension, just ${supportedFileExtension.join(',')} are supported}`, - { itemIndex: i }, - ); - } - - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, propertyName); - data.attachment = { - value: binaryDataBuffer, - options: { - filename: binaryProperty.fileName, - contentType: binaryProperty.mimeType, - }, - }; - } else { + if (!supportedFileExtension.includes(binaryData.fileExtension as string)) { throw new NodeOperationError( this.getNode(), - `Binary property ${propertyName} does not exist on input`, + `Invalid extension, just ${supportedFileExtension.join(',')} are supported}`, { itemIndex: i }, ); } + + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, propertyName); + data.attachment = { + value: binaryDataBuffer, + options: { + filename: binaryData.fileName, + contentType: binaryData.mimeType, + }, + }; } } diff --git a/packages/nodes-base/nodes/Slack/V1/SlackV1.node.ts b/packages/nodes-base/nodes/Slack/V1/SlackV1.node.ts index cf97def17b..26d169f39d 100644 --- a/packages/nodes-base/nodes/Slack/V1/SlackV1.node.ts +++ b/packages/nodes-base/nodes/Slack/V1/SlackV1.node.ts @@ -1,7 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, @@ -1076,7 +1075,6 @@ export class SlackV1 implements INodeType { //https://api.slack.com/methods/files.upload if (operation === 'upload') { const options = this.getNodeParameter('options', i); - const binaryData = this.getNodeParameter('binaryData', i); const body: IDataObject = {}; if (options.channelIds) { body.channels = (options.channelIds as string[]).join(','); @@ -1093,31 +1091,18 @@ export class SlackV1 implements INodeType { if (options.title) { body.title = options.title as string; } - if (binaryData) { + if (this.getNodeParameter('binaryData', i)) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - if ( - items[i].binary === undefined || - //@ts-ignore - items[i].binary[binaryPropertyName] === undefined - ) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const binaryDataBuffer = await this.helpers.getBinaryDataBuffer( i, binaryPropertyName, ); body.file = { - //@ts-ignore value: binaryDataBuffer, options: { - //@ts-ignore - filename: items[i].binary[binaryPropertyName].fileName, - //@ts-ignore - contentType: items[i].binary[binaryPropertyName].mimeType, + filename: binaryData.fileName, + contentType: binaryData.mimeType, }, }; responseData = await slackApiRequest.call( diff --git a/packages/nodes-base/nodes/Slack/V2/SlackV2.node.ts b/packages/nodes-base/nodes/Slack/V2/SlackV2.node.ts index 5bed04d053..930f6b3e97 100644 --- a/packages/nodes-base/nodes/Slack/V2/SlackV2.node.ts +++ b/packages/nodes-base/nodes/Slack/V2/SlackV2.node.ts @@ -1,9 +1,9 @@ -import type { IExecuteFunctions } from 'n8n-core'; import { BINARY_ENCODING } from 'n8n-core'; import type { Readable } from 'stream'; import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeListSearchItems, @@ -1043,7 +1043,6 @@ export class SlackV2 implements INodeType { //https://api.slack.com/methods/files.upload if (operation === 'upload') { const options = this.getNodeParameter('options', i); - const binaryData = this.getNodeParameter('binaryData', i); const body: IDataObject = {}; if (options.channelIds) { body.channels = (options.channelIds as string[]).join(','); @@ -1060,34 +1059,21 @@ export class SlackV2 implements INodeType { if (options.title) { body.title = options.title as string; } - if (binaryData) { + if (this.getNodeParameter('binaryData', i)) { const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); - if ( - items[i].binary === undefined || - //@ts-ignore - items[i].binary[binaryPropertyName] === undefined - ) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); + let uploadData: Buffer | Readable; - const itemBinaryData = items[i].binary![binaryPropertyName]; - if (itemBinaryData.id) { - uploadData = this.helpers.getBinaryStream(itemBinaryData.id); + if (binaryData.id) { + uploadData = this.helpers.getBinaryStream(binaryData.id); } else { - uploadData = Buffer.from(itemBinaryData.data, BINARY_ENCODING); + uploadData = Buffer.from(binaryData.data, BINARY_ENCODING); } body.file = { - //@ts-ignore value: uploadData, options: { - //@ts-ignore - filename: itemBinaryData.fileName, - //@ts-ignore - contentType: itemBinaryData.mimeType, + filename: binaryData.fileName, + contentType: binaryData.mimeType, }, }; responseData = await slackApiRequest.call( diff --git a/packages/nodes-base/nodes/SpreadsheetFile/SpreadsheetFile.node.ts b/packages/nodes-base/nodes/SpreadsheetFile/SpreadsheetFile.node.ts index ea08c2d698..ac51121f9b 100644 --- a/packages/nodes-base/nodes/SpreadsheetFile/SpreadsheetFile.node.ts +++ b/packages/nodes-base/nodes/SpreadsheetFile/SpreadsheetFile.node.ts @@ -1,7 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, @@ -295,30 +294,22 @@ export class SpreadsheetFile implements INodeType { if (operation === 'fromFile') { // Read data from spreadsheet file to workflow - - let item: INodeExecutionData; for (let i = 0; i < items.length; i++) { try { - item = items[i]; - const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); const options = this.getNodeParameter('options', i, {}); - if (item.binary === undefined || item.binary[binaryPropertyName] === undefined) { - // Property did not get found on item - continue; - } - + this.helpers.assertBinaryData(i, binaryPropertyName); // Read the binary spreadsheet data - const binaryData = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); let workbook; if (options.readAsString === true) { - workbook = xlsxRead(binaryData.toString(), { + workbook = xlsxRead(binaryDataBuffer.toString(), { type: 'string', raw: options.rawData as boolean, }); } else { - workbook = xlsxRead(binaryData, { raw: options.rawData as boolean }); + workbook = xlsxRead(binaryDataBuffer, { raw: options.rawData as boolean }); } if (workbook.SheetNames.length === 0) { diff --git a/packages/nodes-base/nodes/Ssh/Ssh.node.ts b/packages/nodes-base/nodes/Ssh/Ssh.node.ts index b846ecb679..0c0063314f 100644 --- a/packages/nodes-base/nodes/Ssh/Ssh.node.ts +++ b/packages/nodes-base/nodes/Ssh/Ssh.node.ts @@ -1,13 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; import { BINARY_ENCODING } from 'n8n-core'; import type { IDataObject, + IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { rm, writeFile } from 'fs/promises'; @@ -341,25 +340,8 @@ export class Ssh implements INodeType { const parameterPath = this.getNodeParameter('path', i) as string; const fileName = this.getNodeParameter('options.fileName', i, '') as string; - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - - const propertyNameUpload = this.getNodeParameter('binaryPropertyName', i); - - const binaryData = item.binary[propertyNameUpload]; - - if (item.binary[propertyNameUpload] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${propertyNameUpload}"`, - { itemIndex: i }, - ); - } + const binaryPropertyName = this.getNodeParameter('binaryPropertyName', i); + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); let uploadData: Buffer | Readable; if (binaryData.id) { diff --git a/packages/nodes-base/nodes/TheHive/TheHive.node.ts b/packages/nodes-base/nodes/TheHive/TheHive.node.ts index d868d23025..4a89fadafc 100644 --- a/packages/nodes-base/nodes/TheHive/TheHive.node.ts +++ b/packages/nodes-base/nodes/TheHive/TheHive.node.ts @@ -1,8 +1,7 @@ /* eslint-disable @typescript-eslint/dot-notation */ -import type { IExecuteFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodeParameters, @@ -10,7 +9,6 @@ import type { INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { alertFields, alertOperations } from './descriptions/AlertDescription'; @@ -427,28 +425,8 @@ export class TheHive implements INodeType { element.data = artifactvalue.data as string; if (artifactvalue.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data exists on item!', - { itemIndex: i }, - ); - } - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[binaryPropertyName]; - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; } @@ -704,28 +682,8 @@ export class TheHive implements INodeType { element.data = artifactvalue.data as string; if (artifactvalue.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data exists on item!', - { itemIndex: i }, - ); - } - const binaryPropertyName = artifactvalue.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[binaryPropertyName]; - + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); element.data = `${binaryData.fileName};${binaryData.mimeType};${binaryData.data}`; } @@ -905,25 +863,8 @@ export class TheHive implements INodeType { let options: IDataObject = {}; if (body.dataType === 'file') { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = this.getNodeParameter('binaryProperty', i); - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); options = { @@ -1765,25 +1706,8 @@ export class TheHive implements INodeType { .attachmentValues as IDataObject; if (attachmentValues) { - const item = items[i]; - - if (item.binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!', { - itemIndex: i, - }); - } - const binaryPropertyName = attachmentValues.binaryProperty as string; - - if (item.binary[binaryPropertyName] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryPropertyName}"`, - { itemIndex: i }, - ); - } - - const binaryData = item.binary[binaryPropertyName]; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); options = { diff --git a/packages/nodes-base/nodes/Twist/Twist.node.ts b/packages/nodes-base/nodes/Twist/Twist.node.ts index 0262339160..3a7a646b3d 100644 --- a/packages/nodes-base/nodes/Twist/Twist.node.ts +++ b/packages/nodes-base/nodes/Twist/Twist.node.ts @@ -1,15 +1,12 @@ -import type { IExecuteFunctions } from 'n8n-core'; - import type { - IBinaryKeyData, IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, INodeTypeDescription, } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; import { twistApiRequest } from './GenericFunctions'; @@ -254,18 +251,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( @@ -363,18 +349,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( @@ -442,18 +417,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( @@ -567,18 +531,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( @@ -651,18 +604,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( @@ -759,18 +701,7 @@ export class Twist implements INodeType { const attachments: IDataObject[] = []; for (const binaryProperty of binaryProperties) { - const item = items[i].binary as IBinaryKeyData; - - const binaryData = item[binaryProperty]; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } - + const binaryData = this.helpers.assertBinaryData(i, binaryProperty); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); attachments.push( diff --git a/packages/nodes-base/nodes/Twitter/GenericFunctions.ts b/packages/nodes-base/nodes/Twitter/GenericFunctions.ts index 32481f2344..94194b8243 100644 --- a/packages/nodes-base/nodes/Twitter/GenericFunctions.ts +++ b/packages/nodes-base/nodes/Twitter/GenericFunctions.ts @@ -1,13 +1,13 @@ import type { OptionsWithUrl } from 'request'; import type { + IDataObject, IExecuteFunctions, IExecuteSingleFunctions, IHookFunctions, ILoadOptionsFunctions, -} from 'n8n-core'; - -import type { IBinaryKeyData, IDataObject, INodeExecutionData, JsonObject } from 'n8n-workflow'; + JsonObject, +} from 'n8n-workflow'; import { NodeApiError, NodeOperationError, sleep } from 'n8n-workflow'; export async function twitterApiRequest( @@ -80,7 +80,6 @@ export function chunks(buffer: Buffer, chunkSize: number) { export async function uploadAttachments( this: IExecuteFunctions, binaryProperties: string[], - items: INodeExecutionData[], i: number, ) { const uploadUri = 'https://upload.twitter.com/1.1/media/upload.json'; @@ -88,27 +87,14 @@ export async function uploadAttachments( const media: IDataObject[] = []; for (const binaryPropertyName of binaryProperties) { - const binaryData = items[i].binary as IBinaryKeyData; - - if (binaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data set. So file can not be written!', - { itemIndex: i }, - ); - } - - if (!binaryData[binaryPropertyName]) { - continue; - } - let attachmentBody = {}; let response: IDataObject = {}; + const binaryData = this.helpers.assertBinaryData(i, binaryPropertyName); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - const isAnimatedWebp = dataBuffer.toString().indexOf('ANMF') !== -1; - const isImage = binaryData[binaryPropertyName].mimeType.includes('image'); + const isAnimatedWebp = dataBuffer.toString().indexOf('ANMF') !== -1; + const isImage = binaryData.mimeType.includes('image'); if (isImage && isAnimatedWebp) { throw new NodeOperationError( @@ -120,7 +106,7 @@ export async function uploadAttachments( if (isImage) { const form = { - media_data: binaryData[binaryPropertyName].data, + media_data: binaryData.data, }; response = await twitterApiRequest.call(this, 'POST', '', {}, {}, uploadUri, { @@ -130,13 +116,10 @@ export async function uploadAttachments( media.push(response); } else { // https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload-init - - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName); - attachmentBody = { command: 'INIT', - total_bytes: binaryDataBuffer.byteLength, - media_type: binaryData[binaryPropertyName].mimeType, + total_bytes: dataBuffer.byteLength, + media_type: binaryData.mimeType, }; response = await twitterApiRequest.call(this, 'POST', '', {}, {}, uploadUri, { @@ -147,7 +130,7 @@ export async function uploadAttachments( // break the data on 5mb chunks (max size that can be uploaded at once) - const binaryParts = chunks(binaryDataBuffer, 5242880); + const binaryParts = chunks(dataBuffer, 5242880); let index = 0; @@ -155,7 +138,7 @@ export async function uploadAttachments( //https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload-append attachmentBody = { - name: binaryData[binaryPropertyName].fileName, + name: binaryData.fileName, command: 'APPEND', media_id: mediaId, media_data: Buffer.from(binaryPart).toString('base64'), diff --git a/packages/nodes-base/nodes/Twitter/Twitter.node.ts b/packages/nodes-base/nodes/Twitter/Twitter.node.ts index 37945c9033..96507dee31 100644 --- a/packages/nodes-base/nodes/Twitter/Twitter.node.ts +++ b/packages/nodes-base/nodes/Twitter/Twitter.node.ts @@ -1,7 +1,7 @@ -import type { IExecuteFunctions, ILoadOptionsFunctions } from 'n8n-core'; - import type { IDataObject, + IExecuteFunctions, + ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, INodeType, @@ -125,7 +125,7 @@ export class Twitter implements INodeType { return propertyName.trim(); }); - const medias = await uploadAttachments.call(this, attachmentProperties, items, i); + const medias = await uploadAttachments.call(this, attachmentProperties, i); body.message_create.message_data.attachment = { type: 'media', //@ts-ignore @@ -166,7 +166,7 @@ export class Twitter implements INodeType { return propertyName.trim(); }); - const medias = await uploadAttachments.call(this, attachmentProperties, items, i); + const medias = await uploadAttachments.call(this, attachmentProperties, i); body.media_ids = (medias as IDataObject[]) .map((media: IDataObject) => media.media_id_string) diff --git a/packages/nodes-base/nodes/WhatsApp/MediaFunctions.ts b/packages/nodes-base/nodes/WhatsApp/MediaFunctions.ts index 40298e00ab..643c543f4d 100644 --- a/packages/nodes-base/nodes/WhatsApp/MediaFunctions.ts +++ b/packages/nodes-base/nodes/WhatsApp/MediaFunctions.ts @@ -10,25 +10,20 @@ export async function getUploadFormData( if (!mediaPropertyName) throw new NodeOperationError(this.getNode(), 'Parameter "mediaPropertyName" is not defined'); - const { binary: binaryData } = this.getInputData(); - if (!binaryData) throw new NodeOperationError(this.getNode(), 'Binary data missing in input'); - - const binaryFile = binaryData[mediaPropertyName]; - if (binaryFile === undefined) - throw new NodeOperationError(this.getNode(), 'Could not find file in node input data'); + const binaryData = this.helpers.assertBinaryData(mediaPropertyName); const mediaFileName = (this.getNodeParameter('additionalFields') as IDataObject).mediaFileName as | string | undefined; - const fileName = mediaFileName || binaryFile.fileName; + const fileName = mediaFileName || binaryData.fileName; if (!fileName) throw new NodeOperationError(this.getNode(), 'No file name given for media upload.'); const buffer = await this.helpers.getBinaryDataBuffer(mediaPropertyName); const formData = new FormData(); - formData.append('file', buffer, { contentType: binaryFile.mimeType, filename: fileName }); + formData.append('file', buffer, { contentType: binaryData.mimeType, filename: fileName }); formData.append('messaging_product', 'whatsapp'); return { fileName, formData }; diff --git a/packages/nodes-base/nodes/WriteBinaryFile/WriteBinaryFile.node.ts b/packages/nodes-base/nodes/WriteBinaryFile/WriteBinaryFile.node.ts index 9b07c51213..dc3695c4aa 100644 --- a/packages/nodes-base/nodes/WriteBinaryFile/WriteBinaryFile.node.ts +++ b/packages/nodes-base/nodes/WriteBinaryFile/WriteBinaryFile.node.ts @@ -1,7 +1,10 @@ -import type { IExecuteFunctions } from 'n8n-core'; import { BINARY_ENCODING } from 'n8n-core'; -import type { INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow'; -import { NodeOperationError } from 'n8n-workflow'; +import type { + IExecuteFunctions, + INodeExecutionData, + INodeType, + INodeTypeDescription, +} from 'n8n-workflow'; import { writeFile as fsWriteFile } from 'fs/promises'; import type { Readable } from 'stream'; @@ -76,22 +79,6 @@ export class WriteBinaryFile implements INodeType { item = items[itemIndex]; - if (item.binary === undefined) { - throw new NodeOperationError( - this.getNode(), - 'No binary data set. So file can not be written!', - { itemIndex }, - ); - } - const itemBinaryData = item.binary[dataPropertyName]; - if (itemBinaryData === undefined) { - throw new NodeOperationError( - this.getNode(), - `The binary property "${dataPropertyName}" does not exist. So no file can be written!`, - { itemIndex }, - ); - } - const newItem: INodeExecutionData = { json: {}, pairedItem: { @@ -100,11 +87,13 @@ export class WriteBinaryFile implements INodeType { }; Object.assign(newItem.json, item.json); + const binaryData = this.helpers.assertBinaryData(itemIndex, dataPropertyName); + let fileContent: Buffer | Readable; - if (itemBinaryData.id) { - fileContent = this.helpers.getBinaryStream(itemBinaryData.id); + if (binaryData.id) { + fileContent = this.helpers.getBinaryStream(binaryData.id); } else { - fileContent = Buffer.from(itemBinaryData.data, BINARY_ENCODING); + fileContent = Buffer.from(binaryData.data, BINARY_ENCODING); } // Write the file to disk diff --git a/packages/nodes-base/nodes/Zulip/Zulip.node.ts b/packages/nodes-base/nodes/Zulip/Zulip.node.ts index e26be1c828..d163487ad5 100644 --- a/packages/nodes-base/nodes/Zulip/Zulip.node.ts +++ b/packages/nodes-base/nodes/Zulip/Zulip.node.ts @@ -1,6 +1,6 @@ -import type { IExecuteFunctions } from 'n8n-core'; import type { IDataObject, + IExecuteFunctions, ILoadOptionsFunctions, INodeExecutionData, INodePropertyOptions, @@ -192,29 +192,16 @@ export class Zulip implements INodeType { //https://zulipchat.com/api/upload-file if (operation === 'updateFile') { const credentials = await this.getCredentials('zulipApi'); - const binaryProperty = this.getNodeParameter('dataBinaryProperty', i); - if (items[i].binary === undefined) { - throw new NodeOperationError(this.getNode(), 'No binary data exists on item!'); - } - //@ts-ignore - if (items[i].binary[binaryProperty] === undefined) { - throw new NodeOperationError( - this.getNode(), - `Item has no binary property called "${binaryProperty}"`, - { itemIndex: i }, - ); - } + const dataBinaryProperty = this.getNodeParameter('dataBinaryProperty', i); - const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty); + const binaryData = this.helpers.assertBinaryData(i, dataBinaryProperty); + const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, dataBinaryProperty); const formData = { file: { - //@ts-ignore value: binaryDataBuffer, options: { - //@ts-ignore - filename: items[i].binary[binaryProperty].fileName, - //@ts-ignore - contentType: items[i].binary[binaryProperty].mimeType, + filename: binaryData.fileName, + contentType: binaryData.mimeType, }, }, }; diff --git a/packages/workflow/src/Interfaces.ts b/packages/workflow/src/Interfaces.ts index 1f9372c2c3..0e317075d3 100644 --- a/packages/workflow/src/Interfaces.ts +++ b/packages/workflow/src/Interfaces.ts @@ -757,6 +757,7 @@ export type IExecuteFunctions = ExecuteFunctions.GetNodeParameterFn & inputData: INodeExecutionData[], options: { itemData: IPairedItemData | IPairedItemData[] }, ): NodeExecutionWithMetadata[]; + assertBinaryData(itemIndex: number, propertyName: string): IBinaryData; getBinaryDataBuffer(itemIndex: number, propertyName: string): Promise; }; }; @@ -772,6 +773,7 @@ export interface IExecuteSingleFunctions extends BaseExecutionFunctions { helpers: RequestHelperFunctions & BinaryHelperFunctions & { + assertBinaryData(propertyName: string, inputIndex?: number): IBinaryData; getBinaryDataBuffer(propertyName: string, inputIndex?: number): Promise; }; } diff --git a/packages/workflow/src/NodeHelpers.ts b/packages/workflow/src/NodeHelpers.ts index bfef53b0aa..ee24b84df9 100644 --- a/packages/workflow/src/NodeHelpers.ts +++ b/packages/workflow/src/NodeHelpers.ts @@ -457,7 +457,7 @@ function getParameterDependencies(nodePropertiesArray: INodeProperties[]): IPara * to have the parameters available they depend on * */ -export function getParamterResolveOrder( +export function getParameterResolveOrder( nodePropertiesArray: INodeProperties[], parameterDependencies: IParameterDependencies, ): number[] { @@ -583,7 +583,7 @@ export function getNodeParameters( nodeValuesRoot = nodeValuesRoot || nodeValuesDisplayCheck; // Go through the parameters in order of their dependencies - const parameterItterationOrderIndex = getParamterResolveOrder( + const parameterItterationOrderIndex = getParameterResolveOrder( nodePropertiesArray, parameterDependencies, );