🔀 Merge branch 'master' into oauth-support

This commit is contained in:
Jan Oberhauser
2020-04-04 17:34:10 +02:00
376 changed files with 45850 additions and 2723 deletions

View File

@@ -1,9 +1,13 @@
import { IExecuteFunctions } from 'n8n-core';
import {
BINARY_ENCODING,
IExecuteFunctions,
} from 'n8n-core';
import {
IDataObject,
INodeExecutionData,
INodeType,
INodeTypeDescription,
IBinaryData,
} from 'n8n-workflow';
import { OptionsWithUri } from 'request';
@@ -321,67 +325,67 @@ export class HttpRequest implements INodeType {
},
// Header Parameters
// Body Parameter
{
displayName: 'Headers',
name: 'headerParametersJson',
type: 'json',
displayName: 'Send Binary Data',
name: 'sendBinaryData',
type: 'boolean',
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: {
jsonParameters: [
true,
],
},
},
default: '',
description: 'Header parameters as JSON (flat object).',
},
{
displayName: 'Headers',
name: 'headerParametersUi',
placeholder: 'Add Header',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
jsonParameters: [
false,
requestMethod: [
'PATCH',
'POST',
'PUT',
],
},
},
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.',
},
]
},
],
description: `Name of the binary property which contains the data for the file to be uploaded.<br />
For Form-Data Multipart, multiple can be provided in the format:<br />
"sendKey1:binaryProperty1,sendKey2:binaryProperty2`,
},
// Body Parameter
{
displayName: 'Body Parameters',
name: 'bodyParametersJson',
type: 'json',
displayOptions: {
hide: {
sendBinaryData: [
true,
],
},
show: {
jsonParameters: [
true,
@@ -442,6 +446,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
{
displayName: 'Query Parameters',
@@ -545,9 +605,10 @@ export class HttpRequest implements INodeType {
},
};
let response: any; // tslint:disable-line:no-any
const returnItems: INodeExecutionData[] = [];
for (let itemIndex = 0; itemIndex < items.length; itemIndex++) {
const options = this.getNodeParameter('options', 0, {}) as IDataObject;
const options = this.getNodeParameter('options', itemIndex, {}) as IDataObject;
const url = this.getNodeParameter('url', itemIndex) as string;
const fullResponse = !!options.fullResponse as boolean;
@@ -589,6 +650,70 @@ export class HttpRequest implements INodeType {
// Paramter is empty so skip it
continue;
}
if (optionData.name === 'body' && parametersAreJson === true) {
const sendBinaryData = this.getNodeParameter('sendBinaryData', itemIndex, false) as boolean;
if (sendBinaryData === true) {
const contentTypesAllowed = [
'raw',
'multipart-form-data',
];
if (!contentTypesAllowed.includes(options.bodyContentType as string)) {
// 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" or "FORM-DATA/MULTIPART"!');
}
const item = items[itemIndex];
if (item.binary === undefined) {
throw new Error('No binary data exists on item!');
}
if (options.bodyContentType === 'raw') {
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!`);
}
const binaryProperty = item.binary[binaryPropertyName] as IBinaryData;
requestOptions.body = Buffer.from(binaryProperty.data, BINARY_ENCODING);
} else if (options.bodyContentType === 'multipart-form-data') {
requestOptions.body = {};
const binaryPropertyNameFull = this.getNodeParameter('binaryPropertyName', itemIndex) as string;
const binaryPropertyNames = binaryPropertyNameFull.split(',').map(key => key.trim());
for (const propertyData of binaryPropertyNames) {
let propertyName = 'file';
let binaryPropertyName = propertyData;
if (propertyData.includes(':')) {
const propertyDataParts = propertyData.split(':');
propertyName = propertyDataParts[0];
binaryPropertyName = propertyDataParts[1];
} else if (binaryPropertyNames.length > 1) {
throw new Error('If more than one property should be send it is needed to define the in the format: "sendKey1:binaryProperty1,sendKey2:binaryProperty2"');
}
if (item.binary[binaryPropertyName] === undefined) {
throw new Error(`No binary data property "${binaryPropertyName}" does not exists on item!`);
}
const binaryProperty = item.binary[binaryPropertyName] as IBinaryData;
requestOptions.body[propertyName] = {
value: Buffer.from(binaryProperty.data, BINARY_ENCODING),
options: {
filename: binaryProperty.fileName,
contentType: binaryProperty.mimeType,
},
};
}
}
continue;
}
}
// @ts-ignore
requestOptions[optionData.name] = tempValue;
@@ -674,12 +799,22 @@ export class HttpRequest implements INodeType {
}
// Now that the options are all set make the actual http request
let response;
if (oAuth2Api !== undefined) {
response = await this.helpers.requestOAuth.call(this, 'oAuth2Api', requestOptions);
} else {
response = await this.helpers.request(requestOptions);
try {
// Now that the options are all set make the actual http request
if (oAuth2Api !== undefined) {
response = await this.helpers.requestOAuth.call(this, 'oAuth2Api', requestOptions);
} else {
response = await this.helpers.request(requestOptions);
}
} catch (error) {
if (this.continueOnFail() === true) {
returnItems.push({ json: { error } });
continue;
}
throw error;
}
if (responseFormat === 'file') {