Initial changes for binary data management (#2105)

* introduce binary data management

* cr

* add binary data changes to awsS3 node

* add binary data changes to Box node

* add binary data changes to CiscoWebex node

* add binary data changes to HumaniticAi node

* add binary data changes to Jira node

* add binary data changes to Line node

* add binary data changes to MicrosoftOneDrive node

* add binary data changes to MicrosoftOutlook node

* add binary data changes to Mindee node

* add binary data changes to NocoDB node

* add binary data changes to Pushbullet node

* add binary data changes to Pushover node

* add binary data changes to Raindrop node

* add binary data changes to S3 node

* add binary data changes to Salesforce node

* add binary data changes to Ssh node

* add binary data changes to TheHive node

* add binary data changes to Twist node

* add binary data changes to Twitter node

* remove changes not needed right now

* 🐛 Fix issue with multiple runs

* 🐛 Revert fix and add support for multiple inputs

Co-authored-by: Jan Oberhauser <jan.oberhauser@gmail.com>
This commit is contained in:
Ahsan Virani 2021-08-20 18:08:40 +02:00 committed by GitHub
parent 7da86641d5
commit 178235e148
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 103 additions and 66 deletions

View file

@ -34,9 +34,10 @@ export interface IProcessMessage {
export interface IExecuteFunctions extends IExecuteFunctionsBase { export interface IExecuteFunctions extends IExecuteFunctionsBase {
helpers: { helpers: {
prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>; prepareBinaryData(binaryData: Buffer, filePath?: string, mimeType?: string): Promise<IBinaryData>;
request: requestPromise.RequestPromiseAPI, getBinaryDataBuffer(itemIndex: number, propertyName: string): Promise<Buffer>;
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any>, // tslint:disable-line:no-any request: requestPromise.RequestPromiseAPI;
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any>, // tslint:disable-line:no-any requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any>; // tslint:disable-line:no-any
requestOAuth1(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUrl | requestPromise.RequestPromiseOptions): Promise<any>; // tslint:disable-line:no-any
returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[]; returnJsonArray(jsonData: IDataObject | IDataObject[]): INodeExecutionData[];
}; };
} }

View file

@ -59,6 +59,21 @@ const requestPromiseWithDefaults = requestPromise.defaults({
timeout: 300000, // 5 minutes timeout: 300000, // 5 minutes
}); });
/**
* Returns binary data buffer for given item index and property name.
*
* @export
* @param {ITaskDataConnections} inputData
* @param {number} itemIndex
* @param {string} propertyName
* @param {number} inputIndex
* @returns {Promise<Buffer>}
*/
export async function getBinaryDataBuffer(inputData: ITaskDataConnections, itemIndex: number, propertyName: string, inputIndex: number): Promise<Buffer> {
const binaryData = inputData['main']![inputIndex]![itemIndex]!.binary![propertyName]!;
return Buffer.from(binaryData.data, BINARY_ENCODING);
}
/** /**
* Takes a buffer and converts it into the format n8n uses. It encodes the binary data as * Takes a buffer and converts it into the format n8n uses. It encodes the binary data as
* base64 and adds metadata. * base64 and adds metadata.
@ -763,6 +778,9 @@ export function getExecuteFunctions(workflow: Workflow, runExecutionData: IRunEx
}, },
helpers: { helpers: {
prepareBinaryData, prepareBinaryData,
getBinaryDataBuffer(itemIndex: number, propertyName: string, inputIndex = 0): Promise<Buffer> {
return getBinaryDataBuffer.call(this, inputData, itemIndex, propertyName, inputIndex);
},
request: requestPromiseWithDefaults, request: requestPromiseWithDefaults,
requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any requestOAuth2(this: IAllExecuteFunctions, credentialsType: string, requestOptions: OptionsWithUri | requestPromise.RequestPromiseOptions, oAuth2Options?: IOAuth2Options): Promise<any> { // tslint:disable-line:no-any
return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options); return requestOAuth2.call(this, credentialsType, requestOptions, node, additionalData, oAuth2Options);

View file

@ -1348,7 +1348,7 @@ describe('WorkflowExecute', () => {
const workflowExecute = new WorkflowExecute(additionalData, executionMode); const workflowExecute = new WorkflowExecute(additionalData, executionMode);
const executionData = await workflowExecute.run(workflowInstance, undefined); const executionData = await workflowExecute.run(workflowInstance);
const result = await waitPromise.promise(); const result = await waitPromise.promise();

View file

@ -13,7 +13,6 @@ import {
} from 'xml2js'; } from 'xml2js';
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -607,8 +606,9 @@ export class AwsS3 implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer; body = binaryDataBuffer;
headers['Content-Type'] = binaryData.mimeType; headers['Content-Type'] = binaryData.mimeType;

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -277,6 +276,7 @@ export class Box implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const body: IDataObject = {}; const body: IDataObject = {};
@ -285,7 +285,7 @@ export class Box implements INodeType {
body['attributes'] = JSON.stringify(attributes); body['attributes'] = JSON.stringify(attributes);
body['file'] = { body['file'] = {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -174,10 +173,11 @@ export class CiscoWebex implements INodeType {
const binaryPropertyName = file.binaryPropertyName as string; const binaryPropertyName = file.binaryPropertyName as string;
const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; const binaryData = items[i].binary![binaryPropertyName] as IBinaryData;
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const formData = { const formData = {
files: { files: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -226,9 +225,10 @@ export class Compression implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData.fileExtension === 'zip') { if (binaryData.fileExtension === 'zip') {
const files = await unzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); const files = await unzip(binaryDataBuffer);
for (const key of Object.keys(files)) { for (const key of Object.keys(files)) {
// when files are compresed using MACOSX for some reason they are duplicated under __MACOSX // when files are compresed using MACOSX for some reason they are duplicated under __MACOSX
@ -241,7 +241,7 @@ export class Compression implements INodeType {
binaryObject[`${outputPrefix}${zipIndex++}`] = data; binaryObject[`${outputPrefix}${zipIndex++}`] = data;
} }
} else if (binaryData.fileExtension === 'gz') { } else if (binaryData.fileExtension === 'gz') {
const file = await gunzip(Buffer.from(binaryData.data as string, BINARY_ENCODING)); const file = await gunzip(binaryDataBuffer);
const fileName = binaryData.fileName?.split('.')[0]; const fileName = binaryData.fileName?.split('.')[0];
@ -280,10 +280,11 @@ export class Compression implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (outputFormat === 'zip') { if (outputFormat === 'zip') {
zipData[binaryData.fileName as string] = [ zipData[binaryData.fileName as string] = [
Buffer.from(binaryData.data, BINARY_ENCODING), { binaryDataBuffer, {
level: ALREADY_COMPRESSED.includes(binaryData.fileExtension as string) ? 0 : 6, level: ALREADY_COMPRESSED.includes(binaryData.fileExtension as string) ? 0 : 6,
}, },
]; ];
@ -291,7 +292,7 @@ export class Compression implements INodeType {
} else if (outputFormat === 'gzip') { } else if (outputFormat === 'gzip') {
const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string; const outputPrefix = this.getNodeParameter('outputPrefix', 0) as string;
const data = await gzip(Buffer.from(binaryData.data, BINARY_ENCODING)) as Uint8Array; const data = await gzip(binaryDataBuffer) as Uint8Array;
const fileName = binaryData.fileName?.split('.')[0]; const fileName = binaryData.fileName?.split('.')[0];
@ -326,7 +327,7 @@ export class Compression implements INodeType {
} catch (error) { } catch (error) {
if (this.continueOnFail()) { if (this.continueOnFail()) {
returnData.push({json:{ error: error.message }}); returnData.push({ json: { error: error.message } });
continue; continue;
} }
throw error; throw error;

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -88,6 +87,7 @@ export class HumanticAi implements INodeType {
const item = items[i].binary as IBinaryKeyData; const item = items[i].binary as IBinaryKeyData;
const binaryData = item[binaryPropertyName] as IBinaryData; const binaryData = item[binaryPropertyName] as IBinaryData;
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData === undefined) { if (binaryData === undefined) {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
@ -102,7 +102,7 @@ export class HumanticAi implements INodeType {
{ {
formData: { formData: {
resume: { resume: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -148,6 +148,7 @@ export class HumanticAi implements INodeType {
const item = items[i].binary as IBinaryKeyData; const item = items[i].binary as IBinaryKeyData;
const binaryData = item[binaryPropertyName] as IBinaryData; const binaryData = item[binaryPropertyName] as IBinaryData;
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData === undefined) { if (binaryData === undefined) {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
@ -162,7 +163,7 @@ export class HumanticAi implements INodeType {
{ {
formData: { formData: {
resume: { resume: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -754,6 +753,7 @@ export class Jira implements INodeType {
const item = items[i].binary as IBinaryKeyData; const item = items[i].binary as IBinaryKeyData;
const binaryData = item[binaryPropertyName] as IBinaryData; const binaryData = item[binaryPropertyName] as IBinaryData;
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData === undefined) { if (binaryData === undefined) {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
@ -769,7 +769,7 @@ export class Jira implements INodeType {
{ {
formData: { formData: {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -118,9 +117,10 @@ export class Line implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[image.binaryProperty as string]; const binaryData = (items[i].binary as IBinaryKeyData)[image.binaryProperty as string];
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(i, image.binaryProperty as string);
body.imageFile = { body.imageFile = {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: binaryDataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -192,8 +191,8 @@ export class MicrosoftOneDrive implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const body = Buffer.from(binaryData.data, BINARY_ENCODING);
responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName || binaryData.fileName}:/content`, body, {}, undefined, { 'Content-Type': binaryData.mimeType, 'Content-length': body.length }, {} ); responseData = await microsoftApiRequest.call(this, 'PUT', `/drive/items/${parentId}:/${fileName || binaryData.fileName}:/content`, body, {}, undefined, { 'Content-Type': binaryData.mimeType, 'Content-length': body.length }, {} );
returnData.push(JSON.parse(responseData) as IDataObject); returnData.push(JSON.parse(responseData) as IDataObject);

View file

@ -648,7 +648,7 @@ export class MicrosoftOutlook implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const dataBuffer = Buffer.from(binaryData.data, 'base64'); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const fileName = additionalFields.fileName === undefined ? binaryData.fileName : additionalFields.fileName; const fileName = additionalFields.fileName === undefined ? binaryData.fileName : additionalFields.fileName;

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -140,6 +139,7 @@ export class Mindee implements INodeType {
const item = items[i].binary as IBinaryKeyData; const item = items[i].binary as IBinaryKeyData;
const binaryData = item[binaryPropertyName] as IBinaryData; const binaryData = item[binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData === undefined) { if (binaryData === undefined) {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
@ -154,7 +154,7 @@ export class Mindee implements INodeType {
{ {
formData: { formData: {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -182,6 +182,7 @@ export class Mindee implements INodeType {
const item = items[i].binary as IBinaryKeyData; const item = items[i].binary as IBinaryKeyData;
const binaryData = item[binaryPropertyName] as IBinaryData; const binaryData = item[binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
if (binaryData === undefined) { if (binaryData === undefined) {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
@ -196,7 +197,7 @@ export class Mindee implements INodeType {
{ {
formData: { formData: {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -160,10 +159,11 @@ export class NocoDB implements INodeType {
throw new NodeOperationError(this.getNode(), `Binary property ${binaryPropertyName} does not exist on item!`); throw new NodeOperationError(this.getNode(), `Binary property ${binaryPropertyName} does not exist on item!`);
} }
const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; const binaryData = items[i].binary![binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const formData = { const formData = {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,
@ -338,10 +338,11 @@ export class NocoDB implements INodeType {
throw new NodeOperationError(this.getNode(), `Binary property ${binaryPropertyName} does not exist on item!`); throw new NodeOperationError(this.getNode(), `Binary property ${binaryPropertyName} does not exist on item!`);
} }
const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; const binaryData = items[i].binary![binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const formData = { const formData = {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -495,6 +494,7 @@ export class Pushbullet implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
//create upload url //create upload url
const { const {
@ -523,7 +523,7 @@ export class Pushbullet implements INodeType {
{ {
formData: { formData: {
file: { file: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -366,8 +365,10 @@ export class Pushover implements INodeType {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryPropertyName}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
body.attachment = { body.attachment = {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -345,10 +344,11 @@ export class Raindrop implements INodeType {
const binaryPropertyName = updateFields.cover as string; const binaryPropertyName = updateFields.cover as string;
const binaryData = items[i].binary![binaryPropertyName] as IBinaryData; const binaryData = items[i].binary![binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const formData = { const formData = {
cover: { cover: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,

View file

@ -1,4 +1,3 @@
import { import {
paramCase, paramCase,
snakeCase, snakeCase,
@ -608,8 +607,7 @@ export class S3 implements INodeType {
} }
const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName]; const binaryData = (items[i].binary as IBinaryKeyData)[binaryPropertyName];
body = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
body = Buffer.from(binaryData.data, BINARY_ENCODING) as Buffer;
headers['Content-Type'] = binaryData.mimeType; headers['Content-Type'] = binaryData.mimeType;

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -1686,6 +1685,8 @@ export class Salesforce implements INodeType {
} }
if (items[i].binary && items[i].binary![binaryPropertyName]) { if (items[i].binary && items[i].binary![binaryPropertyName]) {
const binaryData = items[i].binary![binaryPropertyName]; const binaryData = items[i].binary![binaryPropertyName];
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
body.entity_content['PathOnClient'] = `${title}.${binaryData.fileExtension}`; body.entity_content['PathOnClient'] = `${title}.${binaryData.fileExtension}`;
data = { data = {
entity_content: { entity_content: {
@ -1695,7 +1696,7 @@ export class Salesforce implements INodeType {
}, },
}, },
VersionData: { VersionData: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
contentType: binaryData.mimeType, contentType: binaryData.mimeType,

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -389,9 +388,11 @@ export class Ssh implements INodeType {
throw new Error(`No binary data property "${propertyNameUpload}" does not exists on item!`); throw new Error(`No binary data property "${propertyNameUpload}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, propertyNameUpload);
const { path } = await file({ prefix: 'n8n-ssh-' }); const { path } = await file({ prefix: 'n8n-ssh-' });
temporaryFiles.push(path); temporaryFiles.push(path);
await writeFile(path, Buffer.from(binaryData.data, BINARY_ENCODING)); await writeFile(path, dataBuffer);
await ssh.putFile(path, `${parameterPath}${(parameterPath.charAt(parameterPath.length - 1) === '/') ? '' : '/'}${fileName || binaryData.fileName}`); await ssh.putFile(path, `${parameterPath}${(parameterPath.charAt(parameterPath.length - 1) === '/') ? '' : '/'}${fileName || binaryData.fileName}`);

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions IExecuteFunctions
} from 'n8n-core'; } from 'n8n-core';
@ -929,11 +928,12 @@ export class TheHive implements INodeType {
} }
const binaryData = item.binary[binaryPropertyName] as IBinaryData; const binaryData = item.binary[binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
options = { options = {
formData: { formData: {
attachment: { attachment: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
contentType: binaryData.mimeType, contentType: binaryData.mimeType,
filename: binaryData.fileName, filename: binaryData.fileName,
@ -1885,11 +1885,12 @@ export class TheHive implements INodeType {
} }
const binaryData = item.binary[binaryPropertyName] as IBinaryData; const binaryData = item.binary[binaryPropertyName] as IBinaryData;
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
options = { options = {
formData: { formData: {
attachment: { attachment: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
contentType: binaryData.mimeType, contentType: binaryData.mimeType,
filename: binaryData.fileName, filename: binaryData.fileName,

View file

@ -1,5 +1,4 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
} from 'n8n-core'; } from 'n8n-core';
@ -278,6 +277,8 @@ export class Twist implements INodeType {
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -287,7 +288,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -380,6 +381,8 @@ export class Twist implements INodeType {
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -389,7 +392,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -452,6 +455,8 @@ export class Twist implements INodeType {
throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`); throw new NodeOperationError(this.getNode(), `No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -461,7 +466,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -547,6 +552,8 @@ export class Twist implements INodeType {
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -556,7 +563,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -619,6 +626,8 @@ export class Twist implements INodeType {
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -628,7 +637,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },
@ -720,6 +729,8 @@ export class Twist implements INodeType {
throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`); throw new Error(`No binary data property "${binaryProperty}" does not exists on item!`);
} }
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryProperty);
attachments.push(await twistApiRequest.call( attachments.push(await twistApiRequest.call(
this, this,
'POST', 'POST',
@ -729,7 +740,7 @@ export class Twist implements INodeType {
{ {
formData: { formData: {
file_name: { file_name: {
value: Buffer.from(binaryData.data, BINARY_ENCODING), value: dataBuffer,
options: { options: {
filename: binaryData.fileName, filename: binaryData.fileName,
}, },

View file

@ -3,7 +3,6 @@ import {
} from 'request'; } from 'request';
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
IExecuteSingleFunctions, IExecuteSingleFunctions,
IHookFunctions, IHookFunctions,
@ -96,7 +95,8 @@ export async function uploadAttachments(this: IExecuteFunctions, binaryPropertie
let attachmentBody = {}; let attachmentBody = {};
let response: IDataObject = {}; let response: IDataObject = {};
const isAnimatedWebp = (Buffer.from(binaryData[binaryPropertyName].data, 'base64').toString().indexOf('ANMF') !== -1); const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
const isAnimatedWebp = (dataBuffer.toString().indexOf('ANMF') !== -1);
const isImage = binaryData[binaryPropertyName].mimeType.includes('image'); const isImage = binaryData[binaryPropertyName].mimeType.includes('image');
@ -118,9 +118,11 @@ export async function uploadAttachments(this: IExecuteFunctions, binaryPropertie
// https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload-init // https://developer.twitter.com/en/docs/media/upload-media/api-reference/post-media-upload-init
const dataBuffer = await this.helpers.getBinaryDataBuffer(i, binaryPropertyName);
attachmentBody = { attachmentBody = {
command: 'INIT', command: 'INIT',
total_bytes: Buffer.from(binaryData[binaryPropertyName].data, BINARY_ENCODING).byteLength, total_bytes: dataBuffer.byteLength,
media_type: binaryData[binaryPropertyName].mimeType, media_type: binaryData[binaryPropertyName].mimeType,
}; };
@ -130,7 +132,7 @@ export async function uploadAttachments(this: IExecuteFunctions, binaryPropertie
// break the data on 5mb chunks (max size that can be uploaded at once) // break the data on 5mb chunks (max size that can be uploaded at once)
const binaryParts = chunks(Buffer.from(binaryData[binaryPropertyName].data, BINARY_ENCODING), 5242880); const binaryParts = chunks(dataBuffer, 5242880);
let index = 0; let index = 0;

View file

@ -1,7 +1,5 @@
import { import {
BINARY_ENCODING,
IExecuteFunctions, IExecuteFunctions,
IExecuteSingleFunctions
} from 'n8n-core'; } from 'n8n-core';
import { import {
IDataObject, IDataObject,
@ -76,14 +74,16 @@ export class WriteBinaryFile implements INodeType {
throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So no file can be written!`); throw new NodeOperationError(this.getNode(), `The binary property "${dataPropertyName}" does not exist. So no file can be written!`);
} }
// Write the file to disk
await fsWriteFile(fileName, Buffer.from(item.binary[dataPropertyName].data, BINARY_ENCODING), 'binary');
const newItem: INodeExecutionData = { const newItem: INodeExecutionData = {
json: {}, json: {},
}; };
Object.assign(newItem.json, item.json); Object.assign(newItem.json, item.json);
const binaryDataBuffer = await this.helpers.getBinaryDataBuffer(itemIndex, dataPropertyName);
// Write the file to disk
await fsWriteFile(fileName, binaryDataBuffer, 'binary');
if (item.binary !== undefined) { if (item.binary !== undefined) {
// Create a shallow copy of the binary data so that the old // Create a shallow copy of the binary data so that the old
// data references which do not get changed still stay behind // data references which do not get changed still stay behind
@ -100,7 +100,7 @@ export class WriteBinaryFile implements INodeType {
} catch (error) { } catch (error) {
if (this.continueOnFail()) { if (this.continueOnFail()) {
returnData.push({json:{ error: error.message }}); returnData.push({ json: { error: error.message } });
continue; continue;
} }
throw error; throw error;