diff --git a/CHANGES.txt b/CHANGES.txt index 958fc1951..4ec2538eb 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,6 @@ +10.25.0 (January 4, 2024) + - Updated SDK to support URLs without TLS protocol in NodeJS, to simplify proxy usage inside private networks. + 10.24.1 (December 12, 2023) - Updated SDK cache for browsers using localStorage, to clear cached feature flag definitions before initiating the synchronization process if the cache was previously synchronized with a different SDK key (i.e., a different environment) or different Split Filter criteria, to avoid using invalid cached data when the SDK is ready from cache. - Updated @splitsoftware/splitio-commons package to version 1.12.1. diff --git a/package-lock.json b/package-lock.json index 3bc281cea..db2985694 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,25 +1,25 @@ { "name": "@splitsoftware/splitio", - "version": "10.24.1", + "version": "10.25.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.24.1", + "version": "10.25.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.12.1", + "@splitsoftware/splitio-commons": "1.13.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", - "node-fetch": "^2.6.7", + "node-fetch": "^2.7.0", "unfetch": "^4.2.0" }, "devDependencies": { - "@types/node-fetch": "^2.5.12", + "@types/node-fetch": "^2.6.10", "@types/seedrandom": "^3.0.2", "copyfiles": "^2.4.1", "cross-env": "^7.0.3", @@ -874,9 +874,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.12.1.tgz", - "integrity": "sha512-EkCcqlYvVafazs9c5i+pmhf6rIyj3A70dqQ4U3BKE646t7tf6mxGzqZz1sAl540xNyYI7CA/iIqisEWvDtJc0A==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.13.0.tgz", + "integrity": "sha512-SCZv396jaoIGgs48FpgPaF5nBZ0Ka4BYj7wFu1bsGBhGhajR2bTQdDWDedQ/eVCljhHfo60W32X77UCzEcNq0Q==", "dependencies": { "tslib": "^2.3.1" }, @@ -985,13 +985,13 @@ "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==" }, "node_modules/@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.10.tgz", + "integrity": "sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==", "dev": true, "dependencies": { "@types/node": "*", - "form-data": "^3.0.0" + "form-data": "^4.0.0" } }, "node_modules/@types/seedrandom": { @@ -3386,9 +3386,9 @@ } }, "node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "dependencies": { "asynckit": "^0.4.0", @@ -4903,9 +4903,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -8446,9 +8446,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.12.1.tgz", - "integrity": "sha512-EkCcqlYvVafazs9c5i+pmhf6rIyj3A70dqQ4U3BKE646t7tf6mxGzqZz1sAl540xNyYI7CA/iIqisEWvDtJc0A==", + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.13.0.tgz", + "integrity": "sha512-SCZv396jaoIGgs48FpgPaF5nBZ0Ka4BYj7wFu1bsGBhGhajR2bTQdDWDedQ/eVCljhHfo60W32X77UCzEcNq0Q==", "requires": { "tslib": "^2.3.1" } @@ -8549,13 +8549,13 @@ "integrity": "sha512-LhFTglglr63mNXUSRYD8A+ZAIu5sFqNJ4Y2fPuY7UlrySJH87rRRlhtVmMHplmfk5WkoJGmDjE9oiTfyX94CpQ==" }, "@types/node-fetch": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.2.tgz", - "integrity": "sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A==", + "version": "2.6.10", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.10.tgz", + "integrity": "sha512-PPpPK6F9ALFTn59Ka3BaL+qGuipRfxNE8qVgkp0bVixeiR2c2/L+IVOiBdu9JhhT22sWnQEp6YyHGI2b2+CMcA==", "dev": true, "requires": { "@types/node": "*", - "form-data": "^3.0.0" + "form-data": "^4.0.0" } }, "@types/seedrandom": { @@ -10470,9 +10470,9 @@ } }, "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -11615,9 +11615,9 @@ } }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "requires": { "whatwg-url": "^5.0.0" }, diff --git a/package.json b/package.json index 686c6b397..73771f7b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.24.1", + "version": "10.25.0", "description": "Split SDK", "files": [ "README.md", @@ -40,20 +40,20 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.12.1", + "@splitsoftware/splitio-commons": "1.13.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", - "node-fetch": "^2.6.7", + "node-fetch": "^2.7.0", "unfetch": "^4.2.0" }, "optionalDependencies": { "eventsource": "^1.1.2" }, "devDependencies": { - "@types/node-fetch": "^2.5.12", + "@types/node-fetch": "^2.6.10", "@types/seedrandom": "^3.0.2", "copyfiles": "^2.4.1", "cross-env": "^7.0.3", diff --git a/src/platform/getFetch/__tests__/node.spec.js b/src/platform/getFetch/__tests__/node.spec.js index 144d8880c..e557f292c 100644 --- a/src/platform/getFetch/__tests__/node.spec.js +++ b/src/platform/getFetch/__tests__/node.spec.js @@ -1,8 +1,33 @@ import tape from 'tape-catch'; -import { getFetch } from '../node'; +import sinon from 'sinon'; +import { getFetch, __setFetch } from '../node'; -tape('getFetch returns node-fetch module in Node', assert => { - assert.equal(getFetch(), require('node-fetch')); +tape('getFetch returns a wrapped node-fetch module in Node', assert => { + assert.equal(typeof getFetch(), 'function'); + + assert.end(); +}); + +tape('getFetch passes an agent object to HTTPs requests', assert => { + const fetchMock = sinon.stub(); + __setFetch(fetchMock); + + const fetch = getFetch(); + + fetch('http://test.com'); + assert.true(fetchMock.calledWithExactly('http://test.com', { agent: undefined })); + + fetch('https-https://', { option: 'value' }); + assert.true(fetchMock.calledWithExactly('https-https://', { option: 'value', agent: undefined })); + + fetch('https://test.com'); + assert.true(fetchMock.calledWithExactly('https://test.com', { agent: sinon.match.object })); + + fetch('https://test.com', { option: 'value' }); + assert.true(fetchMock.calledWithExactly('https://test.com', { option: 'value', agent: sinon.match.object })); + + // Restore + __setFetch(require('node-fetch')); assert.end(); }); diff --git a/src/platform/getFetch/node.js b/src/platform/getFetch/node.js index 9ad9a8b5d..a6d5ccc22 100644 --- a/src/platform/getFetch/node.js +++ b/src/platform/getFetch/node.js @@ -1,3 +1,14 @@ +/* eslint-disable compat/compat */ +import https from 'https'; + +// @TODO +// 1- handle multiple protocols automatically +// 2- destroy it once the sdk is destroyed +const agent = new https.Agent({ + keepAlive: true, + keepAliveMsecs: 1500 +}); + let nodeFetch; try { @@ -16,6 +27,14 @@ export function __setFetch(fetch) { nodeFetch = fetch; } +/** + * Retrieves 'node-fetch', a Fetch API polyfill for NodeJS, with fallback to global 'fetch' if available. + * It passes an https agent with keepAlive enabled if URL is https. + */ export function getFetch() { - return nodeFetch; + if (nodeFetch) { + return (url, options) => { + return nodeFetch(url, Object.assign({ agent: url.startsWith('https:') ? agent : undefined }, options)); + }; + } } diff --git a/src/platform/node.js b/src/platform/node.js index d3d2a93bb..0a87e3f6e 100644 --- a/src/platform/node.js +++ b/src/platform/node.js @@ -1,12 +1,10 @@ import EventEmitter from 'events'; import { getFetch } from '../platform/getFetch/node'; import { getEventSource } from '../platform/getEventSource/node'; -import { getOptions } from '../platform/request/options/node'; import { NodeSignalListener } from '@splitsoftware/splitio-commons/src/listeners/node'; import { now } from '@splitsoftware/splitio-commons/src/utils/timeTracker/now/node'; export const platform = { - getOptions, getFetch, getEventSource, EventEmitter, diff --git a/src/platform/request/options/node.js b/src/platform/request/options/node.js deleted file mode 100644 index 8be8ee290..000000000 --- a/src/platform/request/options/node.js +++ /dev/null @@ -1,15 +0,0 @@ -// @TODO -// 1- handle multiple protocols automatically -// 2- destroy it once the sdk is destroyed -import https from 'https'; - -const agent = new https.Agent({ - keepAlive: true, - keepAliveMsecs: 1500 -}); - -export function getOptions() { - return { - agent - }; -} diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 9877b7949..c77894e11 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.24.1'; +export const packageVersion = '10.25.0';