diff --git a/.eslintrc.js b/.eslintrc.js index d1e97bd..8f2667f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,5 +13,8 @@ 'use strict'; module.exports = { - "extends": "@adobe/eslint-config-asset-compute" + "extends": "@adobe/eslint-config-asset-compute", + "parserOptions": { + "ecmaVersion": 12 + }, }; diff --git a/.gitignore b/.gitignore index 0e45a17..6c08383 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,9 @@ typings/ .vscode !.vscode/launch.json +# Webstorm +.idea + # serverless .serverless/action.zip .webpack diff --git a/index.js b/index.js index 722ac72..f58fb97 100644 --- a/index.js +++ b/index.js @@ -12,8 +12,6 @@ 'use strict'; const AbortController = require('abort-controller'); -const fetch = require('node-fetch'); -const {FetchError} = fetch; /** * Retry @@ -137,7 +135,7 @@ function checkParameters(retryOptions) { * Fetch retry that wraps around `node-fetch` library * @param {String} url request url * @param {Options} options options for fetch request (e.g. headers, RetryOptions for retries or `false` if no do not want to perform retries) - * @returns {Object} json response of calling fetch + * @returns {Object} json response of calling fetch */ module.exports = async function (url, options) { options = options || {}; @@ -157,7 +155,7 @@ module.exports = async function (url, options) { } try { - const response = await fetch(url, options); + const response = await import('node-fetch').then( ({ default: fetch }) => fetch(url, options)); clearTimeout(timeoutHandler); if (!retry(retryOptions, null, response)) { @@ -172,6 +170,7 @@ module.exports = async function (url, options) { if (!retry(retryOptions, error, null)) { if (error.name === 'AbortError') { + const FetchError = await import('node-fetch').then( ({ FetchError }) => FetchError); return reject(new FetchError(`network timeout at ${url}`, 'request-timeout')); } diff --git a/package-lock.json b/package-lock.json index 0ac623a..69a8fc7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -523,6 +523,12 @@ "universal-user-agent": "^6.0.0" }, "dependencies": { + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true + }, "universal-user-agent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", @@ -1272,6 +1278,11 @@ "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", "dev": true }, + "data-uri-to-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz", + "integrity": "sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==" + }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", @@ -2064,6 +2075,14 @@ "reusify": "^1.0.4" } }, + "fetch-blob": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.1.2.tgz", + "integrity": "sha512-hunJbvy/6OLjCD0uuhLdp0mMPzP/yd2ssd1t2FCJsaA7wkWhpbp9xfuNVpv7Ll4jFhzp6T4LAupSiV9uOeg0VQ==", + "requires": { + "web-streams-polyfill": "^3.0.3" + } + }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", @@ -3646,9 +3665,13 @@ } }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.0.0.tgz", + "integrity": "sha512-bKMI+C7/T/SPU1lKnbQbwxptpCrG9ashG+VkytmXCPZyuM9jB6VU+hY0oi4lC8LxTtAeWdckNCTa3nrGsAdA3Q==", + "requires": { + "data-uri-to-buffer": "^3.0.1", + "fetch-blob": "^3.1.2" + } }, "node-preload": { "version": "0.2.1", @@ -8833,6 +8856,12 @@ "agent-base": "5", "debug": "4" } + }, + "node-fetch": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", + "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "dev": true } } }, @@ -8901,6 +8930,15 @@ "readable-stream": "2 || 3" } }, + "timeout-signal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/timeout-signal/-/timeout-signal-1.1.0.tgz", + "integrity": "sha512-fuWY4tM1njcHCiOB7XkTmP0EOxzBkPbuQwPN+ZCzM6G0Tj4fMVgEffG/OPgiNUX48o+FhQEa2Oh4qjEDBCy5WQ==", + "dev": true, + "requires": { + "abort-controller": "^3.0.0" + } + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -9065,6 +9103,11 @@ "spdx-expression-parse": "^3.0.0" } }, + "web-streams-polyfill": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.1.0.tgz", + "integrity": "sha512-wO9r1YnYe7kFBLHyyVEhV1H8VRWoNiNnuP+v/HUUmSTaRF8F93Kmd3JMrETx0f11GXxRek6OcL2QtjFIdc5WYw==" + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", diff --git a/package.json b/package.json index 53dea8b..fb8c87e 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "abort-controller": "^3.0.0", - "node-fetch": "^2.6.1" + "node-fetch": "^3.0.0" }, "devDependencies": { "@adobe/eslint-config-asset-compute": "^1.3.1", @@ -24,7 +24,8 @@ "nock": "^13.0.4", "nyc": "^15.1.0", "rewire": "^5.0.0", - "semantic-release": "^17.2.1" + "semantic-release": "^17.2.1", + "timeout-signal": "^1.1.0" }, "keywords": [ "fetch", diff --git a/test/index.test.js b/test/index.test.js index 65453c8..65f662d 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -202,9 +202,9 @@ describe('test fetch retry', () => { .reply(200, { ok: true }); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, - { - method: 'GET', - headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } + { + method: 'GET', + headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } } ); assert.strictEqual(response.ok, true); @@ -217,9 +217,9 @@ describe('test fetch retry', () => { .reply(200, { ok: true }); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, - { - method: 'GET', - headers: { Authorization: 'Bearer thisShouldBeAToken' } + { + method: 'GET', + headers: { Authorization: 'Bearer thisShouldBeAToken' } } ); assert.strictEqual(response.ok, true); @@ -256,9 +256,9 @@ describe('test fetch retry', () => { .reply(401, { ok: false }); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, - { - method: 'GET', - headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } + { + method: 'GET', + headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } } ); assert.strictEqual(response.ok, false); @@ -269,7 +269,7 @@ describe('test fetch retry', () => { .get(FAKE_PATH) .reply(500); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET', retryOptions: false }); - assert.strictEqual(response.statusText, 'Internal Server Error'); + assert.strictEqual(response.statusText, ''); }); it('test get retry with default settings 500 then 200', async () => { @@ -283,7 +283,7 @@ describe('test fetch retry', () => { const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET' }); assert(nock.isDone()); assert(response.ok); - assert.strictEqual(response.statusText, 'OK'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 200); }); @@ -297,13 +297,13 @@ describe('test fetch retry', () => { .get(FAKE_PATH) .matchHeader('Authorization', 'Basic thisShouldBeAnAuthHeader') .reply(200, { ok: true }); - const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, - { - method: 'GET', headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } + const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, + { + method: 'GET', headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' } }); assert(nock.isDone()); assert(response.ok); - assert.strictEqual(response.statusText, 'OK'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 200); }); @@ -314,7 +314,7 @@ describe('test fetch retry', () => { const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET' }); assert(nock.isDone()); assert(!response.ok); - assert.strictEqual(response.statusText, 'Bad Request'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 400); }); @@ -325,7 +325,7 @@ describe('test fetch retry', () => { const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET' }); assert(nock.isDone()); assert(!response.ok); - assert.strictEqual(response.statusText, 'Not Found'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 404); }); @@ -336,7 +336,7 @@ describe('test fetch retry', () => { const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET' }); assert(nock.isDone()); assert(!response.ok); - assert.strictEqual(response.statusText, 'Multiple Choices'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 300); }); @@ -353,7 +353,7 @@ describe('test fetch retry', () => { .reply(200, { ok: true }); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { method: 'GET' }); assert(nock.isDone()); - assert.strictEqual(response.statusText, 'OK'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 200); }); @@ -388,7 +388,7 @@ describe('test fetch retry', () => { } }); assert(nock.isDone()); - assert.strictEqual(response.statusText, 'Not Found'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 404); }); @@ -406,7 +406,7 @@ describe('test fetch retry', () => { }); assert(!nock.isDone()); // should fail on first fetch call nock.cleanAll(); - assert.strictEqual(response.statusText, 'HTTP Version Not Supported'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 505); }); @@ -429,7 +429,7 @@ describe('test fetch retry', () => { } }); assert(nock.isDone()); - assert.strictEqual(response.statusText, 'OK'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 200); }); @@ -452,7 +452,7 @@ describe('test fetch retry', () => { } }); assert(!nock.isDone()); // nock should not have gotten all calls - assert.strictEqual(response.statusText, 'Unauthorized'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 401); // clean up nock @@ -470,7 +470,7 @@ describe('test fetch retry', () => { .reply(200); const response = await fetch(`${FAKE_BASE_URL}${FAKE_PATH}`, { - method: 'GET', + method: 'GET', headers: { Authorization: 'Basic thisShouldBeAnAuthHeader' }, @@ -483,7 +483,7 @@ describe('test fetch retry', () => { } }); assert(!nock.isDone()); // nock should not have gotten all calls - assert.strictEqual(response.statusText, 'Unauthorized'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 401); // clean up nock @@ -505,7 +505,7 @@ describe('test fetch retry', () => { }); assert(nock.isDone()); nock.cleanAll(); // clean persisted nock - assert.strictEqual(response.statusText, 'Not Found'); + assert.strictEqual(response.statusText, ''); assert.strictEqual(response.status, 404); }).timeout(3000);