Make possible to send binary-data with HttpRequest-Node

This commit is contained in:
Jan Oberhauser 2020-01-10 12:57:01 -06:00
parent 29633cfd1f
commit 83c49ddd21
2 changed files with 136 additions and 52 deletions

View file

@ -1,4 +1,7 @@
import { IExecuteFunctions } from 'n8n-core'; import {
BINARY_ENCODING,
IExecuteFunctions,
} from 'n8n-core';
import { import {
IDataObject, IDataObject,
INodeExecutionData, INodeExecutionData,
@ -306,67 +309,65 @@ export class HttpRequest implements INodeType {
}, },
// Header Parameters // Body Parameter
{ {
displayName: 'Headers', displayName: 'Send Binary Data',
name: 'headerParametersJson', name: 'sendBinaryData',
type: 'json', type: 'boolean',
displayOptions: { displayOptions: {
show: {
// TODO: Make it possible to use dot-notation
// 'options.bodyContentType': [
// 'raw',
// ],
jsonParameters: [
true,
],
requestMethod: [
'PATCH',
'POST',
'PUT',
],
},
},
default: false,
description: 'If binary data should be send as body.',
},
{
displayName: 'Binary Property',
name: 'binaryPropertyName',
type: 'string',
required: true,
default: 'data',
displayOptions: {
hide: {
sendBinaryData: [
false,
],
},
show: { show: {
jsonParameters: [ jsonParameters: [
true, true,
], ],
}, requestMethod: [
}, 'PATCH',
default: '', 'POST',
description: 'Header parameters as JSON (flat object).', 'PUT',
},
{
displayName: 'Headers',
name: 'headerParametersUi',
placeholder: 'Add Header',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
jsonParameters: [
false,
], ],
}, },
}, },
description: 'The headers to send.', description: 'Name of the binary property which contains<br />the data for the file to be uploaded.',
default: {},
options: [
{
name: 'parameter',
displayName: 'Header',
values: [
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'Name of the header.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'Value to set for the header.',
},
]
},
],
}, },
// Body Parameter
{ {
displayName: 'Body Parameters', displayName: 'Body Parameters',
name: 'bodyParametersJson', name: 'bodyParametersJson',
type: 'json', type: 'json',
displayOptions: { displayOptions: {
hide: {
sendBinaryData: [
true,
],
},
show: { show: {
jsonParameters: [ jsonParameters: [
true, true,
@ -427,6 +428,62 @@ export class HttpRequest implements INodeType {
], ],
}, },
// Header Parameters
{
displayName: 'Headers',
name: 'headerParametersJson',
type: 'json',
displayOptions: {
show: {
jsonParameters: [
true,
],
},
},
default: '',
description: 'Header parameters as JSON or RAW.',
},
{
displayName: 'Headers',
name: 'headerParametersUi',
placeholder: 'Add Header',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
jsonParameters: [
false,
],
},
},
description: 'The headers to send.',
default: {},
options: [
{
name: 'parameter',
displayName: 'Header',
values: [
{
displayName: 'Name',
name: 'name',
type: 'string',
default: '',
description: 'Name of the header.',
},
{
displayName: 'Value',
name: 'value',
type: 'string',
default: '',
description: 'Value to set for the header.',
},
]
},
],
},
// Query Parameter // Query Parameter
{ {
displayName: 'Query Parameters', displayName: 'Query Parameters',
@ -573,6 +630,33 @@ export class HttpRequest implements INodeType {
// Paramter is empty so skip it // Paramter is empty so skip it
continue; continue;
} }
if (optionData.name === 'body' && parametersAreJson === true) {
const sendBinaryData = this.getNodeParameter('sendBinaryData', itemIndex, false) as boolean;
if (sendBinaryData === true) {
if (options.bodyContentType !== 'raw') {
// As n8n-workflow.NodeHelpers.getParamterResolveOrder can not be changed
// easily to handle parameters in dot.notation simply error for now.
throw new Error('Sending binary data is only supported when option "Body Content Type" is set to "RAW/CUSTOM"!');
}
const item = items[itemIndex];
if (item.binary === undefined) {
throw new Error('No binary data exists on item!');
}
const binaryPropertyName = this.getNodeParameter('binaryPropertyName', itemIndex) as string;
if (item.binary[binaryPropertyName] === undefined) {
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
}
requestOptions.body = Buffer.from(item.binary[binaryPropertyName].data, BINARY_ENCODING);
continue;
}
}
// @ts-ignore // @ts-ignore
requestOptions[optionData.name] = tempValue; requestOptions[optionData.name] = tempValue;

View file

@ -282,10 +282,10 @@ export function displayParameter(nodeValues: INodeParameters, parameter: INodePr
for (const propertyName of Object.keys(parameter.displayOptions.show)) { for (const propertyName of Object.keys(parameter.displayOptions.show)) {
if (propertyName.charAt(0) === '/') { if (propertyName.charAt(0) === '/') {
// Get the value from the root of the node // Get the value from the root of the node
value = nodeValuesRoot[propertyName.slice(1)]; value = get(nodeValuesRoot, propertyName.slice(1));
} else { } else {
// Get the value from current level // Get the value from current level
value = nodeValues[propertyName]; value = get(nodeValues, propertyName);
} }
if (value === undefined || !parameter.displayOptions.show[propertyName].includes(value as string)) { if (value === undefined || !parameter.displayOptions.show[propertyName].includes(value as string)) {
@ -299,10 +299,10 @@ export function displayParameter(nodeValues: INodeParameters, parameter: INodePr
for (const propertyName of Object.keys(parameter.displayOptions.hide)) { for (const propertyName of Object.keys(parameter.displayOptions.hide)) {
if (propertyName.charAt(0) === '/') { if (propertyName.charAt(0) === '/') {
// Get the value from the root of the node // Get the value from the root of the node
value = nodeValuesRoot[propertyName.slice(1)]; value = get(nodeValuesRoot, propertyName.slice(1));
} else { } else {
// Get the value from current level // Get the value from current level
value = nodeValues[propertyName]; value = get(nodeValues, propertyName);
} }
if (value !== undefined && parameter.displayOptions.hide[propertyName].includes(value as string)) { if (value !== undefined && parameter.displayOptions.hide[propertyName].includes(value as string)) {
return false; return false;
@ -475,7 +475,7 @@ export function getParamterResolveOrder(nodePropertiesArray: INodeProperties[],
} }
if (itterations > lastIndexReduction + nodePropertiesArray.length) { if (itterations > lastIndexReduction + nodePropertiesArray.length) {
throw new Error('Could not resolve parameter depenencies!'); throw new Error('Could not resolve parameter depenencies. Max itterations got reached!');
} }
lastIndexLength = indexToResolve.length; lastIndexLength = indexToResolve.length;
} }