From e69c33382af746e9c6acafb51b64c7f505d0098f Mon Sep 17 00:00:00 2001 From: Bram Kn Date: Fri, 21 Oct 2022 18:29:20 +0200 Subject: [PATCH] feat(HTTP Request Node): add option for raw json header & query (#4408) * http node headers and query JSON parameter options added * Query and Header added to option processing * remove old set headers. * :zap: Small improvements Co-authored-by: ricardo --- package-lock.json | 62 ++++----- .../HttpRequest/V3/HttpRequestV3.node.ts | 122 +++++++++++++++++- 2 files changed, 148 insertions(+), 36 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35d4ed9d1883e..ba80fb99e9b86 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "n8n", - "version": "0.198.2", + "version": "0.199.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "n8n", - "version": "0.198.2", + "version": "0.199.0", "hasInstallScript": true, "workspaces": [ "packages/*", @@ -43375,7 +43375,7 @@ }, "packages/cli": { "name": "n8n", - "version": "0.198.2", + "version": "0.199.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@oclif/command": "^1.5.18", @@ -43421,10 +43421,10 @@ "lodash.split": "^4.4.2", "lodash.unset": "^4.5.2", "mysql2": "~2.3.0", - "n8n-core": "~0.138.0", - "n8n-editor-ui": "~0.164.2", - "n8n-nodes-base": "~0.196.0", - "n8n-workflow": "~0.120.0", + "n8n-core": "~0.139.0", + "n8n-editor-ui": "~0.165.0", + "n8n-nodes-base": "~0.197.0", + "n8n-workflow": "~0.121.0", "nodemailer": "^6.7.1", "oauth-1.0a": "^2.2.6", "open": "^7.0.0", @@ -44571,7 +44571,7 @@ }, "packages/core": { "name": "n8n-core", - "version": "0.138.0", + "version": "0.139.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "axios": "^0.21.1", @@ -44583,7 +44583,7 @@ "form-data": "^4.0.0", "lodash.get": "^4.4.2", "mime-types": "^2.1.27", - "n8n-workflow": "~0.120.0", + "n8n-workflow": "~0.121.0", "oauth-1.0a": "^2.2.6", "p-cancelable": "^2.0.0", "qs": "^6.10.1", @@ -45639,7 +45639,7 @@ }, "packages/design-system": { "name": "n8n-design-system", - "version": "0.38.0", + "version": "0.39.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "element-ui": "~2.15.7", @@ -45822,7 +45822,7 @@ }, "packages/editor-ui": { "name": "n8n-editor-ui", - "version": "0.164.2", + "version": "0.165.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@codemirror/autocomplete": "^6.1.0", @@ -45854,8 +45854,8 @@ "lodash.set": "^4.3.2", "luxon": "~2.3.0", "monaco-editor": "^0.30.1", - "n8n-design-system": "~0.38.0", - "n8n-workflow": "~0.120.0", + "n8n-design-system": "~0.39.0", + "n8n-workflow": "~0.121.0", "normalize-wheel": "^1.0.1", "prismjs": "^1.17.1", "quill": "2.0.0-dev.4", @@ -46331,7 +46331,7 @@ }, "packages/node-dev": { "name": "n8n-node-dev", - "version": "0.77.0", + "version": "0.78.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@oclif/command": "^1.5.18", @@ -46339,8 +46339,8 @@ "change-case": "^4.1.1", "fast-glob": "^3.2.5", "inquirer": "^7.0.1", - "n8n-core": "~0.138.0", - "n8n-workflow": "~0.120.0", + "n8n-core": "~0.139.0", + "n8n-workflow": "~0.121.0", "oauth-1.0a": "^2.2.6", "replace-in-file": "^6.0.0", "request": "^2.88.2", @@ -46362,7 +46362,7 @@ }, "packages/nodes-base": { "name": "n8n-nodes-base", - "version": "0.196.0", + "version": "0.197.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@kafkajs/confluent-schema-registry": "1.0.6", @@ -46401,7 +46401,7 @@ "mqtt": "4.2.6", "mssql": "^8.1.2", "mysql2": "~2.3.0", - "n8n-core": "~0.138.0", + "n8n-core": "~0.139.0", "node-html-markdown": "^1.1.3", "node-ssh": "^12.0.0", "nodemailer": "^6.7.1", @@ -46456,7 +46456,7 @@ "eslint-plugin-n8n-nodes-base": "^1.10.0", "gulp": "^4.0.0", "jest": "^27.4.7", - "n8n-workflow": "~0.120.0", + "n8n-workflow": "~0.121.0", "ts-jest": "^27.1.3", "tslint": "^6.1.2", "typescript": "~4.8.0" @@ -47493,7 +47493,7 @@ }, "packages/workflow": { "name": "n8n-workflow", - "version": "0.120.0", + "version": "0.121.0", "license": "SEE LICENSE IN LICENSE.md", "dependencies": { "@n8n_io/riot-tmpl": "^1.0.1", @@ -72168,10 +72168,10 @@ "lodash.split": "^4.4.2", "lodash.unset": "^4.5.2", "mysql2": "~2.3.0", - "n8n-core": "~0.138.0", - "n8n-editor-ui": "~0.164.2", - "n8n-nodes-base": "~0.196.0", - "n8n-workflow": "~0.120.0", + "n8n-core": "~0.139.0", + "n8n-editor-ui": "~0.165.0", + "n8n-nodes-base": "~0.197.0", + "n8n-workflow": "~0.121.0", "nodemailer": "^6.7.1", "nodemon": "^2.0.2", "oauth-1.0a": "^2.2.6", @@ -73061,7 +73061,7 @@ "jest": "^27.4.7", "lodash.get": "^4.4.2", "mime-types": "^2.1.27", - "n8n-workflow": "~0.120.0", + "n8n-workflow": "~0.121.0", "oauth-1.0a": "^2.2.6", "p-cancelable": "^2.0.0", "qs": "^6.10.1", @@ -74054,8 +74054,8 @@ "lodash.set": "^4.3.2", "luxon": "~2.3.0", "monaco-editor": "^0.30.1", - "n8n-design-system": "~0.38.0", - "n8n-workflow": "~0.120.0", + "n8n-design-system": "~0.39.0", + "n8n-workflow": "~0.121.0", "normalize-wheel": "^1.0.1", "prismjs": "^1.17.1", "quill": "2.0.0-dev.4", @@ -74411,8 +74411,8 @@ "change-case": "^4.1.1", "fast-glob": "^3.2.5", "inquirer": "^7.0.1", - "n8n-core": "~0.138.0", - "n8n-workflow": "~0.120.0", + "n8n-core": "~0.139.0", + "n8n-workflow": "~0.121.0", "oauth-1.0a": "^2.2.6", "replace-in-file": "^6.0.0", "request": "^2.88.2", @@ -74491,8 +74491,8 @@ "mqtt": "4.2.6", "mssql": "^8.1.2", "mysql2": "~2.3.0", - "n8n-core": "~0.138.0", - "n8n-workflow": "~0.120.0", + "n8n-core": "~0.139.0", + "n8n-workflow": "~0.121.0", "node-html-markdown": "^1.1.3", "node-ssh": "^12.0.0", "nodemailer": "^6.7.1", diff --git a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts index a305250c94969..8067495f96aeb 100644 --- a/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts +++ b/packages/nodes-base/nodes/HttpRequest/V3/HttpRequestV3.node.ts @@ -144,6 +144,27 @@ export class HttpRequestV3 implements INodeType { noDataExpression: true, description: 'Whether the request has query params or not', }, + { + displayName: 'Specify Query Parameters', + name: 'specifyQuery', + type: 'options', + displayOptions: { + show: { + sendQuery: [true], + }, + }, + options: [ + { + name: 'Using Fields Below', + value: 'keypair', + }, + { + name: 'Using JSON', + value: 'json', + }, + ], + default: 'keypair', + }, { displayName: 'Query Parameters', name: 'queryParameters', @@ -151,6 +172,7 @@ export class HttpRequestV3 implements INodeType { displayOptions: { show: { sendQuery: [true], + specifyQuery: ['keypair'], }, }, typeOptions: { @@ -186,6 +208,18 @@ export class HttpRequestV3 implements INodeType { }, ], }, + { + displayName: 'JSON', + name: 'jsonQuery', + type: 'json', + displayOptions: { + show: { + sendQuery: [true], + specifyQuery: ['json'], + }, + }, + default: '', + }, { displayName: 'Send Headers', name: 'sendHeaders', @@ -194,6 +228,27 @@ export class HttpRequestV3 implements INodeType { noDataExpression: true, description: 'Whether the request has headers or not', }, + { + displayName: 'Specify Headers', + name: 'specifyHeaders', + type: 'options', + displayOptions: { + show: { + sendHeaders: [true], + }, + }, + options: [ + { + name: 'Using Fields Below', + value: 'keypair', + }, + { + name: 'Using JSON', + value: 'json', + }, + ], + default: 'keypair', + }, { displayName: 'Header Parameters', name: 'headerParameters', @@ -201,6 +256,7 @@ export class HttpRequestV3 implements INodeType { displayOptions: { show: { sendHeaders: [true], + specifyHeaders: ['keypair'], }, }, typeOptions: { @@ -236,6 +292,18 @@ export class HttpRequestV3 implements INodeType { }, ], }, + { + displayName: 'JSON', + name: 'jsonHeaders', + type: 'json', + displayOptions: { + show: { + sendHeaders: [true], + specifyHeaders: ['json'], + }, + }, + default: '', + }, { displayName: 'Send Body', name: 'sendBody', @@ -865,6 +933,9 @@ export class HttpRequestV3 implements INodeType { itemIndex, [], ) as [{ name: string; value: string }]; + const specifyQuery = this.getNodeParameter('specifyQuery', itemIndex, 'keypair') as string; + const jsonQueryParameter = this.getNodeParameter('jsonQuery', itemIndex, '') as string; + const sendBody = this.getNodeParameter('sendBody', itemIndex, false) as boolean; const bodyContentType = this.getNodeParameter('contentType', itemIndex, '') as string; const specifyBody = this.getNodeParameter('specifyBody', itemIndex, '') as string; @@ -880,6 +951,8 @@ export class HttpRequestV3 implements INodeType { itemIndex, [], ) as [{ name: string; value: string }]; + const specifyHeaders = this.getNodeParameter('specifyHeaders', itemIndex, 'keypair') as string; + const jsonHeadersParameter = this.getNodeParameter('jsonHeaders', itemIndex, '') as string; const { redirect, @@ -1053,15 +1126,54 @@ export class HttpRequestV3 implements INodeType { } } + // Get parameters defined in the UI if (sendQuery && queryParameters) { - requestOptions.qs = await queryParameters.reduce(parmetersToKeyValue, Promise.resolve({})); + if (specifyQuery === 'keypair') { + requestOptions.qs = await queryParameters.reduce( + parmetersToKeyValue, + Promise.resolve({}), + ); + } else if (specifyQuery === 'json') { + // query is specified using JSON + try { + JSON.parse(jsonQueryParameter); + } catch (_) { + throw new NodeOperationError( + this.getNode(), + `JSON parameter need to be an valid JSON`, + { + runIndex: itemIndex, + }, + ); + } + + requestOptions.qs = JSON.parse(jsonQueryParameter); + } } + // Get parameters defined in the UI if (sendHeaders && headerParameters) { - requestOptions.headers = await headerParameters.reduce( - parmetersToKeyValue, - Promise.resolve({}), - ); + if (specifyHeaders === 'keypair') { + requestOptions.headers = await headerParameters.reduce( + parmetersToKeyValue, + Promise.resolve({}), + ); + } else if (specifyHeaders === 'json') { + // body is specified using JSON + try { + JSON.parse(jsonHeadersParameter); + } catch (_) { + throw new NodeOperationError( + this.getNode(), + `JSON parameter need to be an valid JSON`, + { + runIndex: itemIndex, + }, + ); + } + + requestOptions.headers = JSON.parse(jsonHeadersParameter); + } } if (autoDetectResponseFormat || responseFormat === 'file') {