From f196d9dd5d81816880ac78b344b6b54ec37a2045 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Tue, 19 Jan 2021 21:25:48 +0200 Subject: [PATCH 01/20] Layout migration strategy, for #14 --- lib/Adaptor.js | 37 ++++++++++++++++++++----------------- lib/Utils.js | 37 +++++++++++++++++++++++++++++++++++++ package-lock.json | 40 +++++++++++++++++++++++----------------- package.json | 2 +- src/Adaptor.js | 40 +++++++++++++++++++++++++--------------- src/Utils.js | 38 ++++++++++++++++++++++++++++++++++++++ test/index.js | 5 +++-- 7 files changed, 147 insertions(+), 52 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 2b6b797..d1525f6 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -131,25 +131,28 @@ function execute(...operations) { function get(path, params, callback) { return state => { + var _params$authenticatio; + + path = (0, _languageCommon.expandReferences)(path)(state); // params = expandReferences(params)(state); + + console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = (0, _languageCommon.expandReferences)(params)(state); - const auth = (0, _Utils.setAuth)(state.configuration, authentication); - return (0, _Client.req)('GET', { + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio = params === null || params === void 0 ? void 0 : params.authentication) !== null && _params$authenticatio !== void 0 ? _params$authenticatio : params === null || params === void 0 ? void 0 : params.auth); + const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, - query, - auth, - headers, - options, - ...rest - }).then(response => { + auth + }); // const { + // query, + // headers, + // authentication, + // body, + // formData, + // options, + // ...rest + // } = expandReferences(params)(state); + // return req('GET', { url, query, auth, headers, options, ...rest }).then( + + return _languageCommon.http.get(config)(state).then(response => { const nextState = (0, _languageCommon.composeNextState)(state, response); if (callback) return callback(nextState); return nextState; diff --git a/lib/Utils.js b/lib/Utils.js index 35641b1..4311daf 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -7,6 +7,7 @@ exports.setUrl = setUrl; exports.setAuth = setAuth; exports.assembleError = assembleError; exports.tryJson = tryJson; +exports.mapToAxiosConfig = mapToAxiosConfig; function setUrl(configuration, path) { if (configuration && configuration.baseUrl) return configuration.baseUrl + path;else return path; @@ -43,3 +44,39 @@ function tryJson(data) { }; } } + +function mapToAxiosConfig(requestConfig) { + var _requestConfig$url, _requestConfig$params, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$httpAg; + + return { ...requestConfig, + url: (_requestConfig$url = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.url) !== null && _requestConfig$url !== void 0 ? _requestConfig$url : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.uri, + // method, + // baseURL, + // transformRequest, + // transformResponse, + // headers, + params: (_requestConfig$params = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.params) !== null && _requestConfig$params !== void 0 ? _requestConfig$params : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.qs, + // paramsSerializer, + data: (_requestConfig$data = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.data) !== null && _requestConfig$data !== void 0 ? _requestConfig$data : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.body) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData), + // timeouts, + // withCredentials, + // adapter, + auth: (_requestConfig$auth = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.auth) !== null && _requestConfig$auth !== void 0 ? _requestConfig$auth : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.authentication, + responseType: (_requestConfig$respon = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.responseType) !== null && _requestConfig$respon !== void 0 ? _requestConfig$respon : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.json, + responseEncoding: (_requestConfig$respon2 = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.responseEncoding) !== null && _requestConfig$respon2 !== void 0 ? _requestConfig$respon2 : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.encoding, + // xsrfCookieName, + // xsrfHeaderName, + // onUploadProgress, + // onDownloadProgress, + // maxContentLength, + // maxBodyLength, + // validateStatus, + // maxRedirects, + // socketPath, + httpAgent: (_requestConfig$httpAg = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.httpAgent) !== null && _requestConfig$httpAg !== void 0 ? _requestConfig$httpAg : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.agent // httpsAgent, + // proxy, + // cancelToken, + // decompress, + + }; +} diff --git a/package-lock.json b/package-lock.json index 4ec4e90..66e8cb2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1193,14 +1193,6 @@ "resolved": "https://registry.npmjs.org/@types/node/-/node-13.11.1.tgz", "integrity": "sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g==" }, - "JSONPath": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/JSONPath/-/JSONPath-0.10.0.tgz", - "integrity": "sha1-RJWb3ZTjZBhY5/IUfZPHMvNQWxw=", - "requires": { - "underscore": "*" - } - }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -1333,6 +1325,14 @@ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha1-8OAD2cqef1nHpQiUXXsu+aBKVC8=" }, + "axios": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz", + "integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==", + "requires": { + "follow-redirects": "^1.10.0" + } + }, "babel-plugin-dynamic-import-node": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz", @@ -2258,6 +2258,11 @@ } } }, + "follow-redirects": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.1.tgz", + "integrity": "sha512-SSG5xmZh1mkPGyKzjZP8zLjltIfpW32Y5QpdNJyjcfGxK3qo3NDDkZOZSFiGn1A6SclQxY9GzEwAHQ3dmYRWpg==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -2761,6 +2766,11 @@ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, + "jsonpath-plus": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-4.0.0.tgz", + "integrity": "sha512-e0Jtg4KAzDJKKwzbLaUtinCn0RZseWBVRTRGihSpvFlM3wTR7ExSp+PTdeTsDrLNJUe7L7JYJe8mblHX5SCT6A==" + }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -2786,11 +2796,12 @@ "optional": true }, "language-common": { - "version": "github:openfn/language-common#b8047f82680d95387cbe4596f55e24e4d0b128c6", - "from": "github:openfn/language-common#v0.3.0", + "version": "github:openfn/language-common#ebae051d343c793583a6d8988a0b30d075178b83", + "from": "github:openfn/language-common#v1.0.0", "requires": { - "JSONPath": "^0.10.0", - "lodash": "^4.17.4" + "axios": "^0.21.1", + "jsonpath-plus": "^4.0.0", + "lodash": "^4.17.19" } }, "leven": { @@ -4514,11 +4525,6 @@ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true }, - "underscore": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.1.tgz", - "integrity": "sha1-BtzjSg5op7q8KbNluOdLiSUgOWE=" - }, "unicode-canonical-property-names-ecmascript": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", diff --git a/package.json b/package.json index 8363a56..7e53969 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "cheerio-tableparser": "^1.0.1", "csv-parse": "^4.10.1", "import": "0.0.6", - "language-common": "github:openfn/language-common#v0.3.0", + "language-common": "github:openfn/language-common#v1.0.0", "request": "^2.72.0" }, "devDependencies": { diff --git a/src/Adaptor.js b/src/Adaptor.js index 4b6f3dc..6e00a93 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -1,10 +1,11 @@ /** @module Adaptor */ import { req, rawRequest } from './Client'; -import { setAuth, setUrl } from './Utils'; +import { setAuth, setUrl, mapToAxiosConfig } from './Utils'; import { execute as commonExecute, expandReferences, composeNextState, + http, } from 'language-common'; import cheerio from 'cheerio'; import cheerioTableparser from 'cheerio-tableparser'; @@ -55,27 +56,36 @@ export function execute(...operations) { */ export function get(path, params, callback) { return state => { + path = expandReferences(path)(state); + + // params = expandReferences(params)(state); + console.log('params', params); const url = setUrl(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = expandReferences(params)(state); + const auth = setAuth( + state.configuration, + params?.authentication ?? params?.auth + ); - const auth = setAuth(state.configuration, authentication); + const config = mapToAxiosConfig({ ...params, url, auth }); + // const { + // query, + // headers, + // authentication, + // body, + // formData, + // options, + // ...rest + // } = expandReferences(params)(state); - return req('GET', { url, query, auth, headers, options, ...rest }).then( - response => { + // return req('GET', { url, query, auth, headers, options, ...rest }).then( + return http + .get(config)(state) + .then(response => { const nextState = composeNextState(state, response); if (callback) return callback(nextState); return nextState; - } - ); + }); }; } diff --git a/src/Utils.js b/src/Utils.js index 906f8cb..f4ca6d9 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -34,3 +34,41 @@ export function tryJson(data) { return { body: data }; } } + +export function mapToAxiosConfig(requestConfig) { + return { + ...requestConfig, + url: requestConfig?.url ?? requestConfig?.uri, + // method, + // baseURL, + // transformRequest, + // transformResponse, + // headers, + params: requestConfig?.params ?? requestConfig?.qs, + // paramsSerializer, + data: + requestConfig?.data ?? + (requestConfig?.body || requestConfig?.form || requestConfig?.formData), + // timeouts, + // withCredentials, + // adapter, + auth: requestConfig?.auth ?? requestConfig?.authentication, + responseType: requestConfig?.responseType ?? requestConfig?.json, + responseEncoding: + requestConfig?.responseEncoding ?? requestConfig?.encoding, + // xsrfCookieName, + // xsrfHeaderName, + // onUploadProgress, + // onDownloadProgress, + // maxContentLength, + // maxBodyLength, + // validateStatus, + // maxRedirects, + // socketPath, + httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, + // httpsAgent, + // proxy, + // cancelToken, + // decompress, + }; +} diff --git a/test/index.js b/test/index.js index fcd6b71..934124c 100644 --- a/test/index.js +++ b/test/index.js @@ -245,7 +245,7 @@ describe('get', () => { nock.cleanAll(); }); - it('accepts headers', async () => { + it.only('accepts headers', async () => { const state = { configuration: { username: 'hello', @@ -260,6 +260,7 @@ describe('get', () => { }) )(state); + console.log('finalState', finalState.data); expect(finalState.data).to.eql([ '/api/fake', { @@ -546,7 +547,7 @@ describe('delete', () => { }) )(state); - // TODO: fix this interface, if `Utils.tryJson` cleanly converts the + // TODO: fix this interface, if `Utils.tryJson` cleanly converts the // response body, it won't be under the `body` key. See `put()` example // above where we have to look inside `data.body.body`. expect(finalState.data).to.eql({}); From d6e9d71386581e55d70708ee31260405ff86f871 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 09:50:18 +0200 Subject: [PATCH 02/20] Validating Tests: accepts headers, passes, for #14 --- lib/Adaptor.js | 2 +- src/Adaptor.js | 2 +- test/index.js | 18 +++++++++--------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index d1525f6..b43d811 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -153,7 +153,7 @@ function get(path, params, callback) { // return req('GET', { url, query, auth, headers, options, ...rest }).then( return _languageCommon.http.get(config)(state).then(response => { - const nextState = (0, _languageCommon.composeNextState)(state, response); + const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/src/Adaptor.js b/src/Adaptor.js index 6e00a93..facc5ad 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -82,7 +82,7 @@ export function get(path, params, callback) { return http .get(config)(state) .then(response => { - const nextState = composeNextState(state, response); + const nextState = composeNextState(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/test/index.js b/test/index.js index 934124c..a149ad1 100644 --- a/test/index.js +++ b/test/index.js @@ -260,15 +260,15 @@ describe('get', () => { }) )(state); - console.log('finalState', finalState.data); - expect(finalState.data).to.eql([ - '/api/fake', - { - authorization: 'Basic aGVsbG86dGhlcmU=', - host: 'www.example.com', - 'x-openfn': 'testing', - }, - ]); + expect(finalState.data[1]).to.haveOwnProperty('x-openfn', 'testing'); + + expect(finalState.data[1]).to.haveOwnProperty( + 'authorization', + 'Basic aGVsbG86dGhlcmU=' + ); + + expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); + expect(finalState.references).to.eql([{ triggering: 'event' }]); }); From 67fd838c4b0a192933c9a32a59be54efe101c64f Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 10:02:09 +0200 Subject: [PATCH 03/20] Validating Tests: accepts authentication for http basic auth, passes, for #14 --- test/index.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/test/index.js b/test/index.js index a149ad1..fe9ce7e 100644 --- a/test/index.js +++ b/test/index.js @@ -260,6 +260,8 @@ describe('get', () => { }) )(state); + expect(finalState.data[0]).to.eql('/api/fake'); + expect(finalState.data[1]).to.haveOwnProperty('x-openfn', 'testing'); expect(finalState.data[1]).to.haveOwnProperty( @@ -272,7 +274,7 @@ describe('get', () => { expect(finalState.references).to.eql([{ triggering: 'event' }]); }); - it('accepts authentication for http basic auth', async () => { + it.only('accepts authentication for http basic auth', async () => { const state = { configuration: { username: 'hello', @@ -285,13 +287,14 @@ describe('get', () => { state ); - expect(finalState.data).to.eql([ - '/api/fake', - { - authorization: 'Basic aGVsbG86dGhlcmU=', - host: 'www.example.com', - }, - ]); + expect(finalState.data[0]).to.eql('/api/fake'); + + expect(finalState.data[1]).to.haveOwnProperty( + 'authorization', + 'Basic aGVsbG86dGhlcmU=' + ); + + expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); it('can enable gzip', async () => { From c233cf2e717c468960b6037fbc3676d0294be201 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 10:35:50 +0200 Subject: [PATCH 04/20] Validating Tests: can enable gzip, passes, for #14 --- lib/Utils.js | 12 +++++++++++- src/Utils.js | 8 +++++++- test/index.js | 17 +++++++++-------- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/lib/Utils.js b/lib/Utils.js index 4311daf..0c624d3 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -9,6 +9,8 @@ exports.assembleError = assembleError; exports.tryJson = tryJson; exports.mapToAxiosConfig = mapToAxiosConfig; +var _http = require("language-common/lib/http"); + function setUrl(configuration, path) { if (configuration && configuration.baseUrl) return configuration.baseUrl + path;else return path; } @@ -48,13 +50,21 @@ function tryJson(data) { function mapToAxiosConfig(requestConfig) { var _requestConfig$url, _requestConfig$params, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$httpAg; + let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; + + if ((requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.gzip) === true) { + headers = { ...headers, + 'Accept-Encoding': 'gzip, deflate' + }; + } + return { ...requestConfig, url: (_requestConfig$url = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.url) !== null && _requestConfig$url !== void 0 ? _requestConfig$url : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.uri, // method, // baseURL, // transformRequest, // transformResponse, - // headers, + headers, params: (_requestConfig$params = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.params) !== null && _requestConfig$params !== void 0 ? _requestConfig$params : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.qs, // paramsSerializer, data: (_requestConfig$data = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.data) !== null && _requestConfig$data !== void 0 ? _requestConfig$data : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.body) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData), diff --git a/src/Utils.js b/src/Utils.js index f4ca6d9..18b48e2 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,3 +1,5 @@ +import { head } from 'language-common/lib/http'; + export function setUrl(configuration, path) { if (configuration && configuration.baseUrl) return configuration.baseUrl + path; @@ -36,6 +38,10 @@ export function tryJson(data) { } export function mapToAxiosConfig(requestConfig) { + let headers = requestConfig?.headers; + if (requestConfig?.gzip === true) { + headers = { ...headers, 'Accept-Encoding': 'gzip, deflate' }; + } return { ...requestConfig, url: requestConfig?.url ?? requestConfig?.uri, @@ -43,7 +49,7 @@ export function mapToAxiosConfig(requestConfig) { // baseURL, // transformRequest, // transformResponse, - // headers, + headers, params: requestConfig?.params ?? requestConfig?.qs, // paramsSerializer, data: diff --git a/test/index.js b/test/index.js index fe9ce7e..6ef8764 100644 --- a/test/index.js +++ b/test/index.js @@ -297,7 +297,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it('can enable gzip', async () => { + it.only('can enable gzip', async () => { const state = { configuration: {}, data: {}, @@ -307,13 +307,14 @@ describe('get', () => { get('https://www.example.com/api/fake', { gzip: true }) )(state); - expect(finalState.data).to.eql([ - '/api/fake', - { - 'accept-encoding': 'gzip, deflate', - host: 'www.example.com', - }, - ]); + expect(finalState.data[0]).to.eql('/api/fake'); + + expect(finalState.data[1]).to.haveOwnProperty( + 'accept-encoding', + 'gzip, deflate' + ); + + expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); it('allows query strings to be set', async () => { From 2ed471de59386a2879336444d4eb0cb7002b2148 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 10:50:36 +0200 Subject: [PATCH 05/20] Validating Tests: allows query strings to be set, passes, for #14 --- lib/Adaptor.js | 8 ++++---- lib/Utils.js | 8 ++++++-- src/Adaptor.js | 2 +- src/Utils.js | 7 ++++++- test/index.js | 12 +++++------- 5 files changed, 22 insertions(+), 15 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index b43d811..7592bb5 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -131,13 +131,13 @@ function execute(...operations) { function get(path, params, callback) { return state => { - var _params$authenticatio; - - path = (0, _languageCommon.expandReferences)(path)(state); // params = expandReferences(params)(state); + var _params$authenticatio, _params, _params2; + path = (0, _languageCommon.expandReferences)(path)(state); + params = (0, _languageCommon.expandReferences)(params)(state); console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio = params === null || params === void 0 ? void 0 : params.authentication) !== null && _params$authenticatio !== void 0 ? _params$authenticatio : params === null || params === void 0 ? void 0 : params.auth); + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio = (_params = params) === null || _params === void 0 ? void 0 : _params.authentication) !== null && _params$authenticatio !== void 0 ? _params$authenticatio : (_params2 = params) === null || _params2 === void 0 ? void 0 : _params2.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, auth diff --git a/lib/Utils.js b/lib/Utils.js index 0c624d3..617d05b 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -48,8 +48,9 @@ function tryJson(data) { } function mapToAxiosConfig(requestConfig) { - var _requestConfig$url, _requestConfig$params, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$httpAg; + var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$httpAg; + console.log('rawRequestconfig', requestConfig); let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; if ((requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.gzip) === true) { @@ -65,7 +66,10 @@ function mapToAxiosConfig(requestConfig) { // transformRequest, // transformResponse, headers, - params: (_requestConfig$params = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.params) !== null && _requestConfig$params !== void 0 ? _requestConfig$params : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.qs, + params: { ...(requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.params), + ...(requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.qs), + ...(requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.query) + }, // paramsSerializer, data: (_requestConfig$data = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.data) !== null && _requestConfig$data !== void 0 ? _requestConfig$data : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.body) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData), // timeouts, diff --git a/src/Adaptor.js b/src/Adaptor.js index facc5ad..d2a9f63 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -58,7 +58,7 @@ export function get(path, params, callback) { return state => { path = expandReferences(path)(state); - // params = expandReferences(params)(state); + params = expandReferences(params)(state); console.log('params', params); const url = setUrl(state.configuration, path); diff --git a/src/Utils.js b/src/Utils.js index 18b48e2..9030804 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -38,6 +38,7 @@ export function tryJson(data) { } export function mapToAxiosConfig(requestConfig) { + console.log('rawRequestconfig', requestConfig); let headers = requestConfig?.headers; if (requestConfig?.gzip === true) { headers = { ...headers, 'Accept-Encoding': 'gzip, deflate' }; @@ -50,7 +51,11 @@ export function mapToAxiosConfig(requestConfig) { // transformRequest, // transformResponse, headers, - params: requestConfig?.params ?? requestConfig?.qs, + params: { + ...requestConfig?.params, + ...requestConfig?.qs, + ...requestConfig?.query, + }, // paramsSerializer, data: requestConfig?.data ?? diff --git a/test/index.js b/test/index.js index 6ef8764..2f78370 100644 --- a/test/index.js +++ b/test/index.js @@ -317,7 +317,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it('allows query strings to be set', async () => { + it.only('allows query strings to be set', async () => { const state = { configuration: {}, data: {}, @@ -326,12 +326,10 @@ describe('get', () => { const finalState = await execute( get('https://www.example.com/api/fake', { query: { id: 1 } }) )(state); - expect(finalState.data).to.eql([ - '/api/fake?id=1', - { - host: 'www.example.com', - }, - ]); + + expect(finalState.data[0]).to.eql('/api/fake?id=1'); + + expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); it('can follow redirects', async () => { From f73376462fff87e8366f8dd14bf21d858b157f49 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 13:56:24 +0200 Subject: [PATCH 06/20] Validating Tests: can keep and reuse cookies, passes, for #14 --- lib/Adaptor.js | 36 +++++++++++++++++++++++++++++++++- package-lock.json | 49 +++++++++++++++++++++++++++++++---------------- package.json | 5 +++-- src/Adaptor.js | 44 ++++++++++++++++++++++++++++++++++++++++++ test/index.js | 15 ++++++++------- 5 files changed, 122 insertions(+), 27 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 7592bb5..d42cbb8 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -81,6 +81,10 @@ var _fs = _interopRequireDefault(require("fs")); var _csvParse = _interopRequireDefault(require("csv-parse")); +var _http = require("language-common/lib/http"); + +var _toughCookie = _interopRequireDefault(require("tough-cookie")); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @module Adaptor */ @@ -107,7 +111,37 @@ function execute(...operations) { ...state }); }; -} +} // axios interceptors + + +var Cookie = _toughCookie.default.Cookie; +var cookiejar = new _toughCookie.default.CookieJar(); + +_http.__axios.interceptors.request.use(function (config) { + cookiejar.getCookies(config.url, function (err, cookies) { + config.headers.cookie = cookies.join('; '); + }); + return config; +}); + +_http.__axios.interceptors.response.use(function (response) { + let cookies; + if (response.headers['set-cookie'] instanceof Array) cookies = response.headers['set-cookie'].map(Cookie.parse);else cookies = [Cookie.parse(response.headers['set-cookie'])]; + let keepCookies = []; + response.headers['set-cookie'].forEach(function (c) { + cookiejar.setCookie(Cookie.parse(c), response.config.url, function (err, cookie) { + if (response.config.keepCookie) { + keepCookies.push(cookie.cookieString()); + } + }); + }); + return { ...response, + data: { ...response.data, + __cookie: (keepCookies === null || keepCookies === void 0 ? void 0 : keepCookies.length) === 1 ? keepCookies[0] : keepCookies, + __headers: response.headers + } + }; +}); /** * Make a GET request * @public diff --git a/package-lock.json b/package-lock.json index 66e8cb2..462e87f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2796,8 +2796,8 @@ "optional": true }, "language-common": { - "version": "github:openfn/language-common#ebae051d343c793583a6d8988a0b30d075178b83", - "from": "github:openfn/language-common#v1.0.0", + "version": "github:openfn/language-common#a99164fb28ad5794230680f4a45c3c39dce1d2ac", + "from": "github:openfn/language-common#export_axios", "requires": { "axios": "^0.21.1", "jsonpath-plus": "^4.0.0", @@ -3668,9 +3668,9 @@ "dev": true }, "psl": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz", - "integrity": "sha1-4ev2o7VWT6g3bz2iJ12nbYdcob0=" + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==" }, "punycode": { "version": "2.1.1", @@ -3804,6 +3804,22 @@ "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } } }, "require-directory": { @@ -4491,19 +4507,13 @@ } }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha1-U/Nto/R3g7CSWvoG/587FlKA94E=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" - } + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" } }, "tunnel-agent": { @@ -4566,6 +4576,11 @@ "set-value": "^2.0.1" } }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==" + }, "unset-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", diff --git a/package.json b/package.json index 7e53969..f3f0f96 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,9 @@ "cheerio-tableparser": "^1.0.1", "csv-parse": "^4.10.1", "import": "0.0.6", - "language-common": "github:openfn/language-common#v1.0.0", - "request": "^2.72.0" + "language-common": "github:openfn/language-common#export_axios", + "request": "^2.72.0", + "tough-cookie": "^4.0.0" }, "devDependencies": { "@babel/cli": "^7.12.10", diff --git a/src/Adaptor.js b/src/Adaptor.js index d2a9f63..2f1f796 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -11,6 +11,8 @@ import cheerio from 'cheerio'; import cheerioTableparser from 'cheerio-tableparser'; import fs from 'fs'; import parse from 'csv-parse'; +import { __axios } from 'language-common/lib/http'; +import tough from 'tough-cookie'; /** * Execute a sequence of operations. @@ -35,6 +37,48 @@ export function execute(...operations) { }; } +// axios interceptors +var Cookie = tough.Cookie; +var cookiejar = new tough.CookieJar(); + +__axios.interceptors.request.use(function (config) { + cookiejar.getCookies(config.url, function (err, cookies) { + config.headers.cookie = cookies.join('; '); + }); + return config; +}); + +__axios.interceptors.response.use(function (response) { + let cookies; + + if (response.headers['set-cookie'] instanceof Array) + cookies = response.headers['set-cookie'].map(Cookie.parse); + else cookies = [Cookie.parse(response.headers['set-cookie'])]; + + let keepCookies = []; + + response.headers['set-cookie'].forEach(function (c) { + cookiejar.setCookie( + Cookie.parse(c), + response.config.url, + function (err, cookie) { + if (response.config.keepCookie) { + keepCookies.push(cookie.cookieString()); + } + } + ); + }); + + return { + ...response, + data: { + ...response.data, + __cookie: keepCookies?.length === 1 ? keepCookies[0] : keepCookies, + __headers: response.headers, + }, + }; +}); + /** * Make a GET request * @public diff --git a/test/index.js b/test/index.js index 2f78370..f804c93 100644 --- a/test/index.js +++ b/test/index.js @@ -225,9 +225,9 @@ describe('get', () => { testServer.get('/api/fake-cookies').reply( 200, function (url, body) { - return url; + return { url }; }, - { 'Set-Cookie': 'tasty_cookie=choco' } + { 'Set-Cookie': ['tasty_cookie=choco'] } ); testServer.get('/api/fake-callback').reply(200, function (url, body) { @@ -245,7 +245,7 @@ describe('get', () => { nock.cleanAll(); }); - it.only('accepts headers', async () => { + it('accepts headers', async () => { const state = { configuration: { username: 'hello', @@ -274,7 +274,7 @@ describe('get', () => { expect(finalState.references).to.eql([{ triggering: 'event' }]); }); - it.only('accepts authentication for http basic auth', async () => { + it('accepts authentication for http basic auth', async () => { const state = { configuration: { username: 'hello', @@ -297,7 +297,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it.only('can enable gzip', async () => { + it('can enable gzip', async () => { const state = { configuration: {}, data: {}, @@ -317,7 +317,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it.only('allows query strings to be set', async () => { + it('allows query strings to be set', async () => { const state = { configuration: {}, data: {}, @@ -346,7 +346,7 @@ describe('get', () => { expect(finalState.data.body).to.eql('/api/fake-endpoint-3'); }); - it('can keep and reuse cookies', async () => { + it.only('can keep and reuse cookies', async () => { const state = { configuration: {}, data: {}, @@ -357,6 +357,7 @@ describe('get', () => { keepCookie: true, }) )(state); + expect(finalState.data.__cookie).to.eql('tasty_cookie=choco'); }); From 62770a014b8e4928a55a8e84e69fbdfc817a94e9 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 14:50:38 +0200 Subject: [PATCH 07/20] Validating Tests: can follow redirects, passes, for #14 --- lib/Adaptor.js | 30 ++++++++++++++++++++---------- lib/Utils.js | 4 ++-- src/Adaptor.js | 38 +++++++++++++++++++------------------- src/Utils.js | 4 +++- test/index.js | 8 ++++---- 5 files changed, 48 insertions(+), 36 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index d42cbb8..f7d69a1 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -118,25 +118,35 @@ var Cookie = _toughCookie.default.Cookie; var cookiejar = new _toughCookie.default.CookieJar(); _http.__axios.interceptors.request.use(function (config) { - cookiejar.getCookies(config.url, function (err, cookies) { - config.headers.cookie = cookies.join('; '); + cookiejar === null || cookiejar === void 0 ? void 0 : cookiejar.getCookies(config.url, function (err, cookies) { + config.headers.cookie = cookies === null || cookies === void 0 ? void 0 : cookies.join('; '); }); return config; }); _http.__axios.interceptors.response.use(function (response) { let cookies; - if (response.headers['set-cookie'] instanceof Array) cookies = response.headers['set-cookie'].map(Cookie.parse);else cookies = [Cookie.parse(response.headers['set-cookie'])]; let keepCookies = []; - response.headers['set-cookie'].forEach(function (c) { - cookiejar.setCookie(Cookie.parse(c), response.config.url, function (err, cookie) { - if (response.config.keepCookie) { - keepCookies.push(cookie.cookieString()); - } + + if (response.headers['set-cookie']) { + var _response$headers$set, _response$headers$set2; + + if (response.headers['set-cookie'] instanceof Array) cookies = (_response$headers$set = response.headers['set-cookie']) === null || _response$headers$set === void 0 ? void 0 : _response$headers$set.map(Cookie.parse);else cookies = [Cookie.parse(response.headers['set-cookie'])]; + (_response$headers$set2 = response.headers['set-cookie']) === null || _response$headers$set2 === void 0 ? void 0 : _response$headers$set2.forEach(function (c) { + cookiejar.setCookie(Cookie.parse(c), response.config.url, function (err, cookie) { + var _response$config; + + if ((_response$config = response.config) === null || _response$config === void 0 ? void 0 : _response$config.keepCookie) { + keepCookies === null || keepCookies === void 0 ? void 0 : keepCookies.push(cookie === null || cookie === void 0 ? void 0 : cookie.cookieString()); + } + }); }); - }); + } + return { ...response, - data: { ...response.data, + data: { + body: { ...response.data + }, __cookie: (keepCookies === null || keepCookies === void 0 ? void 0 : keepCookies.length) === 1 ? keepCookies[0] : keepCookies, __headers: response.headers } diff --git a/lib/Utils.js b/lib/Utils.js index 617d05b..28bc9ed 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -48,7 +48,7 @@ function tryJson(data) { } function mapToAxiosConfig(requestConfig) { - var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$httpAg; + var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed, _requestConfig$httpAg; console.log('rawRequestconfig', requestConfig); let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; @@ -85,7 +85,7 @@ function mapToAxiosConfig(requestConfig) { // maxContentLength, // maxBodyLength, // validateStatus, - // maxRedirects, + maxRedirects: (_requestConfig$maxRed = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.maxRedirects) !== null && _requestConfig$maxRed !== void 0 ? _requestConfig$maxRed : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.followAllRedirects) === false ? 0 : 5, // socketPath, httpAgent: (_requestConfig$httpAg = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.httpAgent) !== null && _requestConfig$httpAg !== void 0 ? _requestConfig$httpAg : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.agent // httpsAgent, // proxy, diff --git a/src/Adaptor.js b/src/Adaptor.js index 2f1f796..1f16a8a 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -42,37 +42,37 @@ var Cookie = tough.Cookie; var cookiejar = new tough.CookieJar(); __axios.interceptors.request.use(function (config) { - cookiejar.getCookies(config.url, function (err, cookies) { - config.headers.cookie = cookies.join('; '); + cookiejar?.getCookies(config.url, function (err, cookies) { + config.headers.cookie = cookies?.join('; '); }); return config; }); __axios.interceptors.response.use(function (response) { let cookies; - - if (response.headers['set-cookie'] instanceof Array) - cookies = response.headers['set-cookie'].map(Cookie.parse); - else cookies = [Cookie.parse(response.headers['set-cookie'])]; - let keepCookies = []; - response.headers['set-cookie'].forEach(function (c) { - cookiejar.setCookie( - Cookie.parse(c), - response.config.url, - function (err, cookie) { - if (response.config.keepCookie) { - keepCookies.push(cookie.cookieString()); + if (response.headers['set-cookie']) { + if (response.headers['set-cookie'] instanceof Array) + cookies = response.headers['set-cookie']?.map(Cookie.parse); + else cookies = [Cookie.parse(response.headers['set-cookie'])]; + + response.headers['set-cookie']?.forEach(function (c) { + cookiejar.setCookie( + Cookie.parse(c), + response.config.url, + function (err, cookie) { + if (response.config?.keepCookie) { + keepCookies?.push(cookie?.cookieString()); + } } - } - ); - }); - + ); + }); + } return { ...response, data: { - ...response.data, + body: { ...response.data }, __cookie: keepCookies?.length === 1 ? keepCookies[0] : keepCookies, __headers: response.headers, }, diff --git a/src/Utils.js b/src/Utils.js index 9030804..d08feb5 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -74,7 +74,9 @@ export function mapToAxiosConfig(requestConfig) { // maxContentLength, // maxBodyLength, // validateStatus, - // maxRedirects, + maxRedirects: + requestConfig?.maxRedirects ?? + (requestConfig?.followAllRedirects === false ? 0 : 5), // socketPath, httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, // httpsAgent, diff --git a/test/index.js b/test/index.js index f804c93..6913419 100644 --- a/test/index.js +++ b/test/index.js @@ -219,7 +219,7 @@ describe('get', () => { }) .get('/api/fake-endpoint-3') .reply(200, function (url, body) { - return url; + return { url }; }); testServer.get('/api/fake-cookies').reply( @@ -332,7 +332,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it('can follow redirects', async () => { + it.only('can follow redirects', async () => { const state = { configuration: {}, data: {}, @@ -343,10 +343,10 @@ describe('get', () => { headers: { followAllRedirects: true }, }) )(state); - expect(finalState.data.body).to.eql('/api/fake-endpoint-3'); + expect(finalState.data.body.url).to.eql('/api/fake-endpoint-3'); }); - it.only('can keep and reuse cookies', async () => { + it('can keep and reuse cookies', async () => { const state = { configuration: {}, data: {}, From 9507283a30222bd5d2f62d762f1f115794c9fcf4 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 15:20:39 +0200 Subject: [PATCH 08/20] Validating Tests: accepts callbacks and calls them with nextState, passes, for #14 --- test/index.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/index.js b/test/index.js index 6913419..bc663dc 100644 --- a/test/index.js +++ b/test/index.js @@ -332,7 +332,7 @@ describe('get', () => { expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); }); - it.only('can follow redirects', async () => { + it('can follow redirects', async () => { const state = { configuration: {}, data: {}, @@ -361,7 +361,7 @@ describe('get', () => { expect(finalState.data.__cookie).to.eql('tasty_cookie=choco'); }); - it('accepts callbacks and calls them with nextState', async () => { + it.only('accepts callbacks and calls them with nextState', async () => { const state = { configuration: {}, data: {}, @@ -372,7 +372,9 @@ describe('get', () => { return state; }) )(state); - expect(finalState.data.id).to.eql(3); + + console.log('finalState', finalState); + expect(finalState.data.body.id).to.eql(3); }); it('returns a promise that contains nextState', async () => { From 4d90d6f29bdd9011f2475897f3e51d197e5f3d18 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 15:24:58 +0200 Subject: [PATCH 09/20] Validating Tests: returns a promise that contains nextState, passes, for #14 --- test/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/index.js b/test/index.js index bc663dc..88a745b 100644 --- a/test/index.js +++ b/test/index.js @@ -361,7 +361,7 @@ describe('get', () => { expect(finalState.data.__cookie).to.eql('tasty_cookie=choco'); }); - it.only('accepts callbacks and calls them with nextState', async () => { + it('accepts callbacks and calls them with nextState', async () => { const state = { configuration: {}, data: {}, @@ -373,7 +373,6 @@ describe('get', () => { }) )(state); - console.log('finalState', finalState); expect(finalState.data.body.id).to.eql(3); }); @@ -386,7 +385,7 @@ describe('get', () => { const finalState = await execute( get('https://www.example.com/api/fake-promise', {}) )(state).then(state => state); - expect(finalState.data.id).to.eql(3); + expect(finalState.data.body.id).to.eql(3); }); }); From 5ffdff7a1a1fe343b8c0d5216a45224fd8ca8691 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 15:38:04 +0200 Subject: [PATCH 10/20] Validating Tests: can set JSON on the request body, passing, for #14 --- lib/Adaptor.js | 56 +++++++++++++++++---------------------- src/Adaptor.js | 71 +++++++++++++++++++++++++------------------------- test/index.js | 2 +- 3 files changed, 60 insertions(+), 69 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index f7d69a1..1d04572 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -88,6 +88,17 @@ var _toughCookie = _interopRequireDefault(require("tough-cookie")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @module Adaptor */ +// KEEP THIS HERE FOR NOTES +// const { +// query, +// headers, +// authentication, +// body, +// formData, +// options, +// ...rest +// } = expandReferences(params)(state); +// return req('GET', { url, query, auth, headers, options, ...rest }).then( /** * Execute a sequence of operations. @@ -185,17 +196,7 @@ function get(path, params, callback) { const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, auth - }); // const { - // query, - // headers, - // authentication, - // body, - // formData, - // options, - // ...rest - // } = expandReferences(params)(state); - // return req('GET', { url, query, auth, headers, options, ...rest }).then( - + }); return _languageCommon.http.get(config)(state).then(response => { const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); @@ -208,6 +209,7 @@ function get(path, params, callback) { * @public * @example * post("/myendpoint", { + * @function * body: {"foo": "bar"}, * headers: {"content-type": "application/json"}, * authentication: {username: "user", password: "pass"}, @@ -216,7 +218,6 @@ function get(path, params, callback) { * return state; * } * ) - * @function * @param {string} path - Path to resource * @param {object} params - Body, Query, Headers and Authentication parameters * @param {function} callback - (Optional) Callback function @@ -226,28 +227,19 @@ function get(path, params, callback) { function post(path, params, callback) { return state => { + var _params$authenticatio2, _params3, _params4; + + path = (0, _languageCommon.expandReferences)(path)(state); + params = (0, _languageCommon.expandReferences)(params)(state); + console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = (0, _languageCommon.expandReferences)(params)(state); - const auth = (0, _Utils.setAuth)(state.configuration, authentication); - return (0, _Client.req)('POST', { + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio2 = (_params3 = params) === null || _params3 === void 0 ? void 0 : _params3.authentication) !== null && _params$authenticatio2 !== void 0 ? _params$authenticatio2 : (_params4 = params) === null || _params4 === void 0 ? void 0 : _params4.auth); + const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, - query, - body, - auth, - headers, - formData, - options, - ...rest - }).then(response => { - const nextState = (0, _languageCommon.composeNextState)(state, response); + auth + }); + return _languageCommon.http.post(config)(state).then(response => { + const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/src/Adaptor.js b/src/Adaptor.js index 1f16a8a..840de20 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -14,6 +14,19 @@ import parse from 'csv-parse'; import { __axios } from 'language-common/lib/http'; import tough from 'tough-cookie'; +// KEEP THIS HERE FOR NOTES +// const { +// query, +// headers, +// authentication, +// body, +// formData, +// options, +// ...rest +// } = expandReferences(params)(state); + +// return req('GET', { url, query, auth, headers, options, ...rest }).then( + /** * Execute a sequence of operations. * Wraps `language-common/execute`, and prepends initial state for http. @@ -103,7 +116,9 @@ export function get(path, params, callback) { path = expandReferences(path)(state); params = expandReferences(params)(state); + console.log('params', params); + const url = setUrl(state.configuration, path); const auth = setAuth( @@ -112,17 +127,7 @@ export function get(path, params, callback) { ); const config = mapToAxiosConfig({ ...params, url, auth }); - // const { - // query, - // headers, - // authentication, - // body, - // formData, - // options, - // ...rest - // } = expandReferences(params)(state); - - // return req('GET', { url, query, auth, headers, options, ...rest }).then( + return http .get(config)(state) .then(response => { @@ -138,6 +143,7 @@ export function get(path, params, callback) { * @public * @example * post("/myendpoint", { + * @function * body: {"foo": "bar"}, * headers: {"content-type": "application/json"}, * authentication: {username: "user", password: "pass"}, @@ -146,7 +152,6 @@ export function get(path, params, callback) { * return state; * } * ) - * @function * @param {string} path - Path to resource * @param {object} params - Body, Query, Headers and Authentication parameters * @param {function} callback - (Optional) Callback function @@ -154,34 +159,28 @@ export function get(path, params, callback) { */ export function post(path, params, callback) { return state => { + path = expandReferences(path)(state); + + params = expandReferences(params)(state); + + console.log('params', params); + const url = setUrl(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = expandReferences(params)(state); + const auth = setAuth( + state.configuration, + params?.authentication ?? params?.auth + ); - const auth = setAuth(state.configuration, authentication); + const config = mapToAxiosConfig({ ...params, url, auth }); - return req('POST', { - url, - query, - body, - auth, - headers, - formData, - options, - ...rest, - }).then(response => { - const nextState = composeNextState(state, response); - if (callback) return callback(nextState); - return nextState; - }); + return http + .post(config)(state) + .then(response => { + const nextState = composeNextState(state, response.data); + if (callback) return callback(nextState); + return nextState; + }); }; } diff --git a/test/index.js b/test/index.js index 88a745b..8a2b036 100644 --- a/test/index.js +++ b/test/index.js @@ -410,7 +410,7 @@ describe('post', () => { }); }); - it('can set JSON on the request body', async () => { + it.only('can set JSON on the request body', async () => { const state = { configuration: {}, data: { name: 'test', age: 24 }, From a16a31319c5bfc94e9b00b7e11099cb84f2d6783 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 15:58:09 +0200 Subject: [PATCH 11/20] Validating Tests: can set data via Form param on the request body, passes, for #14 --- lib/Adaptor.js | 5 ++--- src/Adaptor.js | 5 +++-- test/index.js | 11 +++++++---- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 1d04572..fc75713 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -154,10 +154,9 @@ _http.__axios.interceptors.response.use(function (response) { }); } + const resData = (0, _Utils.tryJson)(response.data); return { ...response, - data: { - body: { ...response.data - }, + data: { ...resData, __cookie: (keepCookies === null || keepCookies === void 0 ? void 0 : keepCookies.length) === 1 ? keepCookies[0] : keepCookies, __headers: response.headers } diff --git a/src/Adaptor.js b/src/Adaptor.js index 840de20..da9aab5 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -1,6 +1,6 @@ /** @module Adaptor */ import { req, rawRequest } from './Client'; -import { setAuth, setUrl, mapToAxiosConfig } from './Utils'; +import { setAuth, setUrl, mapToAxiosConfig, tryJson } from './Utils'; import { execute as commonExecute, expandReferences, @@ -82,10 +82,11 @@ __axios.interceptors.response.use(function (response) { ); }); } + const resData = tryJson(response.data); return { ...response, data: { - body: { ...response.data }, + ...resData, __cookie: keepCookies?.length === 1 ? keepCookies[0] : keepCookies, __headers: response.headers, }, diff --git a/test/index.js b/test/index.js index 8a2b036..2bf3b1b 100644 --- a/test/index.js +++ b/test/index.js @@ -410,7 +410,7 @@ describe('post', () => { }); }); - it.only('can set JSON on the request body', async () => { + it('can set JSON on the request body', async () => { const state = { configuration: {}, data: { name: 'test', age: 24 }, @@ -422,7 +422,7 @@ describe('post', () => { expect(finalState.data.body).to.eql({ name: 'test', age: 24 }); }); - it('can set data via Form param on the request body', async () => { + it.only('can set data via Form param on the request body', async () => { let form = { username: 'fake', password: 'fake_pass', @@ -435,10 +435,13 @@ describe('post', () => { const finalState = await execute( post('https://www.example.com/api/fake-form', { form: state.data, - headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, }) )(state); - expect(finalState.data.body).to.eql('username=fake&password=fake_pass'); + + expect(finalState.data.body).to.eql({ + username: 'fake', + password: 'fake_pass', + }); }); it('can set FormData on the request body', async () => { From 176399a749b83107721ac426f8f7d5b808e7943d Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 17:46:28 +0200 Subject: [PATCH 12/20] Validating Tests: can set FormData on the request body, almost passing, for #14 --- lib/Utils.js | 20 +++++++++++++++++++- package-lock.json | 18 ++++++++++++++---- package.json | 1 + src/Utils.js | 26 +++++++++++++++++++++++--- test/index.js | 12 ++++++++---- 5 files changed, 65 insertions(+), 12 deletions(-) diff --git a/lib/Utils.js b/lib/Utils.js index 28bc9ed..1787228 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -11,6 +11,10 @@ exports.mapToAxiosConfig = mapToAxiosConfig; var _http = require("language-common/lib/http"); +var _formData = _interopRequireDefault(require("form-data")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function setUrl(configuration, path) { if (configuration && configuration.baseUrl) return configuration.baseUrl + path;else return path; } @@ -51,6 +55,8 @@ function mapToAxiosConfig(requestConfig) { var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed, _requestConfig$httpAg; console.log('rawRequestconfig', requestConfig); + const form = new _formData.default(); + const formData = (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form); let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; if ((requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.gzip) === true) { @@ -59,6 +65,18 @@ function mapToAxiosConfig(requestConfig) { }; } + if (formData) { + Object.entries(requestConfig.formData).forEach(element => { + form.append(element[0], element[1]); + }); + const formHeaders = form.getHeaders(); + console.log('formHeaders', formHeaders); + headers = { ...headers, + ...formHeaders + }; + } + + console.log('form', form); return { ...requestConfig, url: (_requestConfig$url = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.url) !== null && _requestConfig$url !== void 0 ? _requestConfig$url : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.uri, // method, @@ -71,7 +89,7 @@ function mapToAxiosConfig(requestConfig) { ...(requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.query) }, // paramsSerializer, - data: (_requestConfig$data = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.data) !== null && _requestConfig$data !== void 0 ? _requestConfig$data : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.body) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData), + data: (_requestConfig$data = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.data) !== null && _requestConfig$data !== void 0 ? _requestConfig$data : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.body) || form, // timeouts, // withCredentials, // adapter, diff --git a/package-lock.json b/package-lock.json index 462e87f..3c5c3fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2276,12 +2276,12 @@ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha1-3M5SwF9kTymManq5Nr1yTO/786Y=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz", + "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==", "requires": { "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", + "combined-stream": "^1.0.8", "mime-types": "^2.1.12" } }, @@ -3806,6 +3806,16 @@ "uuid": "^3.3.2" }, "dependencies": { + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", diff --git a/package.json b/package.json index f3f0f96..c38e68a 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "cheerio": "^1.0.0-rc.3", "cheerio-tableparser": "^1.0.1", "csv-parse": "^4.10.1", + "form-data": "^3.0.0", "import": "0.0.6", "language-common": "github:openfn/language-common#export_axios", "request": "^2.72.0", diff --git a/src/Utils.js b/src/Utils.js index d08feb5..c6e12d5 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,4 +1,5 @@ import { head } from 'language-common/lib/http'; +import FormData from 'form-data'; export function setUrl(configuration, path) { if (configuration && configuration.baseUrl) @@ -39,10 +40,31 @@ export function tryJson(data) { export function mapToAxiosConfig(requestConfig) { console.log('rawRequestconfig', requestConfig); + + const form = new FormData(); + + const formData = requestConfig?.formData || requestConfig?.form; + let headers = requestConfig?.headers; + if (requestConfig?.gzip === true) { headers = { ...headers, 'Accept-Encoding': 'gzip, deflate' }; } + + if (formData) { + Object.entries(requestConfig.formData).forEach(element => { + form.append(element[0], element[1]); + }); + + const formHeaders = form.getHeaders(); + + console.log('formHeaders', formHeaders); + + headers = { ...headers, ...formHeaders }; + } + + console.log('form', form); + return { ...requestConfig, url: requestConfig?.url ?? requestConfig?.uri, @@ -57,9 +79,7 @@ export function mapToAxiosConfig(requestConfig) { ...requestConfig?.query, }, // paramsSerializer, - data: - requestConfig?.data ?? - (requestConfig?.body || requestConfig?.form || requestConfig?.formData), + data: requestConfig?.data ?? (requestConfig?.body || form), // timeouts, // withCredentials, // adapter, diff --git a/test/index.js b/test/index.js index 2bf3b1b..ec31f1e 100644 --- a/test/index.js +++ b/test/index.js @@ -1,6 +1,8 @@ import Adaptor from '../src'; import { expect } from 'chai'; import nock from 'nock'; +// import { FormData } from 'form-data'; +// var FormData = require('form-data'); const { execute, get, post, put, patch, del, alterState } = Adaptor; @@ -422,7 +424,7 @@ describe('post', () => { expect(finalState.data.body).to.eql({ name: 'test', age: 24 }); }); - it.only('can set data via Form param on the request body', async () => { + it('can set data via Form param on the request body', async () => { let form = { username: 'fake', password: 'fake_pass', @@ -444,12 +446,14 @@ describe('post', () => { }); }); - it('can set FormData on the request body', async () => { + it.only('can set FormData on the request body', async () => { + // console.log('formData', FormData.default); let formData = { id: 'fake_id', parent: 'fake_parent', mobile_phone: 'fake_phone', }; + const state = { configuration: {}, data: formData, @@ -462,7 +466,8 @@ describe('post', () => { }, }) )(state); - expect(finalState.data.body).to.contain('Content-Disposition: form-data'); + console.log('finalState', finalState); + // expect(finalState.data.body).to.contain('Content-Disposition: form-data'); }); it('can set successCodes on the request', async () => { @@ -475,7 +480,6 @@ describe('post', () => { configuration: {}, data: formData, }; - const finalState = await execute( post('https://www.example.com/api/fake-custom-success-codes', { formData: state => { From 4752978cba015d8fec51b7f03fd497a410afa6c8 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 21:48:38 +0200 Subject: [PATCH 13/20] Validating Tests: can set FormData on the request body, failing, for #14 --- lib/Adaptor.js | 2 +- lib/Utils.js | 28 ++++++++++++++++++++++++---- package.json | 3 ++- src/Adaptor.js | 10 ++++++++-- src/Utils.js | 21 ++++++++++++++++++++- 5 files changed, 55 insertions(+), 9 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index fc75713..2a4c9f7 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -220,7 +220,7 @@ function get(path, params, callback) { * @param {string} path - Path to resource * @param {object} params - Body, Query, Headers and Authentication parameters * @param {function} callback - (Optional) Callback function - * @returns {Operation} + * @returns {operation} */ diff --git a/lib/Utils.js b/lib/Utils.js index 1787228..236c0b4 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -8,11 +8,14 @@ exports.setAuth = setAuth; exports.assembleError = assembleError; exports.tryJson = tryJson; exports.mapToAxiosConfig = mapToAxiosConfig; +exports.recursivelyExpandReferences = recursivelyExpandReferences; var _http = require("language-common/lib/http"); var _formData = _interopRequireDefault(require("form-data")); +var _fp = require("lodash/fp"); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function setUrl(configuration, path) { @@ -52,7 +55,7 @@ function tryJson(data) { } function mapToAxiosConfig(requestConfig) { - var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed, _requestConfig$httpAg; + var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed; console.log('rawRequestconfig', requestConfig); const form = new _formData.default(); @@ -103,12 +106,29 @@ function mapToAxiosConfig(requestConfig) { // maxContentLength, // maxBodyLength, // validateStatus, - maxRedirects: (_requestConfig$maxRed = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.maxRedirects) !== null && _requestConfig$maxRed !== void 0 ? _requestConfig$maxRed : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.followAllRedirects) === false ? 0 : 5, - // socketPath, - httpAgent: (_requestConfig$httpAg = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.httpAgent) !== null && _requestConfig$httpAg !== void 0 ? _requestConfig$httpAg : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.agent // httpsAgent, + maxRedirects: (_requestConfig$maxRed = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.maxRedirects) !== null && _requestConfig$maxRed !== void 0 ? _requestConfig$maxRed : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.followAllRedirects) === false ? 0 : 5 // socketPath, + // httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, + // httpsAgent, // proxy, // cancelToken, // decompress, }; } + +function recursivelyExpandReferences(thing) { + return state => { + if (typeof thing !== 'object') return typeof thing == 'function' ? thing(state) : thing; + let result = (0, _fp.mapValues)(function (value) { + if (Array.isArray(value)) { + return value.map(item => { + return recursivelyExpandReferences(item)(state); + }); + } else { + return recursivelyExpandReferences(value)(state); + } + })(thing); + if (Array.isArray(thing)) result = Object.values(result); + return result; + }; +} diff --git a/package.json b/package.json index c38e68a..912e674 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,8 @@ "import": "0.0.6", "language-common": "github:openfn/language-common#export_axios", "request": "^2.72.0", - "tough-cookie": "^4.0.0" + "tough-cookie": "^4.0.0", + "lodash": "^4.17.19" }, "devDependencies": { "@babel/cli": "^7.12.10", diff --git a/src/Adaptor.js b/src/Adaptor.js index da9aab5..36a2fa4 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -1,6 +1,12 @@ /** @module Adaptor */ import { req, rawRequest } from './Client'; -import { setAuth, setUrl, mapToAxiosConfig, tryJson } from './Utils'; +import { + setAuth, + setUrl, + mapToAxiosConfig, + tryJson, + recursivelyExpandReferences, +} from './Utils'; import { execute as commonExecute, expandReferences, @@ -156,7 +162,7 @@ export function get(path, params, callback) { * @param {string} path - Path to resource * @param {object} params - Body, Query, Headers and Authentication parameters * @param {function} callback - (Optional) Callback function - * @returns {Operation} + * @returns {operation} */ export function post(path, params, callback) { return state => { diff --git a/src/Utils.js b/src/Utils.js index c6e12d5..1af5e47 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,5 +1,6 @@ import { head } from 'language-common/lib/http'; import FormData from 'form-data'; +import { mapValues } from 'lodash/fp'; export function setUrl(configuration, path) { if (configuration && configuration.baseUrl) @@ -98,10 +99,28 @@ export function mapToAxiosConfig(requestConfig) { requestConfig?.maxRedirects ?? (requestConfig?.followAllRedirects === false ? 0 : 5), // socketPath, - httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, + // httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, // httpsAgent, // proxy, // cancelToken, // decompress, }; } + +export function recursivelyExpandReferences(thing) { + return state => { + if (typeof thing !== 'object') + return typeof thing == 'function' ? thing(state) : thing; + let result = mapValues(function (value) { + if (Array.isArray(value)) { + return value.map(item => { + return recursivelyExpandReferences(item)(state); + }); + } else { + return recursivelyExpandReferences(value)(state); + } + })(thing); + if (Array.isArray(thing)) result = Object.values(result); + return result; + }; +} From ac093cb35b7c60e884279c45d44eefd63ad559c1 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 22:23:36 +0200 Subject: [PATCH 14/20] Validating Tests: can set successCodes on the request, passes, for #14 --- lib/Utils.js | 6 +++++- src/Utils.js | 7 ++++++- test/index.js | 12 +++++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/Utils.js b/lib/Utils.js index 236c0b4..f4247bd 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -105,7 +105,11 @@ function mapToAxiosConfig(requestConfig) { // onDownloadProgress, // maxContentLength, // maxBodyLength, - // validateStatus, + validateStatus: function (status) { + var _requestConfig$option, _requestConfig$option2; + + return status >= 200 && status < 300 || (requestConfig === null || requestConfig === void 0 ? void 0 : (_requestConfig$option = requestConfig.options) === null || _requestConfig$option === void 0 ? void 0 : (_requestConfig$option2 = _requestConfig$option.successCodes) === null || _requestConfig$option2 === void 0 ? void 0 : _requestConfig$option2.includes(status)); + }, maxRedirects: (_requestConfig$maxRed = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.maxRedirects) !== null && _requestConfig$maxRed !== void 0 ? _requestConfig$maxRed : (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.followAllRedirects) === false ? 0 : 5 // socketPath, // httpAgent: requestConfig?.httpAgent ?? requestConfig?.agent, // httpsAgent, diff --git a/src/Utils.js b/src/Utils.js index 1af5e47..e4d6ca9 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -94,7 +94,12 @@ export function mapToAxiosConfig(requestConfig) { // onDownloadProgress, // maxContentLength, // maxBodyLength, - // validateStatus, + validateStatus: function (status) { + return ( + (status >= 200 && status < 300) || + requestConfig?.options?.successCodes?.includes(status) + ); + }, maxRedirects: requestConfig?.maxRedirects ?? (requestConfig?.followAllRedirects === false ? 0 : 5), diff --git a/test/index.js b/test/index.js index ec31f1e..dec29d4 100644 --- a/test/index.js +++ b/test/index.js @@ -408,7 +408,7 @@ describe('post', () => { testServer .post('/api/fake-custom-success-codes') .reply(302, function (url, body) { - return { body, statusCode: 302 }; + return { ...body, statusCode: 302 }; }); }); @@ -446,7 +446,7 @@ describe('post', () => { }); }); - it.only('can set FormData on the request body', async () => { + it('can set FormData on the request body', async () => { // console.log('formData', FormData.default); let formData = { id: 'fake_id', @@ -470,7 +470,7 @@ describe('post', () => { // expect(finalState.data.body).to.contain('Content-Disposition: form-data'); }); - it('can set successCodes on the request', async () => { + it.only('can set successCodes on the request', async () => { let formData = { id: 'fake_id', parent: 'fake_parent', @@ -482,13 +482,15 @@ describe('post', () => { }; const finalState = await execute( post('https://www.example.com/api/fake-custom-success-codes', { - formData: state => { + body: state => { return state.data; }, options: { successCodes: [302] }, }) )(state); - expect(finalState.data.statusCode).to.eq(302); + + console.log('finalState', finalState); + expect(finalState.data.body.statusCode).to.eq(302); }); }); From 6137230488727b81a343826cbdcf26e0275bdf88 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 22:27:46 +0200 Subject: [PATCH 15/20] Validating Tests: sends a put request, passing, for #14 --- lib/Adaptor.js | 41 +++++++++++++++++++------------------- src/Adaptor.js | 53 +++++++++++++++++++++++++++----------------------- test/index.js | 5 ++--- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 2a4c9f7..6536466 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -267,28 +267,29 @@ function post(path, params, callback) { function put(path, params, callback) { return state => { + var _params$authenticatio3, _params5, _params6; + + // const url = setUrl(state.configuration, path); + // const { + // query, + // headers, + // authentication, + // body, + // formData, + // options, + // ...rest + // } = expandReferences(params)(state); + path = (0, _languageCommon.expandReferences)(path)(state); + params = (0, _languageCommon.expandReferences)(params)(state); + console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = (0, _languageCommon.expandReferences)(params)(state); - const auth = (0, _Utils.setAuth)(state.configuration, authentication); - return (0, _Client.req)('PUT', { + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio3 = (_params5 = params) === null || _params5 === void 0 ? void 0 : _params5.authentication) !== null && _params$authenticatio3 !== void 0 ? _params$authenticatio3 : (_params6 = params) === null || _params6 === void 0 ? void 0 : _params6.auth); + const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, - query, - body, - formData, - auth, - headers, - options, - ...rest - }).then(response => { - const nextState = (0, _languageCommon.composeNextState)(state, response); + auth + }); + return _languageCommon.http.put(config)(state).then(response => { + const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/src/Adaptor.js b/src/Adaptor.js index 36a2fa4..bbb8a9b 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -212,34 +212,39 @@ export function post(path, params, callback) { */ export function put(path, params, callback) { return state => { + // const url = setUrl(state.configuration, path); + + // const { + // query, + // headers, + // authentication, + // body, + // formData, + // options, + // ...rest + // } = expandReferences(params)(state); + path = expandReferences(path)(state); + + params = expandReferences(params)(state); + + console.log('params', params); + const url = setUrl(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = expandReferences(params)(state); + const auth = setAuth( + state.configuration, + params?.authentication ?? params?.auth + ); - const auth = setAuth(state.configuration, authentication); + const config = mapToAxiosConfig({ ...params, url, auth }); - return req('PUT', { - url, - query, - body, - formData, - auth, - headers, - options, - ...rest, - }).then(response => { - const nextState = composeNextState(state, response); - if (callback) return callback(nextState); - return nextState; - }); + return http + .put(config)(state) + .then(response => { + const nextState = composeNextState(state, response.data); + if (callback) return callback(nextState); + return nextState; + }); }; } diff --git a/test/index.js b/test/index.js index dec29d4..ef30766 100644 --- a/test/index.js +++ b/test/index.js @@ -470,7 +470,7 @@ describe('post', () => { // expect(finalState.data.body).to.contain('Content-Disposition: form-data'); }); - it.only('can set successCodes on the request', async () => { + it('can set successCodes on the request', async () => { let formData = { id: 'fake_id', parent: 'fake_parent', @@ -489,7 +489,6 @@ describe('post', () => { }) )(state); - console.log('finalState', finalState); expect(finalState.data.body.statusCode).to.eq(302); }); }); @@ -501,7 +500,7 @@ describe('put', () => { }); }); - it('sends a put request', async () => { + it.only('sends a put request', async () => { const state = { configuration: {}, data: { name: 'New name' }, From b597ba8e1d0e885b4a99adc813fb3e19a71e7359 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 22:31:19 +0200 Subject: [PATCH 16/20] Validating Tests: sends a patch request, passes, for #14 --- lib/Adaptor.js | 41 +++++++++++--------------------------- src/Adaptor.js | 53 +++++++++++++++++--------------------------------- test/index.js | 4 ++-- 3 files changed, 31 insertions(+), 67 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 6536466..2db3316 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -269,16 +269,6 @@ function put(path, params, callback) { return state => { var _params$authenticatio3, _params5, _params6; - // const url = setUrl(state.configuration, path); - // const { - // query, - // headers, - // authentication, - // body, - // formData, - // options, - // ...rest - // } = expandReferences(params)(state); path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); console.log('params', params); @@ -318,28 +308,19 @@ function put(path, params, callback) { function patch(path, params, callback) { return state => { + var _params$authenticatio4, _params7, _params8; + + path = (0, _languageCommon.expandReferences)(path)(state); + params = (0, _languageCommon.expandReferences)(params)(state); + console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = (0, _languageCommon.expandReferences)(params)(state); - const auth = (0, _Utils.setAuth)(state.configuration, authentication); - return (0, _Client.req)('PATCH', { + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio4 = (_params7 = params) === null || _params7 === void 0 ? void 0 : _params7.authentication) !== null && _params$authenticatio4 !== void 0 ? _params$authenticatio4 : (_params8 = params) === null || _params8 === void 0 ? void 0 : _params8.auth); + const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, - query, - body, - formData, - options, - auth, - headers, - ...rest - }).then(response => { - const nextState = (0, _languageCommon.composeNextState)(state, response); + auth + }); + return _languageCommon.http.patch(config)(state).then(response => { + const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/src/Adaptor.js b/src/Adaptor.js index bbb8a9b..b27f5f9 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -212,17 +212,6 @@ export function post(path, params, callback) { */ export function put(path, params, callback) { return state => { - // const url = setUrl(state.configuration, path); - - // const { - // query, - // headers, - // authentication, - // body, - // formData, - // options, - // ...rest - // } = expandReferences(params)(state); path = expandReferences(path)(state); params = expandReferences(params)(state); @@ -269,34 +258,28 @@ export function put(path, params, callback) { */ export function patch(path, params, callback) { return state => { + path = expandReferences(path)(state); + + params = expandReferences(params)(state); + + console.log('params', params); + const url = setUrl(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = expandReferences(params)(state); + const auth = setAuth( + state.configuration, + params?.authentication ?? params?.auth + ); - const auth = setAuth(state.configuration, authentication); + const config = mapToAxiosConfig({ ...params, url, auth }); - return req('PATCH', { - url, - query, - body, - formData, - options, - auth, - headers, - ...rest, - }).then(response => { - const nextState = composeNextState(state, response); - if (callback) return callback(nextState); - return nextState; - }); + return http + .patch(config)(state) + .then(response => { + const nextState = composeNextState(state, response.data); + if (callback) return callback(nextState); + return nextState; + }); }; } diff --git a/test/index.js b/test/index.js index ef30766..176f158 100644 --- a/test/index.js +++ b/test/index.js @@ -500,7 +500,7 @@ describe('put', () => { }); }); - it.only('sends a put request', async () => { + it('sends a put request', async () => { const state = { configuration: {}, data: { name: 'New name' }, @@ -523,7 +523,7 @@ describe('patch', () => { }); }); - it('sends a patch request', async () => { + it.only('sends a patch request', async () => { const state = { configuration: {}, data: { name: 'New name', id: 6 }, From 329b2b481e62886e7da890bc72af7adb176033c9 Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Wed, 20 Jan 2021 23:12:46 +0200 Subject: [PATCH 17/20] Validating Tests: sends a delete request, partial pass blocked by expandReferences failing on empty objects such as {} and [], for #14 --- lib/Adaptor.js | 45 +++++++++++------------------------ lib/Utils.js | 3 ++- src/Adaptor.js | 64 +++++++++++++++++++------------------------------- src/Utils.js | 3 ++- test/index.js | 11 +++++---- 5 files changed, 49 insertions(+), 77 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 2db3316..48b8677 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -88,17 +88,6 @@ var _toughCookie = _interopRequireDefault(require("tough-cookie")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @module Adaptor */ -// KEEP THIS HERE FOR NOTES -// const { -// query, -// headers, -// authentication, -// body, -// formData, -// options, -// ...rest -// } = expandReferences(params)(state); -// return req('GET', { url, query, auth, headers, options, ...rest }).then( /** * Execute a sequence of operations. @@ -138,6 +127,7 @@ _http.__axios.interceptors.request.use(function (config) { _http.__axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; + console.log('Res from axios', response); if (response.headers['set-cookie']) { var _response$headers$set, _response$headers$set2; @@ -349,28 +339,21 @@ function patch(path, params, callback) { function del(path, params, callback) { return state => { + var _params$authenticatio5; + + // path = recursivelyExpandReferences(path)(state); + // params = recursivelyExpandReferences(params)(state); + console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = (0, _languageCommon.expandReferences)(params)(state); - const auth = (0, _Utils.setAuth)(state.configuration, authentication); - return (0, _Client.req)('DELETE', { + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio5 = params === null || params === void 0 ? void 0 : params.authentication) !== null && _params$authenticatio5 !== void 0 ? _params$authenticatio5 : params === null || params === void 0 ? void 0 : params.auth); + const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, - query, - body, - formData, - options, - auth, - headers, - ...rest - }).then(response => { - const nextState = (0, _languageCommon.composeNextState)(state, response); + auth + }); + console.log('config', config); + return _languageCommon.http.delete(config)(state).then(response => { + console.log('res', response); + const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; }); diff --git a/lib/Utils.js b/lib/Utils.js index f4247bd..4915014 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -58,7 +58,7 @@ function mapToAxiosConfig(requestConfig) { var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed; console.log('rawRequestconfig', requestConfig); - const form = new _formData.default(); + let form = null; const formData = (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form); let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; @@ -69,6 +69,7 @@ function mapToAxiosConfig(requestConfig) { } if (formData) { + form = new _formData.default(); Object.entries(requestConfig.formData).forEach(element => { form.append(element[0], element[1]); }); diff --git a/src/Adaptor.js b/src/Adaptor.js index b27f5f9..53946b3 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -20,19 +20,6 @@ import parse from 'csv-parse'; import { __axios } from 'language-common/lib/http'; import tough from 'tough-cookie'; -// KEEP THIS HERE FOR NOTES -// const { -// query, -// headers, -// authentication, -// body, -// formData, -// options, -// ...rest -// } = expandReferences(params)(state); - -// return req('GET', { url, query, auth, headers, options, ...rest }).then( - /** * Execute a sequence of operations. * Wraps `language-common/execute`, and prepends initial state for http. @@ -70,7 +57,7 @@ __axios.interceptors.request.use(function (config) { __axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; - + console.log('Res from axios', response); if (response.headers['set-cookie']) { if (response.headers['set-cookie'] instanceof Array) cookies = response.headers['set-cookie']?.map(Cookie.parse); @@ -304,34 +291,31 @@ export function patch(path, params, callback) { */ export function del(path, params, callback) { return state => { + // path = recursivelyExpandReferences(path)(state); + + // params = recursivelyExpandReferences(params)(state); + + console.log('params', params); + const url = setUrl(state.configuration, path); - const { - query, - headers, - authentication, - body, - formData, - options, - ...rest - } = expandReferences(params)(state); - - const auth = setAuth(state.configuration, authentication); - - return req('DELETE', { - url, - query, - body, - formData, - options, - auth, - headers, - ...rest, - }).then(response => { - const nextState = composeNextState(state, response); - if (callback) return callback(nextState); - return nextState; - }); + const auth = setAuth( + state.configuration, + params?.authentication ?? params?.auth + ); + + const config = mapToAxiosConfig({ ...params, url, auth }); + + console.log('config', config); + + return http + .delete(config)(state) + .then(response => { + console.log('res', response); + const nextState = composeNextState(state, response.data); + if (callback) return callback(nextState); + return nextState; + }); }; } diff --git a/src/Utils.js b/src/Utils.js index e4d6ca9..d4ca9bb 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -42,7 +42,7 @@ export function tryJson(data) { export function mapToAxiosConfig(requestConfig) { console.log('rawRequestconfig', requestConfig); - const form = new FormData(); + let form = null; const formData = requestConfig?.formData || requestConfig?.form; @@ -53,6 +53,7 @@ export function mapToAxiosConfig(requestConfig) { } if (formData) { + form = new FormData(); Object.entries(requestConfig.formData).forEach(element => { form.append(element[0], element[1]); }); diff --git a/test/index.js b/test/index.js index 176f158..552ad80 100644 --- a/test/index.js +++ b/test/index.js @@ -523,7 +523,7 @@ describe('patch', () => { }); }); - it.only('sends a patch request', async () => { + it('sends a patch request', async () => { const state = { configuration: {}, data: { name: 'New name', id: 6 }, @@ -539,14 +539,17 @@ describe('patch', () => { }); }); +// TODO: FIX EXPAND REFRENCES LANGUAGE COMMON FOR NULLS,[],{}. +// Test only passes if expandReferences is commented out from del in language-common + describe('delete', () => { before(() => { testServer.delete('/api/fake-del-items/6').reply(204, function (url, body) { - return JSON.stringify({}); + return { ...body }; }); }); - it('sends a delete request', async () => { + it.only('sends a delete request', async () => { const state = { configuration: {}, data: {}, @@ -562,6 +565,6 @@ describe('delete', () => { // TODO: fix this interface, if `Utils.tryJson` cleanly converts the // response body, it won't be under the `body` key. See `put()` example // above where we have to look inside `data.body.body`. - expect(finalState.data).to.eql({}); + expect(finalState.data.body).to.eql({}); }); }); From 25bcaca0f1f5018b5227936fd1c681ed1bf091ad Mon Sep 17 00:00:00 2001 From: Chaiwa Berian Date: Thu, 21 Jan 2021 20:10:04 +0200 Subject: [PATCH 18/20] Upgrade to use axios interceptors and new language-common expandReferences, for #14 --- lib/Adaptor.js | 15 ++++----- lib/Utils.js | 7 ++--- package-lock.json | 4 +-- package.json | 2 +- src/Adaptor.js | 13 ++++---- src/Utils.js | 13 ++------ test/index.js | 78 ++++++++++++++++++++++++++++++----------------- 7 files changed, 73 insertions(+), 59 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 48b8677..218e00b 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -127,7 +127,10 @@ _http.__axios.interceptors.request.use(function (config) { _http.__axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; - console.log('Res from axios', response); + response = { ...response, + httpStatus: response.status, + message: response.statusText + }; if (response.headers['set-cookie']) { var _response$headers$set, _response$headers$set2; @@ -339,20 +342,18 @@ function patch(path, params, callback) { function del(path, params, callback) { return state => { - var _params$authenticatio5; + var _params$authenticatio5, _params9, _params10; - // path = recursivelyExpandReferences(path)(state); - // params = recursivelyExpandReferences(params)(state); + path = (0, _languageCommon.expandReferences)(path)(state); + params = (0, _languageCommon.expandReferences)(params)(state); console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); - const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio5 = params === null || params === void 0 ? void 0 : params.authentication) !== null && _params$authenticatio5 !== void 0 ? _params$authenticatio5 : params === null || params === void 0 ? void 0 : params.auth); + const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio5 = (_params9 = params) === null || _params9 === void 0 ? void 0 : _params9.authentication) !== null && _params$authenticatio5 !== void 0 ? _params$authenticatio5 : (_params10 = params) === null || _params10 === void 0 ? void 0 : _params10.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, auth }); - console.log('config', config); return _languageCommon.http.delete(config)(state).then(response => { - console.log('res', response); const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; diff --git a/lib/Utils.js b/lib/Utils.js index 4915014..406d8c5 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -57,7 +57,6 @@ function tryJson(data) { function mapToAxiosConfig(requestConfig) { var _requestConfig$url, _requestConfig$data, _requestConfig$auth, _requestConfig$respon, _requestConfig$respon2, _requestConfig$maxRed; - console.log('rawRequestconfig', requestConfig); let form = null; const formData = (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.formData) || (requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.form); let headers = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.headers; @@ -68,19 +67,17 @@ function mapToAxiosConfig(requestConfig) { }; } - if (formData) { + if (!(0, _fp.isEmpty)(formData)) { form = new _formData.default(); - Object.entries(requestConfig.formData).forEach(element => { + Object.entries(formData).forEach(element => { form.append(element[0], element[1]); }); const formHeaders = form.getHeaders(); - console.log('formHeaders', formHeaders); headers = { ...headers, ...formHeaders }; } - console.log('form', form); return { ...requestConfig, url: (_requestConfig$url = requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.url) !== null && _requestConfig$url !== void 0 ? _requestConfig$url : requestConfig === null || requestConfig === void 0 ? void 0 : requestConfig.uri, // method, diff --git a/package-lock.json b/package-lock.json index 3c5c3fd..6394c04 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2796,8 +2796,8 @@ "optional": true }, "language-common": { - "version": "github:openfn/language-common#a99164fb28ad5794230680f4a45c3c39dce1d2ac", - "from": "github:openfn/language-common#export_axios", + "version": "github:openfn/language-common#ecbfa9fcad883a6eb0fbfcccc43e976a9107779e", + "from": "github:openfn/language-common#master", "requires": { "axios": "^0.21.1", "jsonpath-plus": "^4.0.0", diff --git a/package.json b/package.json index 912e674..7d6c925 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,7 @@ "csv-parse": "^4.10.1", "form-data": "^3.0.0", "import": "0.0.6", - "language-common": "github:openfn/language-common#export_axios", + "language-common": "github:openfn/language-common#master", "request": "^2.72.0", "tough-cookie": "^4.0.0", "lodash": "^4.17.19" diff --git a/src/Adaptor.js b/src/Adaptor.js index 53946b3..28e46f1 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -57,7 +57,11 @@ __axios.interceptors.request.use(function (config) { __axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; - console.log('Res from axios', response); + response = { + ...response, + httpStatus: response.status, + message: response.statusText, + }; if (response.headers['set-cookie']) { if (response.headers['set-cookie'] instanceof Array) cookies = response.headers['set-cookie']?.map(Cookie.parse); @@ -291,9 +295,9 @@ export function patch(path, params, callback) { */ export function del(path, params, callback) { return state => { - // path = recursivelyExpandReferences(path)(state); + path = expandReferences(path)(state); - // params = recursivelyExpandReferences(params)(state); + params = expandReferences(params)(state); console.log('params', params); @@ -306,12 +310,9 @@ export function del(path, params, callback) { const config = mapToAxiosConfig({ ...params, url, auth }); - console.log('config', config); - return http .delete(config)(state) .then(response => { - console.log('res', response); const nextState = composeNextState(state, response.data); if (callback) return callback(nextState); return nextState; diff --git a/src/Utils.js b/src/Utils.js index d4ca9bb..3e668f7 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,6 +1,6 @@ import { head } from 'language-common/lib/http'; import FormData from 'form-data'; -import { mapValues } from 'lodash/fp'; +import { mapValues, isEmpty } from 'lodash/fp'; export function setUrl(configuration, path) { if (configuration && configuration.baseUrl) @@ -40,8 +40,6 @@ export function tryJson(data) { } export function mapToAxiosConfig(requestConfig) { - console.log('rawRequestconfig', requestConfig); - let form = null; const formData = requestConfig?.formData || requestConfig?.form; @@ -51,22 +49,17 @@ export function mapToAxiosConfig(requestConfig) { if (requestConfig?.gzip === true) { headers = { ...headers, 'Accept-Encoding': 'gzip, deflate' }; } - - if (formData) { + if (!isEmpty(formData)) { form = new FormData(); - Object.entries(requestConfig.formData).forEach(element => { + Object.entries(formData).forEach(element => { form.append(element[0], element[1]); }); const formHeaders = form.getHeaders(); - console.log('formHeaders', formHeaders); - headers = { ...headers, ...formHeaders }; } - console.log('form', form); - return { ...requestConfig, url: requestConfig?.url ?? requestConfig?.uri, diff --git a/test/index.js b/test/index.js index 552ad80..e0153b0 100644 --- a/test/index.js +++ b/test/index.js @@ -1,8 +1,6 @@ import Adaptor from '../src'; import { expect } from 'chai'; import nock from 'nock'; -// import { FormData } from 'form-data'; -// var FormData = require('form-data'); const { execute, get, post, put, patch, del, alterState } = Adaptor; @@ -10,7 +8,7 @@ function stdGet(state) { return execute(get('https://www.example.com/api/fake', {}))(state).then( nextState => { const { data, references } = nextState; - expect(data).to.eql({ httpStatus: 'OK', message: 'the response' }); + expect(data.body).to.eql({ httpStatus: 'OK', message: 'the response' }); expect(references).to.eql([{ triggering: 'event' }]); } ); @@ -20,7 +18,7 @@ function clientReq(method, state) { return execute(method('https://www.example.com/api/fake', {}))(state).then( nextState => { const { data, references } = nextState; - expect(data).to.eql({ httpStatus: 'OK', message: 'the response' }); + expect(data.body).to.eql({ httpStatus: 'OK', message: 'the response' }); expect(references).to.eql([{ a: 1 }]); } ); @@ -101,7 +99,7 @@ describe('The get() function', () => { }) )(state).then(nextState => { const { data, references, counter } = nextState; - expect(data).to.eql({ httpStatus: 'OK', message: 'the response' }); + expect(data.body).to.eql({ httpStatus: 'OK', message: 'the response' }); expect(references).to.eql([{ triggering: 'event' }]); expect(counter).to.eql(2); }); @@ -262,16 +260,20 @@ describe('get', () => { }) )(state); - expect(finalState.data[0]).to.eql('/api/fake'); + console.log('finalState', finalState); + expect(finalState.data.body[0]).to.eql('/api/fake'); - expect(finalState.data[1]).to.haveOwnProperty('x-openfn', 'testing'); + expect(finalState.data.body[1]).to.haveOwnProperty('x-openfn', 'testing'); - expect(finalState.data[1]).to.haveOwnProperty( + expect(finalState.data.body[1]).to.haveOwnProperty( 'authorization', 'Basic aGVsbG86dGhlcmU=' ); - expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); + expect(finalState.data.body[1]).to.haveOwnProperty( + 'host', + 'www.example.com' + ); expect(finalState.references).to.eql([{ triggering: 'event' }]); }); @@ -289,14 +291,17 @@ describe('get', () => { state ); - expect(finalState.data[0]).to.eql('/api/fake'); + expect(finalState.data.body[0]).to.eql('/api/fake'); - expect(finalState.data[1]).to.haveOwnProperty( + expect(finalState.data.body[1]).to.haveOwnProperty( 'authorization', 'Basic aGVsbG86dGhlcmU=' ); - expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); + expect(finalState.data.body[1]).to.haveOwnProperty( + 'host', + 'www.example.com' + ); }); it('can enable gzip', async () => { @@ -309,14 +314,17 @@ describe('get', () => { get('https://www.example.com/api/fake', { gzip: true }) )(state); - expect(finalState.data[0]).to.eql('/api/fake'); + expect(finalState.data.body[0]).to.eql('/api/fake'); - expect(finalState.data[1]).to.haveOwnProperty( + expect(finalState.data.body[1]).to.haveOwnProperty( 'accept-encoding', 'gzip, deflate' ); - expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); + expect(finalState.data.body[1]).to.haveOwnProperty( + 'host', + 'www.example.com' + ); }); it('allows query strings to be set', async () => { @@ -329,9 +337,12 @@ describe('get', () => { get('https://www.example.com/api/fake', { query: { id: 1 } }) )(state); - expect(finalState.data[0]).to.eql('/api/fake?id=1'); + expect(finalState.data.body[0]).to.eql('/api/fake?id=1'); - expect(finalState.data[1]).to.haveOwnProperty('host', 'www.example.com'); + expect(finalState.data.body[1]).to.haveOwnProperty( + 'host', + 'www.example.com' + ); }); it('can follow redirects', async () => { @@ -436,14 +447,18 @@ describe('post', () => { const finalState = await execute( post('https://www.example.com/api/fake-form', { - form: state.data, + form: state => { + return state.data; + }, }) )(state); - expect(finalState.data.body).to.eql({ - username: 'fake', - password: 'fake_pass', - }); + expect(finalState.data.body).to.contain( + 'Content-Disposition: form-data; name="username"\r\n\r\n' + ); + expect(finalState.data.body).to.contain( + 'Content-Disposition: form-data; name="password"\r\n\r\n' + ); }); it('can set FormData on the request body', async () => { @@ -466,23 +481,30 @@ describe('post', () => { }, }) )(state); - console.log('finalState', finalState); - // expect(finalState.data.body).to.contain('Content-Disposition: form-data'); + console.log('typeof', typeof finalState.data.body); + console.log('finalState', finalState.data.body); + + expect(finalState.data.body).to.contain( + 'Content-Disposition: form-data; name="username"\r\n\r\n' + ); + expect(finalState.data.body).to.contain( + 'Content-Disposition: form-data; name="password"\r\n\r\n' + ); }); it('can set successCodes on the request', async () => { - let formData = { + let data = { id: 'fake_id', parent: 'fake_parent', mobile_phone: 'fake_phone', }; const state = { configuration: {}, - data: formData, + data, }; const finalState = await execute( post('https://www.example.com/api/fake-custom-success-codes', { - body: state => { + data: state => { return state.data; }, options: { successCodes: [302] }, @@ -549,7 +571,7 @@ describe('delete', () => { }); }); - it.only('sends a delete request', async () => { + it('sends a delete request', async () => { const state = { configuration: {}, data: {}, From c0cbcc19ca33c7e3aa0d43561026ca7a13a8bd54 Mon Sep 17 00:00:00 2001 From: Taylor Downs Date: Fri, 22 Jan 2021 10:48:45 +0000 Subject: [PATCH 19/20] use new common, remove logs to avoid exposing sensitive data --- lib/Adaptor.js | 22 ++++----- lib/Utils.js | 2 - package-lock.json | 115 +++++++++++++++++++++++----------------------- package.json | 6 +-- src/Adaptor.js | 35 ++++---------- src/Utils.js | 1 - test/index.js | 3 -- 7 files changed, 77 insertions(+), 107 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 218e00b..592cc70 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -71,7 +71,7 @@ var _Client = require("./Client"); var _Utils = require("./Utils"); -var _languageCommon = require("language-common"); +var _languageCommon = require("@openfn/language-common"); var _cheerio = _interopRequireDefault(require("cheerio")); @@ -81,14 +81,15 @@ var _fs = _interopRequireDefault(require("fs")); var _csvParse = _interopRequireDefault(require("csv-parse")); -var _http = require("language-common/lib/http"); - var _toughCookie = _interopRequireDefault(require("tough-cookie")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** @module Adaptor */ - +const { + axios +} = _languageCommon.http; +exports.axios = axios; /** * Execute a sequence of operations. * Wraps `language-common/execute`, and prepends initial state for http. @@ -101,6 +102,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @param {Operations} operations - Operations to be performed. * @returns {Operation} */ + function execute(...operations) { const initialState = { references: [], @@ -116,15 +118,13 @@ function execute(...operations) { var Cookie = _toughCookie.default.Cookie; var cookiejar = new _toughCookie.default.CookieJar(); - -_http.__axios.interceptors.request.use(function (config) { +axios.interceptors.request.use(function (config) { cookiejar === null || cookiejar === void 0 ? void 0 : cookiejar.getCookies(config.url, function (err, cookies) { config.headers.cookie = cookies === null || cookies === void 0 ? void 0 : cookies.join('; '); }); return config; }); - -_http.__axios.interceptors.response.use(function (response) { +axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; response = { ...response, @@ -175,14 +175,12 @@ _http.__axios.interceptors.response.use(function (response) { * @returns {Operation} */ - function get(path, params, callback) { return state => { var _params$authenticatio, _params, _params2; path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); - console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio = (_params = params) === null || _params === void 0 ? void 0 : _params.authentication) !== null && _params$authenticatio !== void 0 ? _params$authenticatio : (_params2 = params) === null || _params2 === void 0 ? void 0 : _params2.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, @@ -223,7 +221,6 @@ function post(path, params, callback) { path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); - console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio2 = (_params3 = params) === null || _params3 === void 0 ? void 0 : _params3.authentication) !== null && _params$authenticatio2 !== void 0 ? _params$authenticatio2 : (_params4 = params) === null || _params4 === void 0 ? void 0 : _params4.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, @@ -264,7 +261,6 @@ function put(path, params, callback) { path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); - console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio3 = (_params5 = params) === null || _params5 === void 0 ? void 0 : _params5.authentication) !== null && _params$authenticatio3 !== void 0 ? _params$authenticatio3 : (_params6 = params) === null || _params6 === void 0 ? void 0 : _params6.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, @@ -305,7 +301,6 @@ function patch(path, params, callback) { path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); - console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio4 = (_params7 = params) === null || _params7 === void 0 ? void 0 : _params7.authentication) !== null && _params$authenticatio4 !== void 0 ? _params$authenticatio4 : (_params8 = params) === null || _params8 === void 0 ? void 0 : _params8.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, @@ -346,7 +341,6 @@ function del(path, params, callback) { path = (0, _languageCommon.expandReferences)(path)(state); params = (0, _languageCommon.expandReferences)(params)(state); - console.log('params', params); const url = (0, _Utils.setUrl)(state.configuration, path); const auth = (0, _Utils.setAuth)(state.configuration, (_params$authenticatio5 = (_params9 = params) === null || _params9 === void 0 ? void 0 : _params9.authentication) !== null && _params$authenticatio5 !== void 0 ? _params$authenticatio5 : (_params10 = params) === null || _params10 === void 0 ? void 0 : _params10.auth); const config = (0, _Utils.mapToAxiosConfig)({ ...params, diff --git a/lib/Utils.js b/lib/Utils.js index 406d8c5..1a274c1 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -10,8 +10,6 @@ exports.tryJson = tryJson; exports.mapToAxiosConfig = mapToAxiosConfig; exports.recursivelyExpandReferences = recursivelyExpandReferences; -var _http = require("language-common/lib/http"); - var _formData = _interopRequireDefault(require("form-data")); var _fp = require("lodash/fp"); diff --git a/package-lock.json b/package-lock.json index 6394c04..0bc7e13 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { - "name": "language-http", - "version": "2.4.15", + "name": "@openfn/language-http", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1153,6 +1153,16 @@ "upath": "^1.1.1" } }, + "@openfn/language-common": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@openfn/language-common/-/language-common-1.1.0.tgz", + "integrity": "sha512-Zp33QK+3rRXsMTwfsQwWt4m8SZY3kMO19YhxNRUT6nxiaxDGt2eu6+qLcxbzh/sxZbzFn4dDtFrzw2wc4a8dyw==", + "requires": { + "axios": "^0.21.1", + "jsonpath-plus": "^4.0.0", + "lodash": "^4.17.19" + } + }, "@sinonjs/commons": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", @@ -1252,7 +1262,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", "dev": true, "optional": true }, @@ -1286,7 +1296,7 @@ "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "integrity": "sha1-5gtrDo8wG9l+U3UhW9pAbIURjAs=", "dev": true }, "assign-symbols": { @@ -1299,7 +1309,7 @@ "async-each": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "integrity": "sha1-tyfb+H12UWAvBvTUrDh/R9kbDL8=", "dev": true, "optional": true }, @@ -1311,7 +1321,7 @@ "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "integrity": "sha1-bZUX654DDSQ2ZmZR6GvZ9vE1M8k=", "dev": true, "optional": true }, @@ -1351,7 +1361,7 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "optional": true, "requires": { @@ -1377,7 +1387,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "optional": true, "requires": { @@ -1387,7 +1397,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "optional": true, "requires": { @@ -1397,7 +1407,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "optional": true, "requires": { @@ -1419,7 +1429,7 @@ "binary-extensions": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "integrity": "sha1-WYr+VHVbKGilMw0q/51Ou1Mgm2U=", "dev": true, "optional": true }, @@ -1496,7 +1506,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "optional": true, "requires": { @@ -1684,7 +1694,7 @@ "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", "dev": true, "optional": true, "requires": { @@ -1794,7 +1804,7 @@ "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "integrity": "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=", "dev": true, "optional": true }, @@ -1875,7 +1885,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "optional": true, "requires": { @@ -1916,7 +1926,7 @@ "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", "dev": true, "optional": true, "requires": { @@ -1927,7 +1937,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "optional": true, "requires": { @@ -1937,7 +1947,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "optional": true, "requires": { @@ -1947,7 +1957,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "optional": true, "requires": { @@ -2101,7 +2111,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "optional": true, "requires": { @@ -2298,7 +2308,7 @@ "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "integrity": "sha1-4y/AMKLM7kSmtTcTCNpUvgs5fSc=", "dev": true }, "fs.realpath": { @@ -2569,7 +2579,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", "dev": true, "optional": true }, @@ -2604,7 +2614,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "optional": true, "requires": { @@ -2616,7 +2626,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true, "optional": true } @@ -2677,7 +2687,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "optional": true, "requires": { @@ -2701,7 +2711,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true, "optional": true }, @@ -2795,15 +2805,6 @@ "dev": true, "optional": true }, - "language-common": { - "version": "github:openfn/language-common#ecbfa9fcad883a6eb0fbfcccc43e976a9107779e", - "from": "github:openfn/language-common#master", - "requires": { - "axios": "^0.21.1", - "jsonpath-plus": "^4.0.0", - "lodash": "^4.17.19" - } - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -2975,7 +2976,7 @@ "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "integrity": "sha1-ESC0PcNZp4Xc5ltVuC4lfM9HlWY=", "dev": true, "optional": true, "requires": { @@ -2986,7 +2987,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "optional": true, "requires": { @@ -3206,7 +3207,7 @@ "nanomatch": { "version": "1.2.13", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "integrity": "sha1-uHqKpPwN6P5r6IiVs4mD/yZb0Rk=", "dev": true, "optional": true, "requires": { @@ -3657,14 +3658,14 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", "dev": true, "optional": true }, "propagate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz", - "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", + "integrity": "sha1-QM3tqxgIXHkjNOZPCsFyVtOPmkU=", "dev": true }, "psl": { @@ -3695,7 +3696,7 @@ "readdirp": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "integrity": "sha1-DodiKjMlqjPokihcr4tOhGUppSU=", "dev": true, "optional": true, "requires": { @@ -3723,7 +3724,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "optional": true, "requires": { @@ -3750,7 +3751,7 @@ "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", "dev": true, "optional": true, "requires": { @@ -3768,7 +3769,7 @@ "repeat-element": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "integrity": "sha1-eC4NglwMWjuzlzH4Tv7mt0Lmsc4=", "dev": true, "optional": true }, @@ -3863,7 +3864,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", "dev": true, "optional": true }, @@ -3902,7 +3903,7 @@ "set-value": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "integrity": "sha1-oY1AUw5vB95CKMfe/kInr4ytAFs=", "dev": true, "optional": true, "requires": { @@ -3955,7 +3956,7 @@ "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", "dev": true, "optional": true, "requires": { @@ -3994,7 +3995,7 @@ "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "optional": true, "requires": { @@ -4016,7 +4017,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "optional": true, "requires": { @@ -4026,7 +4027,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "optional": true, "requires": { @@ -4036,7 +4037,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "optional": true, "requires": { @@ -4050,7 +4051,7 @@ "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "optional": true, "requires": { @@ -4099,7 +4100,7 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "optional": true, "requires": { @@ -4495,7 +4496,7 @@ "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", "dev": true, "optional": true, "requires": { @@ -4576,7 +4577,7 @@ "union-value": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "integrity": "sha1-C2/nuDWuzaYcbqTU8CwUIh4QmEc=", "dev": true, "optional": true, "requires": { @@ -4638,7 +4639,7 @@ "upath": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", - "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "integrity": "sha1-j2bbzVWog6za5ECK+LA1pQRMGJQ=", "dev": true, "optional": true }, @@ -4660,7 +4661,7 @@ "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "integrity": "sha1-1QyMrHmhn7wg8pEfVuuXP04QBw8=", "dev": true, "optional": true }, diff --git a/package.json b/package.json index 7d6c925..69fa896 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "language-http", - "version": "2.4.15", + "name": "@openfn/language-http", + "version": "3.0.0", "description": "An HTTP request language package for use with Open Function", "main": "lib/index.js", "scripts": { @@ -14,12 +14,12 @@ "lib/" ], "dependencies": { + "@openfn/language-common": "1.1.0", "cheerio": "^1.0.0-rc.3", "cheerio-tableparser": "^1.0.1", "csv-parse": "^4.10.1", "form-data": "^3.0.0", "import": "0.0.6", - "language-common": "github:openfn/language-common#master", "request": "^2.72.0", "tough-cookie": "^4.0.0", "lodash": "^4.17.19" diff --git a/src/Adaptor.js b/src/Adaptor.js index 28e46f1..c9de949 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -1,25 +1,21 @@ /** @module Adaptor */ import { req, rawRequest } from './Client'; -import { - setAuth, - setUrl, - mapToAxiosConfig, - tryJson, - recursivelyExpandReferences, -} from './Utils'; +import { setAuth, setUrl, mapToAxiosConfig, tryJson } from './Utils'; import { execute as commonExecute, expandReferences, composeNextState, http, -} from 'language-common'; +} from '@openfn/language-common'; import cheerio from 'cheerio'; import cheerioTableparser from 'cheerio-tableparser'; import fs from 'fs'; import parse from 'csv-parse'; -import { __axios } from 'language-common/lib/http'; import tough from 'tough-cookie'; +const { axios } = http; +exports.axios = axios; + /** * Execute a sequence of operations. * Wraps `language-common/execute`, and prepends initial state for http. @@ -47,14 +43,14 @@ export function execute(...operations) { var Cookie = tough.Cookie; var cookiejar = new tough.CookieJar(); -__axios.interceptors.request.use(function (config) { +axios.interceptors.request.use(function (config) { cookiejar?.getCookies(config.url, function (err, cookies) { config.headers.cookie = cookies?.join('; '); }); return config; }); -__axios.interceptors.response.use(function (response) { +axios.interceptors.response.use(function (response) { let cookies; let keepCookies = []; response = { @@ -112,11 +108,8 @@ __axios.interceptors.response.use(function (response) { export function get(path, params, callback) { return state => { path = expandReferences(path)(state); - params = expandReferences(params)(state); - console.log('params', params); - const url = setUrl(state.configuration, path); const auth = setAuth( @@ -158,11 +151,8 @@ export function get(path, params, callback) { export function post(path, params, callback) { return state => { path = expandReferences(path)(state); - params = expandReferences(params)(state); - console.log('params', params); - const url = setUrl(state.configuration, path); const auth = setAuth( @@ -204,11 +194,8 @@ export function post(path, params, callback) { export function put(path, params, callback) { return state => { path = expandReferences(path)(state); - params = expandReferences(params)(state); - console.log('params', params); - const url = setUrl(state.configuration, path); const auth = setAuth( @@ -250,11 +237,8 @@ export function put(path, params, callback) { export function patch(path, params, callback) { return state => { path = expandReferences(path)(state); - params = expandReferences(params)(state); - console.log('params', params); - const url = setUrl(state.configuration, path); const auth = setAuth( @@ -296,11 +280,8 @@ export function patch(path, params, callback) { export function del(path, params, callback) { return state => { path = expandReferences(path)(state); - params = expandReferences(params)(state); - console.log('params', params); - const url = setUrl(state.configuration, path); const auth = setAuth( @@ -425,4 +406,4 @@ export { lastReferenceValue, merge, sourceValue, -} from 'language-common'; +} from '@openfn/language-common'; diff --git a/src/Utils.js b/src/Utils.js index 3e668f7..d71e744 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -1,4 +1,3 @@ -import { head } from 'language-common/lib/http'; import FormData from 'form-data'; import { mapValues, isEmpty } from 'lodash/fp'; diff --git a/test/index.js b/test/index.js index e0153b0..a5a09cc 100644 --- a/test/index.js +++ b/test/index.js @@ -260,7 +260,6 @@ describe('get', () => { }) )(state); - console.log('finalState', finalState); expect(finalState.data.body[0]).to.eql('/api/fake'); expect(finalState.data.body[1]).to.haveOwnProperty('x-openfn', 'testing'); @@ -481,8 +480,6 @@ describe('post', () => { }, }) )(state); - console.log('typeof', typeof finalState.data.body); - console.log('finalState', finalState.data.body); expect(finalState.data.body).to.contain( 'Content-Disposition: form-data; name="username"\r\n\r\n' From 6be6ce59e09a71444c5e80695e628b083491f67b Mon Sep 17 00:00:00 2001 From: Taylor Downs Date: Sat, 23 Jan 2021 13:23:51 +0000 Subject: [PATCH 20/20] fix formData submissions by calling axios directly --- lib/Adaptor.js | 9 +++++++-- src/Adaptor.js | 16 +++++++++------- test/index.js | 11 +++++++---- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/lib/Adaptor.js b/lib/Adaptor.js index 592cc70..011c3fc 100644 --- a/lib/Adaptor.js +++ b/lib/Adaptor.js @@ -226,8 +226,13 @@ function post(path, params, callback) { const config = (0, _Utils.mapToAxiosConfig)({ ...params, url, auth - }); - return _languageCommon.http.post(config)(state).then(response => { + }); // NOTE: that in order to use multipart/form submissions, we call axios.post + // directly so as to avoid calling 'expandReferences' on the config (in + // language-common.http.post) once we've set up the 'form-data' module. + // Elsewhere, calling expandReferences multiple times is harmless. + + return axios.post(config.url, config.data, { ...config + }).then(response => { const nextState = (0, _languageCommon.composeNextState)(state, response.data); if (callback) return callback(nextState); return nextState; diff --git a/src/Adaptor.js b/src/Adaptor.js index c9de949..4a70732 100644 --- a/src/Adaptor.js +++ b/src/Adaptor.js @@ -162,13 +162,15 @@ export function post(path, params, callback) { const config = mapToAxiosConfig({ ...params, url, auth }); - return http - .post(config)(state) - .then(response => { - const nextState = composeNextState(state, response.data); - if (callback) return callback(nextState); - return nextState; - }); + // NOTE: that in order to use multipart/form submissions, we call axios.post + // directly so as to avoid calling 'expandReferences' on the config (in + // language-common.http.post) once we've set up the 'form-data' module. + // Elsewhere, calling expandReferences multiple times is harmless. + return axios.post(config.url, config.data, { ...config }).then(response => { + const nextState = composeNextState(state, response.data); + if (callback) return callback(nextState); + return nextState; + }); }; } diff --git a/test/index.js b/test/index.js index a5a09cc..d61c3a4 100644 --- a/test/index.js +++ b/test/index.js @@ -453,10 +453,10 @@ describe('post', () => { )(state); expect(finalState.data.body).to.contain( - 'Content-Disposition: form-data; name="username"\r\n\r\n' + 'Content-Disposition: form-data; name="username"\r\n\r\nfake' ); expect(finalState.data.body).to.contain( - 'Content-Disposition: form-data; name="password"\r\n\r\n' + 'Content-Disposition: form-data; name="password"\r\n\r\nfake_pass' ); }); @@ -482,10 +482,13 @@ describe('post', () => { )(state); expect(finalState.data.body).to.contain( - 'Content-Disposition: form-data; name="username"\r\n\r\n' + 'Content-Disposition: form-data; name="id"\r\n\r\nfake_id' ); expect(finalState.data.body).to.contain( - 'Content-Disposition: form-data; name="password"\r\n\r\n' + 'Content-Disposition: form-data; name="parent"\r\n\r\nfake_parent' + ); + expect(finalState.data.body).to.contain( + 'Content-Disposition: form-data; name="mobile_phone"\r\n\r\nfake_phone' ); });