From 79fdb4acb23d1102015b9ab6cb86d8a463f97bc0 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 17 Jul 2024 14:12:15 -0300 Subject: [PATCH 01/58] Upgrade JS-commons that includes MyLargeSegments support --- package-lock.json | 14 ++++---- package.json | 2 +- src/__tests__/browserSuites/telemetry.spec.js | 30 ++++++++--------- src/__tests__/nodeSuites/telemetry.spec.js | 4 +-- src/settings/defaults/browser.js | 4 ++- src/settings/defaults/node.js | 4 ++- src/settings/node.js | 6 +++- ts-tests/index.ts | 9 ++++-- types/splitio.d.ts | 32 +++++++++++++++++-- 9 files changed, 71 insertions(+), 34 deletions(-) diff --git a/package-lock.json b/package-lock.json index f8e5b6933..3909675e4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.0", + "@splitsoftware/splitio-commons": "1.16.1-rc.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.0.tgz", - "integrity": "sha512-k16cCWJOWut/NB5W1d9hQEYPxFrZXO66manp+8d6RjZYH4r+Q6lu82NYjDcfh5E93H9v+TVKcQLAmpVofbjcvg==", + "version": "1.16.1-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.0.tgz", + "integrity": "sha512-LcKWbB/ruUl38NQqoIAzYm+RTvrse8iZqZbCP7lqq8v5R6LvYd0nhavDmLTHIr0oKfZzYCKm36SOmSe0S7dvlQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.0.tgz", - "integrity": "sha512-k16cCWJOWut/NB5W1d9hQEYPxFrZXO66manp+8d6RjZYH4r+Q6lu82NYjDcfh5E93H9v+TVKcQLAmpVofbjcvg==", + "version": "1.16.1-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.0.tgz", + "integrity": "sha512-LcKWbB/ruUl38NQqoIAzYm+RTvrse8iZqZbCP7lqq8v5R6LvYd0nhavDmLTHIr0oKfZzYCKm36SOmSe0S7dvlQ==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 4091f4882..848169bd3 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.0", + "@splitsoftware/splitio-commons": "1.16.1-rc.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index d1f77d129..eb46977dd 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -36,7 +36,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', 500); fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', 500); - fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', { status: 200, body: { 'mySegments': [ 'one_segment'] } }); + fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', { status: 200, body: { 'mySegments': ['one_segment'] } }); // We need to handle all requests properly fetchMock.postOnce(baseUrls.events + '/testImpressions/bulk', 200); @@ -76,7 +76,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { // @TODO check if iDe value is correct assert.deepEqual(data, { - mE: {}, hE: { sp: { 500: 1 }, ms: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: { sp: 0, ms: 0 } + mE: {}, hE: { sp: { 500: 1 }, ms: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, 'metrics/usage JSON payload should be the expected'); finish.next(); @@ -96,7 +96,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { // @TODO check if iDe value is correct assert.deepEqual(data, { mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped - tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: { sp: 0, ms: 0 } + tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, '2nd metrics/usage JSON payload should be the expected'); return 200; }); @@ -108,7 +108,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { delete data.tR; // delete to validate other properties assert.deepEqual(data, { - oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, + oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, lE: false, rR: { sp: 99999, ms: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], i: [], uC: 2 /* Default GRANTED */, @@ -188,7 +188,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { const splitFilters = [{ type: 'bySet', values: ['a', '_b', 'a', 'a', 'c', 'd', '_d'] }]; fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=a,c,d', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=a,c,d', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/config', (url, opts) => { const data = JSON.parse(opts.body); @@ -202,10 +202,10 @@ export default async function telemetryBrowserSuite(fetchMock, t) { fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/usage', (url, opts) => { const data = JSON.parse(opts.body); - assert.deepEqual(data.mL.tf, [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 'Latencies stats'); - assert.deepEqual(data.mL.tfs, [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 'Latencies stats'); - assert.deepEqual(data.mL.tcf, [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 'Latencies stats'); - assert.deepEqual(data.mL.tcfs, [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], 'Latencies stats'); + assert.deepEqual(data.mL.tf, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Latencies stats'); + assert.deepEqual(data.mL.tfs, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Latencies stats'); + assert.deepEqual(data.mL.tcf, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Latencies stats'); + assert.deepEqual(data.mL.tcfs, [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 'Latencies stats'); factory.client().destroy().then(() => { assert.end(); @@ -213,14 +213,14 @@ export default async function telemetryBrowserSuite(fetchMock, t) { return 200; }); - fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/usage', 200); + fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/usage', 200); - factory = SplitFactoryForTest({...baseConfig, sync: {splitFilters}}); + factory = SplitFactoryForTest({ ...baseConfig, sync: { splitFilters } }); const client = factory.client(); - assert.deepEqual(client.getTreatmentsByFlagSet('a'),[]); - assert.deepEqual(client.getTreatmentsByFlagSets(['a']),[]); - assert.deepEqual(client.getTreatmentsWithConfigByFlagSet('a'),[]); - assert.deepEqual(client.getTreatmentsWithConfigByFlagSets(['a']),[]); + assert.deepEqual(client.getTreatmentsByFlagSet('a'), []); + assert.deepEqual(client.getTreatmentsByFlagSets(['a']), []); + assert.deepEqual(client.getTreatmentsWithConfigByFlagSet('a'), []); + assert.deepEqual(client.getTreatmentsWithConfigByFlagSets(['a']), []); }, 'SDK with sets configured has sets information in config POST and evaluation by sets telemetry in stats POST'); diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index 22824cd28..fdbc7c457 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -66,7 +66,7 @@ export default async function telemetryNodejsSuite(key, fetchMock, assert) { // @TODO check if iDe value is correct assert.deepEqual(data, { - mE: {}, hE: { sp: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: { sp: 0, ms: 0 } + mE: {}, hE: { sp: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, 'metrics/usage JSON payload should be the expected'); finish.next(); @@ -85,7 +85,7 @@ export default async function telemetryNodejsSuite(key, fetchMock, assert) { // @TODO check if iDe value is correct assert.deepEqual(data, { mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped - tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: { sp: 0, ms: 0 } + tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, '2nd metrics/usage JSON payload should be the expected'); return 200; }); diff --git a/src/settings/defaults/browser.js b/src/settings/defaults/browser.js index 60d47f324..3ee779a0c 100644 --- a/src/settings/defaults/browser.js +++ b/src/settings/defaults/browser.js @@ -10,7 +10,9 @@ export const defaults = { // Maximum amount of time used before notifies me a timeout. readyTimeout: 10, // Amount of time we will wait before the first push of events. - eventsFirstPushWindow: 10 + eventsFirstPushWindow: 10, + // Wait for large segments to emit SDK_READY event. + waitForLargeSegments: true, }, // Consent is considered granted by default diff --git a/src/settings/defaults/node.js b/src/settings/defaults/node.js index 6ba27b528..9fa045334 100644 --- a/src/settings/defaults/node.js +++ b/src/settings/defaults/node.js @@ -13,7 +13,9 @@ export const defaults = { // Maximum amount of time used before notifies me a timeout. readyTimeout: 15, // Don't wait a specific time for first flush on Node, no page load here. - eventsFirstPushWindow: 0 + eventsFirstPushWindow: 0, + // Don't wait for large segments to emit SDK_READY event. + waitForLargeSegments: false, }, features: '.split', diff --git a/src/settings/node.js b/src/settings/node.js index 4d65e46bd..c889b8499 100644 --- a/src/settings/node.js +++ b/src/settings/node.js @@ -12,7 +12,6 @@ const params = { storage: validateStorage, logger: validateLogger, localhost: () => LocalhostFromFile(), - consent: () => undefined, // resets settings.userConsent to the default // In Node.js the SDK ignores `config.integrations`, so a validator for integrations is not required }; @@ -21,5 +20,10 @@ export function settingsFactory(config) { // if provided, keeps reference to the `requestOptions` object if (settings.sync.requestOptions) settings.sync.requestOptions = config.sync.requestOptions; + + // Reset config options not supported in Node.js + if (settings.sync.largeSegmentsEnabled) settings.log.warn('Client instantiation: config.sync.largeSegmentsEnabled option is not supported in NodeJS. Ignoring it.'); + settings.sync.largeSegmentsEnabled = false; + return settings; } diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 9ec3d6d78..0b1527ac0 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -178,7 +178,7 @@ const instantiatedSettingsCore: { } = SDK.settings.core; const instantiatedSettingsMode: ('standalone' | 'consumer') = SDK.settings.mode; const instantiatedSettingsScheduler: { [key: string]: number } = SDK.settings.scheduler; -const instantiatedSettingsStartup: { [key: string]: number } = SDK.settings.startup; +const instantiatedSettingsStartup: { [key: string]: number | boolean } = SDK.settings.startup; const instantiatedSettingsStorage: { prefix: string, options: Object, @@ -535,6 +535,7 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { metricsRefreshRate: 1, telemetryRefreshRate: 1, segmentsRefreshRate: 1, + largeSegmentsRefreshRate: 1, offlineRefreshRate: 1, eventsPushRate: 1, eventsQueueSize: 1, @@ -544,7 +545,8 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { readyTimeout: 1, requestTimeoutBeforeReady: 1, retriesOnFailureBeforeReady: 1, - eventsFirstPushWindow: 1 + eventsFirstPushWindow: 1, + waitForLargeSegments: true, }, urls: { sdk: 'https://asd.com/sdk', @@ -565,7 +567,8 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { sync: { splitFilters: splitFilters, impressionsMode: 'DEBUG', - enabled: true + enabled: true, + largeSegmentsEnabled: true, }, userConsent: 'GRANTED' }; diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 949b757cd..b7598f373 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -78,6 +78,7 @@ interface ISettings { metricsRefreshRate?: number, telemetryRefreshRate: number, segmentsRefreshRate: number, + largeSegmentsRefreshRate: number, offlineRefreshRate: number, eventsPushRate: number, eventsQueueSize: number, @@ -87,7 +88,8 @@ interface ISettings { readyTimeout: number, requestTimeoutBeforeReady: number, retriesOnFailureBeforeReady: number, - eventsFirstPushWindow: number + eventsFirstPushWindow: number, + waitForLargeSegments: boolean }, readonly storage: { prefix: string, @@ -111,7 +113,9 @@ interface ISettings { readonly sync: { splitFilters: SplitIO.SplitFilter[], impressionsMode: SplitIO.ImpressionsMode, - enabled: boolean + enabled: boolean, + largeSegmentsEnabled: boolean, + flagSpecVersion: string } /** * User consent status if using in browser. Undefined if using in NodeJS. @@ -981,6 +985,13 @@ declare namespace SplitIO { * @default 10 */ eventsFirstPushWindow?: number, + /** + * Whether the SDK should wait for large segments to be ready before emitting SDK_READY event. + * It only applies if largeSegmentsEnabled is true. + * @property {boolean} waitForLargeSegments + * @default true + */ + waitForLargeSegments?: boolean }, /** * SDK scheduler settings. @@ -1025,6 +1036,13 @@ declare namespace SplitIO { * @default 60 */ segmentsRefreshRate?: number, + /** + * The SDK polls Split servers for changes to large segment definitions. This parameter controls this polling period in seconds. + * It only applies if largeSegmentsEnabled is true. + * @property {number} largeSegmentsRefreshRate + * @default 60 + */ + largeSegmentsRefreshRate?: number, /** * The SDK posts the queued events data in bulks. This parameter controls the posting rate in seconds. * @property {number} eventsPushRate @@ -1126,7 +1144,15 @@ declare namespace SplitIO { * @typedef {string} userConsent * @default 'GRANTED' */ - userConsent?: ConsentStatus + userConsent?: ConsentStatus, + sync?: ISharedSettings['sync'] & { + /** + * Enables synchronization of large segments. + * @property {boolean} largeSegmentsEnabled + * @default false + */ + largeSegmentsEnabled?: boolean + } } /** * Settings interface for SDK instances created on NodeJS. From a4d8d95770bf984df3a3db0ce5710185abc7e70c Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 17 Jul 2024 19:05:10 -0300 Subject: [PATCH 02/58] Update feature flag definitions adding a flag with large segments, to assert that nothing breaks with default config --- src/__tests__/browserSuites/telemetry.spec.js | 4 +- .../mocks/splitchanges.since.-1.json | 73 +++++++++++++++++++ src/__tests__/nodeSuites/telemetry.spec.js | 4 +- 3 files changed, 77 insertions(+), 4 deletions(-) diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index eb46977dd..39be3e20f 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -76,7 +76,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { // @TODO check if iDe value is correct assert.deepEqual(data, { - mE: {}, hE: { sp: { 500: 1 }, ms: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} + mE: {}, hE: { sp: { 500: 1 }, ms: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 32, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, 'metrics/usage JSON payload should be the expected'); finish.next(); @@ -96,7 +96,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { // @TODO check if iDe value is correct assert.deepEqual(data, { mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped - tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} + tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 32, seC: 1, skC: 1, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, '2nd metrics/usage JSON payload should be the expected'); return 200; }); diff --git a/src/__tests__/mocks/splitchanges.since.-1.json b/src/__tests__/mocks/splitchanges.since.-1.json index 6198d41cc..2fc9eefef 100644 --- a/src/__tests__/mocks/splitchanges.since.-1.json +++ b/src/__tests__/mocks/splitchanges.since.-1.json @@ -1,5 +1,78 @@ { "splits": [ + { + "orgId": null, + "environment": null, + "trafficTypeId": null, + "trafficTypeName": null, + "name": "in_employees_large_segment", + "seed": -1984784937, + "status": "ACTIVE", + "killed": false, + "defaultTreatment": "no", + "conditions": [ + { + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "keySelector": null, + "matcherType": "WHITELIST", + "negate": false, + "userDefinedSegmentMatcherData": null, + "whitelistMatcherData": { + "whitelist": [ + "tia@split.io", + "trevor@split.io" + ] + }, + "unaryNumericMatcherData": null, + "betweenMatcherData": null + } + ] + }, + "partitions": [ + { + "treatment": "yes", + "size": 100 + } + ] + }, + { + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "keySelector": { + "trafficType": "user", + "attribute": null + }, + "matcherType": "IN_LARGE_SEGMENT", + "negate": false, + "userDefinedSegmentMatcherData": { + "segmentName": "employees" + }, + "whitelistMatcherData": null, + "unaryNumericMatcherData": null, + "betweenMatcherData": null, + "unaryStringMatcherData": null + } + ] + }, + "partitions": [ + { + "treatment": "yes", + "size": 0 + }, + { + "treatment": "no", + "size": 100 + } + ] + } + ], + "configurations": {} + }, { "orgId": null, "environment": null, diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index fdbc7c457..a6a6bb66f 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -66,7 +66,7 @@ export default async function telemetryNodejsSuite(key, fetchMock, assert) { // @TODO check if iDe value is correct assert.deepEqual(data, { - mE: {}, hE: { sp: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} + mE: {}, hE: { sp: { 500: 1 } }, tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 32, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, 'metrics/usage JSON payload should be the expected'); finish.next(); @@ -85,7 +85,7 @@ export default async function telemetryNodejsSuite(key, fetchMock, assert) { // @TODO check if iDe value is correct assert.deepEqual(data, { mL: {}, mE: {}, hE: {}, hL: {}, // errors and latencies were popped - tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 31, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} + tR: 0, aR: 0, iQ: 4, iDe: 1, iDr: 0, spC: 32, seC: 3, skC: 3, eQ: 1, eD: 0, sE: [], t: [], ufs: {} }, '2nd metrics/usage JSON payload should be the expected'); return 200; }); From 141f05288db8bd0ff594763767faf074e102c115 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 22 Jul 2024 10:51:27 -0300 Subject: [PATCH 03/58] Upgrade JS-commons --- package-lock.json | 14 ++++----- package.json | 2 +- .../mocks/splitchanges.since.-1.json | 31 ------------------- 3 files changed, 8 insertions(+), 39 deletions(-) diff --git a/package-lock.json b/package-lock.json index 3909675e4..88990eaa6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.0", + "@splitsoftware/splitio-commons": "1.16.1-rc.1", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.0.tgz", - "integrity": "sha512-LcKWbB/ruUl38NQqoIAzYm+RTvrse8iZqZbCP7lqq8v5R6LvYd0nhavDmLTHIr0oKfZzYCKm36SOmSe0S7dvlQ==", + "version": "1.16.1-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.1.tgz", + "integrity": "sha512-sSfpFVhnvKrnJdrhNdTn/9qjS8iHaxj33AQBvOSeiTZ02JPAadHuLjKwY17+S8S6lJZ102ywrApnrEaCLxFUDw==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.0.tgz", - "integrity": "sha512-LcKWbB/ruUl38NQqoIAzYm+RTvrse8iZqZbCP7lqq8v5R6LvYd0nhavDmLTHIr0oKfZzYCKm36SOmSe0S7dvlQ==", + "version": "1.16.1-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.1.tgz", + "integrity": "sha512-sSfpFVhnvKrnJdrhNdTn/9qjS8iHaxj33AQBvOSeiTZ02JPAadHuLjKwY17+S8S6lJZ102ywrApnrEaCLxFUDw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 848169bd3..c21f63e2d 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.0", + "@splitsoftware/splitio-commons": "1.16.1-rc.1", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/mocks/splitchanges.since.-1.json b/src/__tests__/mocks/splitchanges.since.-1.json index 2fc9eefef..dc081eb3f 100644 --- a/src/__tests__/mocks/splitchanges.since.-1.json +++ b/src/__tests__/mocks/splitchanges.since.-1.json @@ -11,33 +11,6 @@ "killed": false, "defaultTreatment": "no", "conditions": [ - { - "matcherGroup": { - "combiner": "AND", - "matchers": [ - { - "keySelector": null, - "matcherType": "WHITELIST", - "negate": false, - "userDefinedSegmentMatcherData": null, - "whitelistMatcherData": { - "whitelist": [ - "tia@split.io", - "trevor@split.io" - ] - }, - "unaryNumericMatcherData": null, - "betweenMatcherData": null - } - ] - }, - "partitions": [ - { - "treatment": "yes", - "size": 100 - } - ] - }, { "matcherGroup": { "combiner": "AND", @@ -62,10 +35,6 @@ "partitions": [ { "treatment": "yes", - "size": 0 - }, - { - "treatment": "no", "size": 100 } ] From 28388205668212abcde6ae55319a91e98bad05df Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 23 Jul 2024 23:16:02 -0300 Subject: [PATCH 04/58] Tests for polling --- package-lock.json | 14 +++---- package.json | 2 +- ...lbacking.spec.js => push-fallback.spec.js} | 40 +++++++++++-------- .../browserSuites/push-refresh-token.spec.js | 2 +- src/__tests__/browserSuites/readiness.spec.js | 2 +- .../mocks/splitchanges.since.-1.json | 32 ++++++++++++++- ...lbacking.spec.js => push-fallback.spec.js} | 8 ++-- .../nodeSuites/push-refresh-token.spec.js | 2 +- src/__tests__/push/browser.spec.js | 4 +- src/__tests__/push/node.spec.js | 4 +- src/settings/__tests__/node.spec.js | 4 +- src/settings/storage/browser.js | 2 +- src/settings/storage/node.js | 4 +- 13 files changed, 78 insertions(+), 42 deletions(-) rename src/__tests__/browserSuites/{push-fallbacking.spec.js => push-fallback.spec.js} (91%) rename src/__tests__/nodeSuites/{push-fallbacking.spec.js => push-fallback.spec.js} (98%) diff --git a/package-lock.json b/package-lock.json index 88990eaa6..5c812e63d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.1", + "@splitsoftware/splitio-commons": "1.16.1-rc.3", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.1.tgz", - "integrity": "sha512-sSfpFVhnvKrnJdrhNdTn/9qjS8iHaxj33AQBvOSeiTZ02JPAadHuLjKwY17+S8S6lJZ102ywrApnrEaCLxFUDw==", + "version": "1.16.1-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.3.tgz", + "integrity": "sha512-c+EkbFp/Ui+BCiSj3EnA/c2LzJRSWtM642GHdPxBJFkDqKmDyKMOp69j/wCXD7ZDN8w0P5tFgbTujrTfA2tHuA==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.1.tgz", - "integrity": "sha512-sSfpFVhnvKrnJdrhNdTn/9qjS8iHaxj33AQBvOSeiTZ02JPAadHuLjKwY17+S8S6lJZ102ywrApnrEaCLxFUDw==", + "version": "1.16.1-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.3.tgz", + "integrity": "sha512-c+EkbFp/Ui+BCiSj3EnA/c2LzJRSWtM642GHdPxBJFkDqKmDyKMOp69j/wCXD7ZDN8w0P5tFgbTujrTfA2tHuA==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index c21f63e2d..bf8afe8ae 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.1", + "@splitsoftware/splitio-commons": "1.16.1-rc.3", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/push-fallbacking.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js similarity index 91% rename from src/__tests__/browserSuites/push-fallbacking.spec.js rename to src/__tests__/browserSuites/push-fallback.spec.js index 83832c0d6..90f698b5d 100644 --- a/src/__tests__/browserSuites/push-fallbacking.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -39,9 +39,9 @@ const userKey = 'nicolas@split.io'; const secondUserKey = 'marcio@split.io'; const baseUrls = { - sdk: 'https://sdk.push-fallbacking/api', - events: 'https://events.push-fallbacking/api', - auth: 'https://auth.push-fallbacking/api' + sdk: 'https://sdk.push-fallback/api', + events: 'https://events.push-fallback/api', + auth: 'https://auth.push-fallback/api' }; const config = { core: { @@ -51,11 +51,14 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.25, + largeSegmentsRefreshRate: 0.25, impressionsRefreshRate: 3000 }, urls: baseUrls, streamingEnabled: true, - // debug: true, + sync: { + largeSegmentsEnabled: true + } }; const settings = settingsFactory(config); @@ -79,30 +82,31 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/nicolas) - * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas) + * 0.0 secs: initial SyncAll (/splitChanges, /my(Large)Segments/nicolas), auth, SSE connection + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /my(Large)Segments/nicolas) + * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas) * 0.3 secs: SPLIT_UPDATE event ignored * 0.4 secs: periodic fetch due to polling (/splitChanges) - * 0.45 secs: periodic fetch due to polling (/mySegments/*) - * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /mySegments/nicolas) - * 0.55 secs: create a new client while streaming -> initial fetch (/mySegments/marcio), auth, SSE connection and syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio) + * 0.45 secs: periodic fetch due to polling (/my(Large)Segments/*) + * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /my(Large)Segments/nicolas) + * 0.55 secs: create a new client while streaming -> initial fetch (/my(Large)Segments/marcio), auth, SSE connection and syncAll (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio) * 0.6 secs: SPLIT_UPDATE event -> /splitChanges - * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio) + * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio) * 0.8 secs: MY_SEGMENTS_UPDATE event ignored * 0.9 secs: periodic fetch due to polling (/splitChanges) - * 0.95 secs: periodic fetch due to polling (/mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) + * 0.95 secs: periodic fetch due to polling (/my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) + * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) * 1.1 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas - * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) + * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) * 1.3 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll and stop polling * 1.5 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll * 1.6 secs: Streaming closed (CONTROL STREAMING_DISABLED event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.8 secs: periodic fetch due to polling (/splitChanges): due to update without segments, mySegments are not fetched + * 1.8 secs: periodic fetch due to polling (/splitChanges) + * 1.85 secs: periodic fetch due to polling (/myLargeSegments/*). /mySegments/* are not fetched due to update without segments * 2.0 secs: periodic fetch due to polling (/splitChanges) * 2.1 secs: destroy client */ -export function testFallbacking(fetchMock, assert) { +export function testFallback(fetchMock, assert) { assert.plan(20); fetchMock.reset(); @@ -213,6 +217,10 @@ export function testFallbacking(fetchMock, assert) { return { status: 200, body: authPushEnabledNicolas }; }); + // MyLargeSegments are fetched one more time than MySegments due to smart pausing of MySegments sync at the end of the test + fetchMock.get({ url: url(settings, '/myLargeSegments/nicolas%40split.io'), repeat: 14 }, { status: 200, body: { myLargeSegments: [] } }); + fetchMock.get({ url: url(settings, '/myLargeSegments/marcio%40split.io'), repeat: 10 }, { status: 200, body: { myLargeSegments: [] } }); + // initial split and mySegment sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); diff --git a/src/__tests__/browserSuites/push-refresh-token.spec.js b/src/__tests__/browserSuites/push-refresh-token.spec.js index cecfcb1fe..d1f929925 100644 --- a/src/__tests__/browserSuites/push-refresh-token.spec.js +++ b/src/__tests__/browserSuites/push-refresh-token.spec.js @@ -57,7 +57,7 @@ export function testRefreshToken(fetchMock, assert) { sseCount++; switch (sseCount) { case 1: - assert.true(nearlyEqual(Date.now() - start, 0), 'first connection is created inmediatelly'); + assert.true(nearlyEqual(Date.now() - start, 0), 'first connection is created immediately'); break; case 2: assert.true(nearlyEqual(Date.now() - start, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'second connection is created with a delay'); diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 3b98d5132..024ff8277 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -62,7 +62,7 @@ export default function (fetchMock, assert) { }); }); - assert.test(t => { // Timeout test, we have retries but mySegmnets takes too long + assert.test(t => { // Timeout test, we have retries but mySegments takes too long const testUrls = { sdk: 'https://sdk.baseurl/readinessSuite2', events: 'https://events.baseurl/readinessSuite2' diff --git a/src/__tests__/mocks/splitchanges.since.-1.json b/src/__tests__/mocks/splitchanges.since.-1.json index dc081eb3f..82ceb16d7 100644 --- a/src/__tests__/mocks/splitchanges.since.-1.json +++ b/src/__tests__/mocks/splitchanges.since.-1.json @@ -5,7 +5,7 @@ "environment": null, "trafficTypeId": null, "trafficTypeName": null, - "name": "in_employees_large_segment", + "name": "in_large_segment", "seed": -1984784937, "status": "ACTIVE", "killed": false, @@ -23,7 +23,35 @@ "matcherType": "IN_LARGE_SEGMENT", "negate": false, "userDefinedSegmentMatcherData": { - "segmentName": "employees" + "segmentName": "harnessians" + }, + "whitelistMatcherData": null, + "unaryNumericMatcherData": null, + "betweenMatcherData": null, + "unaryStringMatcherData": null + } + ] + }, + "partitions": [ + { + "treatment": "yes", + "size": 100 + } + ] + }, + { + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "keySelector": { + "trafficType": "user", + "attribute": null + }, + "matcherType": "IN_LARGE_SEGMENT", + "negate": false, + "userDefinedSegmentMatcherData": { + "segmentName": "splitters" }, "whitelistMatcherData": null, "unaryNumericMatcherData": null, diff --git a/src/__tests__/nodeSuites/push-fallbacking.spec.js b/src/__tests__/nodeSuites/push-fallback.spec.js similarity index 98% rename from src/__tests__/nodeSuites/push-fallbacking.spec.js rename to src/__tests__/nodeSuites/push-fallback.spec.js index 5f330634e..7789236a1 100644 --- a/src/__tests__/nodeSuites/push-fallbacking.spec.js +++ b/src/__tests__/nodeSuites/push-fallback.spec.js @@ -35,9 +35,9 @@ import { settingsFactory } from '../../settings'; const key = 'nicolas@split.io'; const baseUrls = { - sdk: 'https://sdk.push-fallbacking/api', - events: 'https://events.push-fallbacking/api', - auth: 'https://auth.push-fallbacking/api' + sdk: 'https://sdk.push-fallback/api', + events: 'https://events.push-fallback/api', + auth: 'https://auth.push-fallback/api' }; const config = { core: { @@ -96,7 +96,7 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe * 2.1 secs: periodic fetch due to polling (/segmentChanges/*) * 2.1 secs: destroy client */ -export function testFallbacking(fetchMock, assert) { +export function testFallback(fetchMock, assert) { assert.plan(17); fetchMock.reset(); __setEventSource(EventSourceMock); diff --git a/src/__tests__/nodeSuites/push-refresh-token.spec.js b/src/__tests__/nodeSuites/push-refresh-token.spec.js index 0cb2c5424..b3246a2c4 100644 --- a/src/__tests__/nodeSuites/push-refresh-token.spec.js +++ b/src/__tests__/nodeSuites/push-refresh-token.spec.js @@ -57,7 +57,7 @@ export function testRefreshToken(fetchMock, assert) { sseCount++; switch (sseCount) { case 1: - assert.true(nearlyEqual(Date.now() - start, 0), 'first connection is created inmediatelly'); + assert.true(nearlyEqual(Date.now() - start, 0), 'first connection is created immediately'); break; case 2: assert.true(nearlyEqual(Date.now() - start, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'second connection is created with a delay'); diff --git a/src/__tests__/push/browser.spec.js b/src/__tests__/push/browser.spec.js index 2ff84728d..0d8dbeee1 100644 --- a/src/__tests__/push/browser.spec.js +++ b/src/__tests__/push/browser.spec.js @@ -4,7 +4,7 @@ import { testAuthWithPushDisabled, testAuthWith401, testNoEventSource, testSSEWi import { testPushRetriesDueToAuthErrors, testPushRetriesDueToSseErrors, testSdkDestroyWhileAuthRetries, testSdkDestroyWhileAuthSuccess, testSdkDestroyWhileConnDelay } from '../browserSuites/push-initialization-retries.spec'; import { testSynchronization } from '../browserSuites/push-synchronization.spec'; import { testSynchronizationRetries } from '../browserSuites/push-synchronization-retries.spec'; -import { testFallbacking } from '../browserSuites/push-fallbacking.spec'; +import { testFallback } from '../browserSuites/push-fallback.spec'; import { testRefreshToken } from '../browserSuites/push-refresh-token.spec'; import { testSplitKillOnReadyFromCache } from '../browserSuites/push-corner-cases.spec'; import { testFlagSets } from '../browserSuites/push-flag-sets.spec'; @@ -32,7 +32,7 @@ tape('## Browser JS - E2E CI Tests for PUSH ##', function (assert) { assert.test('E2E / PUSH synchronization: happy paths', testSynchronization.bind(null, fetchMock)); assert.test('E2E / PUSH synchronization: retries', testSynchronizationRetries.bind(null, fetchMock)); - assert.test('E2E / PUSH fallbacking, CONTROL, OCCUPANCY and STREAMING_RESET messages', testFallbacking.bind(null, fetchMock)); + assert.test('E2E / PUSH fallback, CONTROL, OCCUPANCY and STREAMING_RESET messages', testFallback.bind(null, fetchMock)); assert.test('E2E / PUSH refresh token and connection delay', testRefreshToken.bind(null, fetchMock)); diff --git a/src/__tests__/push/node.spec.js b/src/__tests__/push/node.spec.js index 6345e15db..ddb756a00 100644 --- a/src/__tests__/push/node.spec.js +++ b/src/__tests__/push/node.spec.js @@ -4,7 +4,7 @@ import { testAuthWithPushDisabled, testAuthWith401, testAuthWith400, testNoEvent import { testPushRetriesDueToAuthErrors, testPushRetriesDueToSseErrors, testSdkDestroyWhileAuthRetries, testSdkDestroyWhileAuthSuccess } from '../nodeSuites/push-initialization-retries.spec'; import { testSynchronization } from '../nodeSuites/push-synchronization.spec'; import { testSynchronizationRetries } from '../nodeSuites/push-synchronization-retries.spec'; -import { testFallbacking } from '../nodeSuites/push-fallbacking.spec'; +import { testFallback } from '../nodeSuites/push-fallback.spec'; import { testRefreshToken } from '../nodeSuites/push-refresh-token.spec'; import { testFlagSets } from '../nodeSuites/push-flag-sets.spec'; @@ -33,7 +33,7 @@ tape('## Node JS - E2E CI Tests for PUSH ##', async function (assert) { assert.test('E2E / PUSH synchronization: happy paths', testSynchronization.bind(null, fetchMock)); assert.test('E2E / PUSH synchronization: retries', testSynchronizationRetries.bind(null, fetchMock)); - assert.test('E2E / PUSH fallbacking, CONTROL and OCCUPANCY messages', testFallbacking.bind(null, fetchMock)); + assert.test('E2E / PUSH fallback, CONTROL and OCCUPANCY messages', testFallback.bind(null, fetchMock)); assert.test('E2E / PUSH refresh token and connection delay', testRefreshToken.bind(null, fetchMock)); diff --git a/src/settings/__tests__/node.spec.js b/src/settings/__tests__/node.spec.js index 54418b874..4e0942e0a 100644 --- a/src/settings/__tests__/node.spec.js +++ b/src/settings/__tests__/node.spec.js @@ -134,8 +134,8 @@ tape('SETTINGS / Log error and fallback to InMemory storage if no valid storage ]; assert.deepEqual(logSpy.args, [ - ['[ERROR] splitio => The provided REDIS storage is invalid for this mode. It requires consumer mode. Fallbacking into default MEMORY storage.'], - ['[ERROR] splitio => The provided \'INVALID\' storage type is invalid. Fallbacking into default MEMORY storage.'] + ['[ERROR] splitio => The provided REDIS storage is invalid for this mode. It requires consumer mode. Fallback into default MEMORY storage.'], + ['[ERROR] splitio => The provided \'INVALID\' storage type is invalid. Fallback into default MEMORY storage.'] ], 'logs error message'); settings.forEach(setting => { assert.equal(setting.storage.type, 'MEMORY', 'fallbacks to memory storage'); }); diff --git a/src/settings/storage/browser.js b/src/settings/storage/browser.js index 92daa2cd2..10a9e3eea 100644 --- a/src/settings/storage/browser.js +++ b/src/settings/storage/browser.js @@ -31,7 +31,7 @@ export function validateStorage(settings) { if (type !== STORAGE_MEMORY && type !== STORAGE_LOCALSTORAGE || type === STORAGE_LOCALSTORAGE && !isLocalStorageAvailable()) { fallbackToMemory(); - log.error('Invalid or unavailable storage. Fallbacking into MEMORY storage'); + log.error('Invalid or unavailable storage. Fallback into MEMORY storage'); } return { diff --git a/src/settings/storage/node.js b/src/settings/storage/node.js index ea85045df..b5296889f 100644 --- a/src/settings/storage/node.js +++ b/src/settings/storage/node.js @@ -16,7 +16,7 @@ export function validateStorage(settings) { case STORAGE_REDIS: { // If passing REDIS storage in localhost or standalone mode, we log an error and fallback to MEMORY storage if (mode === STANDALONE_MODE || mode === LOCALHOST_MODE) { - log.error('The provided REDIS storage is invalid for this mode. It requires consumer mode. Fallbacking into default MEMORY storage.'); + log.error('The provided REDIS storage is invalid for this mode. It requires consumer mode. Fallback into default MEMORY storage.'); return { type: STORAGE_MEMORY, prefix @@ -74,7 +74,7 @@ export function validateStorage(settings) { // If passing MEMORY storage in consumer mode, throw an error (no way to fallback to REDIS storage) if (mode === CONSUMER_MODE) throw new Error('A REDIS storage is required on consumer mode'); // If passing an invalid storage type, log an error - if (type !== STORAGE_MEMORY) log.error(`The provided '${type}' storage type is invalid. Fallbacking into default MEMORY storage.`); + if (type !== STORAGE_MEMORY) log.error(`The provided '${type}' storage type is invalid. Fallback into default MEMORY storage.`); return { type: STORAGE_MEMORY, prefix From 4615c326a3c3deb8f22cc2f8e6827f49b4115942 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 23 Jul 2024 23:19:46 -0300 Subject: [PATCH 05/58] Add readiness tests --- .../readiness-large-segments.spec.js | 149 ++++++++++++++++++ .../mocks/mylargesegments.employees.json | 6 + src/__tests__/online/browser.spec.js | 2 + 3 files changed, 157 insertions(+) create mode 100644 src/__tests__/browserSuites/readiness-large-segments.spec.js create mode 100644 src/__tests__/mocks/mylargesegments.employees.json diff --git a/src/__tests__/browserSuites/readiness-large-segments.spec.js b/src/__tests__/browserSuites/readiness-large-segments.spec.js new file mode 100644 index 000000000..8146842e0 --- /dev/null +++ b/src/__tests__/browserSuites/readiness-large-segments.spec.js @@ -0,0 +1,149 @@ +import { SplitFactory } from '../../'; + +// Mocks +import mySegments from '../mocks/mysegments.nicolas@split.io.json'; +import myLargeSegments from '../mocks/mylargesegments.employees.json'; +import { nearlyEqual } from '../testUtils'; + +const FF = { + name: 'FF', + status: 'ACTIVE', + conditions: [{ + matcherGroup: { + combiner: 'AND', + matchers: [] + } + }] +}; + +const FF_WITH_SEGMENTS = { + name: 'FF_WITH_SEGMENTS', + status: 'ACTIVE', + conditions: [{ + matcherGroup: { + combiner: 'AND', + matchers: [{ + matcherType: 'IN_SEGMENT', + userDefinedSegmentMatcherData: { + segmentName: 'A' + } + }] + } + }] +}; + +const FF_WITH_LARGE_SEGMENTS = { + name: 'FF_WITH_LARGE_SEGMENTS', + status: 'ACTIVE', + conditions: [{ + matcherGroup: { + combiner: 'AND', + matchers: [{ + matcherType: 'IN_LARGE_SEGMENT', + userDefinedSegmentMatcherData: { + segmentName: 'A' + } + }] + } + }] +}; + +const waitConfig = { + core: { + authorizationKey: '', + key: 'emi@split.io' + }, + urls: { + sdk: 'https://sdk.baseurl/largeSegments', + }, + sync: { + largeSegmentsEnabled: true + }, + streamingEnabled: false +}; + +const noWaitConfig = { + ...waitConfig, + startup: { + waitForLargeSegments: false + } +}; + +const SEGMENTS_DELAY = 50; +const LARGE_SEGMENTS_DELAY = 100; +const TEST_END_DELAY = 150; + +export default function (fetchMock, assert) { + + const testCases = [ + { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: true }, + { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: false }, + { waitForLargeSegments: true, featureFlagsWithSegments: false, featureFlagsWithLS: true }, + { waitForLargeSegments: true, featureFlagsWithSegments: false, featureFlagsWithLS: false }, + { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: true }, + { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: false }, + { waitForLargeSegments: false, featureFlagsWithSegments: false, featureFlagsWithLS: true }, + { waitForLargeSegments: false, featureFlagsWithSegments: false, featureFlagsWithLS: false }, + + // Special cases where large segments are not supported for the given SDK key: `/myLargeSegments/*` responds with 403 and there cannot be FFs with large segments + { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: false, myLargeSegmentsForbidden: true }, + { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: false, myLargeSegmentsForbidden: true }, + ]; + + testCases.forEach(({ waitForLargeSegments, featureFlagsWithSegments, featureFlagsWithLS, myLargeSegmentsForbidden }) => { + + const config = waitForLargeSegments ? waitConfig : noWaitConfig; + + const splitChangesMock = { + since: -1, + till: 1457552620999, + splits: [FF, featureFlagsWithSegments && FF_WITH_SEGMENTS, featureFlagsWithLS && FF_WITH_LARGE_SEGMENTS].filter(ff => ff) + }; + + // smart ready: if FFs are not using segments (or LS) we don't need to wait for them + const SDK_READY_DELAY = Math.max( + featureFlagsWithSegments ? SEGMENTS_DELAY : 0, + featureFlagsWithLS && waitForLargeSegments ? LARGE_SEGMENTS_DELAY : 0 + ); + + // emit SDK_UPDATE if large segments arrive after SDK_READY event is emitted and FFs are using them + const shouldEmitSdkUpdate = waitForLargeSegments === false && featureFlagsWithLS === true && (LARGE_SEGMENTS_DELAY > SEGMENTS_DELAY || featureFlagsWithSegments === false); + + assert.test(t => { + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { since: 1457552620999, till: 1457552620999, splits: [] } }); + fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: mySegments }, { delay: SEGMENTS_DELAY }); + fetchMock.getOnce(config.urls.sdk + '/myLargeSegments/emi%40split.io', { status: myLargeSegmentsForbidden ? 403 : 200, body: myLargeSegments }, { delay: LARGE_SEGMENTS_DELAY }); + + // smart pausing: if FFs are not using segments (or LS) we don't need to fetch them + if (featureFlagsWithSegments) fetchMock.getOnce(config.urls.sdk + '/mySegments/shared', { status: 200, body: mySegments }, { delay: SEGMENTS_DELAY }); + if (featureFlagsWithLS) fetchMock.getOnce(config.urls.sdk + '/myLargeSegments/shared', { status: myLargeSegmentsForbidden ? 403 : 200, body: myLargeSegments }, { delay: LARGE_SEGMENTS_DELAY }); + + const splitio = SplitFactory(config); + const client = splitio.client(); + + const start = Date.now(); + client.once(client.Event.SDK_READY, () => { + assert.true(nearlyEqual(Date.now() - start, SDK_READY_DELAY)); + + splitio.client('shared').ready().then(() => { + assert.true(nearlyEqual(Date.now() - start, 2 * SDK_READY_DELAY)); + }); + }); + + let updateEmitted = false; + + client.once(client.Event.SDK_UPDATE, () => { + assert.true(nearlyEqual(Date.now() - start, LARGE_SEGMENTS_DELAY)); + updateEmitted = true; + }); + + setTimeout(() => { + assert.true(updateEmitted === shouldEmitSdkUpdate); + client.destroy().then(() => { t.end(); }); + }, TEST_END_DELAY); + }); + + }); + +} diff --git a/src/__tests__/mocks/mylargesegments.employees.json b/src/__tests__/mocks/mylargesegments.employees.json new file mode 100644 index 000000000..13e67ed94 --- /dev/null +++ b/src/__tests__/mocks/mylargesegments.employees.json @@ -0,0 +1,6 @@ +{ + "myLargeSegments": [ + "employees" + ], + "changeNumber": 1234567890 +} diff --git a/src/__tests__/online/browser.spec.js b/src/__tests__/online/browser.spec.js index f862a3ea8..8da674e95 100644 --- a/src/__tests__/online/browser.spec.js +++ b/src/__tests__/online/browser.spec.js @@ -9,6 +9,7 @@ import impressionsSuiteNone from '../browserSuites/impressions.none.spec'; import telemetrySuite from '../browserSuites/telemetry.spec'; import impressionsListenerSuite from '../browserSuites/impressions-listener.spec'; import readinessSuite from '../browserSuites/readiness.spec'; +import readinessWithLargeSegmentsSuite from '../browserSuites/readiness-large-segments.spec'; import readyFromCache from '../browserSuites/ready-from-cache.spec'; import { withoutBindingTT, bindingTT } from '../browserSuites/events.spec'; import sharedInstantiationSuite from '../browserSuites/shared-instantiation.spec'; @@ -122,6 +123,7 @@ tape('## E2E CI Tests ##', function (assert) { assert.test('E2E / Manager API', managerSuite.bind(null, settings, fetchMock)); /* Validate readiness */ assert.test('E2E / Readiness', readinessSuite.bind(null, fetchMock)); + assert.test('E2E / Readiness with large segments', readinessWithLargeSegmentsSuite.bind(null, fetchMock)); /* Validate headers for ip and hostname are not sended with requests (ignore setting IPAddressesEnabled) */ assert.test('E2E / Ignore setting IPAddressesEnabled', ignoreIpAddressesSettingSuite.bind(null, fetchMock)); /* Check that impressions and events are sended to backend via Beacon API or Fetch when pagehide/visibilitychange events are triggered. */ From 4ed5f2bfaff4c5bcdb0453c9a72adb16c93c3974 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 23 Jul 2024 23:20:05 -0300 Subject: [PATCH 06/58] Add tests for streaming mode --- .../push-synchronization.spec.js | 70 ++++++++++++++++--- ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 ++ ...GMENTS_UPDATE.UNBOUNDED.1457552650000.json | 4 ++ .../mocks/splitchanges.real.withSegments.json | 42 +++++++++++ .../nodeSuites/push-synchronization.spec.js | 4 +- 5 files changed, 114 insertions(+), 10 deletions(-) create mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 4ca030726..3acc27f58 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -17,6 +17,8 @@ import unboundedMessage from '../mocks/message.V2.UNBOUNDED.1457552650000.json'; import boundedZlibMessage from '../mocks/message.V2.BOUNDED.ZLIB.1457552651000.json'; import keylistGzipMessage from '../mocks/message.V2.KEYLIST.GZIP.1457552652000.json'; import segmentRemovalMessage from '../mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMyLargeSegmentsMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json'; +import myLargeSegmentRemovalMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -49,6 +51,9 @@ const config = { }, urls: baseUrls, streamingEnabled: true, + sync: { + largeSegmentsEnabled: true + } }; const settings = settingsFactory(config); @@ -68,17 +73,19 @@ const MILLIS_KEYLIST_FALLBACK = 1300; const MILLIS_BOUNDED = 1400; const MILLIS_KEYLIST = 1500; const MILLIS_SEGMENT_REMOVAL = 1600; +const MILLIS_UNBOUNDED_FETCH_LS = 1700; +const MILLIS_SEGMENT_REMOVAL_LS = 2000; /** * Sequence of calls: * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*, /myLargeSegments/*) * 0.2 secs: SPLIT_UPDATE event -> /splitChanges * 0.3 secs: SPLIT_UPDATE event with old changeNumber * 0.4 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io * 0.5 secs: SPLIT_KILL event -> /splitChanges * 0.6 secs: creates a new client -> new auth and SSE connection - * 0.7 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) + * 0.7 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*, /myLargeSegments/*) * 0.8 secs: MY_SEGMENTS_UPDATE event for new client (with payload). * 0.9 secs: MY_SEGMENTS_UPDATE event for new client (with empty payload). * 1.0 secs: creates more clients @@ -88,9 +95,12 @@ const MILLIS_SEGMENT_REMOVAL = 1600; * 1.4 secs: MY_SEGMENTS_UPDATE_V2 BoundedFetchRequest event. * 1.5 secs: MY_SEGMENTS_UPDATE_V2 KeyList event. * 1.6 secs: MY_SEGMENTS_UPDATE_V2 SegmentRemoval event. + * 1.7 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) + * 1.941 secs: /myLargeSegments/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SPLIT_UPDATE event + * 2.0 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { - assert.plan(38); + assert.plan(44); fetchMock.reset(); let start, splitio, client, otherClient, keylistAddClient, keylistRemoveClient, bitmapTrueClient, sharedClients = []; @@ -236,6 +246,31 @@ export function testSynchronization(fetchMock, assert) { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'on', 'off', 'on'], 'evaluation before segment removal'); bitmapTrueClient.once(bitmapTrueClient.Event.SDK_UPDATE, () => { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'off', 'off', 'off'], 'evaluation after segment removal'); + }); + + eventSourceInstance.emitMessage(segmentRemovalMessage); + }, MILLIS_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); + + setTimeout(() => { + assert.equal(client.getTreatment('in_large_segment'), 'no', 'evaluation before myLargeSegment fetch'); + + const timestampUnboundEvent = Date.now(); + const EXPECTED_DELAY = 241; + + client.once(client.Event.SDK_UPDATE, () => { + assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching myLargeSegments with a delay'); + assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation after myLargeSegment fetch'); + }); + + eventSourceInstance.emitMessage(unboundedMyLargeSegmentsMessage); + }, MILLIS_UNBOUNDED_FETCH_LS - MILLIS_MORE_CLIENTS); + + setTimeout(() => { + assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation before large segment removal'); + assert.deepEqual(sharedClients.map(c => c.getTreatment('in_large_segment')), ['no', 'no', 'no', 'no'], 'evaluation before segment removal'); + + client.once(client.Event.SDK_UPDATE, () => { + assert.equal(client.getTreatment('in_large_segment'), 'no', 'evaluation after large segment removal'); // destroy shared clients and then main client Promise.all(sharedClients.map(c => c.destroy())) @@ -252,8 +287,8 @@ export function testSynchronization(fetchMock, assert) { }); }); - eventSourceInstance.emitMessage(segmentRemovalMessage); - }, MILLIS_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); + eventSourceInstance.emitMessage(myLargeSegmentRemovalMessage); + }, MILLIS_SEGMENT_REMOVAL_LS - MILLIS_MORE_CLIENTS); }); }, MILLIS_MORE_CLIENTS - MILLIS_NEW_CLIENT); @@ -283,7 +318,7 @@ export function testSynchronization(fetchMock, assert) { authParams += `&users=${encodeURIComponent(keylistAddKey)}&users=${encodeURIComponent(keylistRemoveKey)}&users=${encodeURIComponent(bitmapTrueKey)}`; fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&${authParams}`), { status: 200, body: authPushEnabledNicolasAndMarcio }); - // initial split and mySegments sync + // initial sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); @@ -294,6 +329,7 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsNicolasMock1 }; }); + fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); // split and segment sync after SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { @@ -306,6 +342,7 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsNicolasMock1 }; }); + fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); // fetch due to SPLIT_UPDATE event fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { @@ -326,13 +363,15 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: splitChangesMock4 }; }); - // initial fetch of mySegments for new client + // initial fetch of mySegments and myLargeSegments for new client fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsMarcio }; }); + fetchMock.getOnce(url(settings, '/myLargeSegments/marcio%40split.io'), { status: 200, body: { myLargeSegments: [] } }); + - // split and mySegment sync after second SSE opened + // sync after second SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SECOND_SSE_OPEN), 'sync after second SSE connection is opened'); @@ -347,6 +386,9 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsMarcio }; }); + fetchMock.get({ url: url(settings, '/myLargeSegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); + fetchMock.get({ url: url(settings, '/myLargeSegments/marcio%40split.io'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); + // 3 unbounded fetch requests fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 3 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -357,15 +399,25 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: mySegmentsMarcio }; }); - // initial fetch of mySegments for other clients + sync after third SSE opened + 3 unbounded fetch requests + // initial fetch of mySegments and myLargeSegments for other clients + sync after third SSE opened + 3 unbounded fetch requests for mySegments fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); fetchMock.get({ url: url(settings, '/mySegments/key1'), repeat: 5 }, { status: 200, body: { mySegments: [] } }); fetchMock.get({ url: url(settings, '/mySegments/key3'), repeat: 5 }, { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); fetchMock.get({ url: url(settings, `/mySegments/${bitmapTrueKey}`), repeat: 5 }, { status: 200, body: { mySegments: [] } }); + fetchMock.get({ url: url(settings, '/myLargeSegments/key1'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); + fetchMock.get({ url: url(settings, '/myLargeSegments/key3'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); + fetchMock.get({ url: url(settings, `/myLargeSegments/${bitmapTrueKey}`), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); // bounded fetch request fetchMock.get(url(settings, `/mySegments/${bitmapTrueKey}`), { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); + // unbounded myLargeSegments fetch requests + fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: ['employees', 'splitters'] } }); + fetchMock.getOnce(url(settings, '/myLargeSegments/marcio%40split.io'), { status: 200, body: { myLargeSegments: [] } }); + fetchMock.getOnce(url(settings, '/myLargeSegments/key1'), { status: 200, body: { myLargeSegments: [] } }); + fetchMock.getOnce(url(settings, '/myLargeSegments/key3'), { status: 200, body: { myLargeSegments: [] } }); + fetchMock.getOnce(url(settings, `/myLargeSegments/${bitmapTrueKey}`), { status: 200, body: { myLargeSegments: [] } }); + fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); }); diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..eac4303a0 --- /dev/null +++ b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552653000,\\\"largeSegments\\\":[\\\"harnessians\\\",\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json new file mode 100644 index 000000000..8563135d0 --- /dev/null +++ b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552650000,\\\"largeSegments\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":0,\\\"s\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/splitchanges.real.withSegments.json b/src/__tests__/mocks/splitchanges.real.withSegments.json index a9d4149f4..3f474a14f 100644 --- a/src/__tests__/mocks/splitchanges.real.withSegments.json +++ b/src/__tests__/mocks/splitchanges.real.withSegments.json @@ -1,5 +1,47 @@ { "splits": [ + { + "orgId": null, + "environment": null, + "trafficTypeId": null, + "trafficTypeName": null, + "name": "in_large_segment", + "seed": -1984784937, + "status": "ACTIVE", + "killed": false, + "defaultTreatment": "no", + "conditions": [ + { + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "keySelector": { + "trafficType": "user", + "attribute": null + }, + "matcherType": "IN_LARGE_SEGMENT", + "negate": false, + "userDefinedSegmentMatcherData": { + "segmentName": "harnessians" + }, + "whitelistMatcherData": null, + "unaryNumericMatcherData": null, + "betweenMatcherData": null, + "unaryStringMatcherData": null + } + ] + }, + "partitions": [ + { + "treatment": "yes", + "size": 100 + } + ] + } + ], + "configurations": {} + }, { "trafficTypeName": "user", "name": "real_split", diff --git a/src/__tests__/nodeSuites/push-synchronization.spec.js b/src/__tests__/nodeSuites/push-synchronization.spec.js index 51c17724d..954f8a560 100644 --- a/src/__tests__/nodeSuites/push-synchronization.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization.spec.js @@ -44,7 +44,9 @@ const config = { }, urls: baseUrls, streamingEnabled: true, - // debug: true, + sync: { + largeSegmentsEnabled: true // ignored in node + } }; const settings = settingsFactory(config); From 7acf4488c2f0385430d05e4fd5aed2e01a4b9d50 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 25 Jul 2024 19:42:03 +0100 Subject: [PATCH 07/58] Update test --- package-lock.json | 14 +++++++------- package.json | 2 +- .../browserSuites/push-synchronization.spec.js | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5c812e63d..26a56013c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.3", + "@splitsoftware/splitio-commons": "1.16.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.3.tgz", - "integrity": "sha512-c+EkbFp/Ui+BCiSj3EnA/c2LzJRSWtM642GHdPxBJFkDqKmDyKMOp69j/wCXD7ZDN8w0P5tFgbTujrTfA2tHuA==", + "version": "1.16.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.4.tgz", + "integrity": "sha512-xL0zAbq6/iDUQU5TInCDIPzWVA9K2YlT/dWbSYpyIzbLVk/Hqir1TcTzulYw86Ant/nfWZJaE4sCygb1y3q2TA==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.3.tgz", - "integrity": "sha512-c+EkbFp/Ui+BCiSj3EnA/c2LzJRSWtM642GHdPxBJFkDqKmDyKMOp69j/wCXD7ZDN8w0P5tFgbTujrTfA2tHuA==", + "version": "1.16.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.4.tgz", + "integrity": "sha512-xL0zAbq6/iDUQU5TInCDIPzWVA9K2YlT/dWbSYpyIzbLVk/Hqir1TcTzulYw86Ant/nfWZJaE4sCygb1y3q2TA==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index bf8afe8ae..0d3bacfb3 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.3", + "@splitsoftware/splitio-commons": "1.16.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 3acc27f58..b9e99a439 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -74,7 +74,7 @@ const MILLIS_BOUNDED = 1400; const MILLIS_KEYLIST = 1500; const MILLIS_SEGMENT_REMOVAL = 1600; const MILLIS_UNBOUNDED_FETCH_LS = 1700; -const MILLIS_SEGMENT_REMOVAL_LS = 2000; +const MILLIS_SEGMENT_REMOVAL_LS = 2100; /** * Sequence of calls: @@ -97,7 +97,7 @@ const MILLIS_SEGMENT_REMOVAL_LS = 2000; * 1.6 secs: MY_SEGMENTS_UPDATE_V2 SegmentRemoval event. * 1.7 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) * 1.941 secs: /myLargeSegments/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SPLIT_UPDATE event - * 2.0 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 2.1 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { assert.plan(44); From cbcd0c919a2e687453d3673844e1fda8b3cf6cc8 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 25 Jul 2024 20:27:12 +0100 Subject: [PATCH 08/58] rc --- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- src/settings/defaults/version.js | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/package-lock.json b/package-lock.json index 26a56013c..554ba8d28 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.0", + "version": "10.27.1-rc.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.27.0", + "version": "10.27.1-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.4", + "@splitsoftware/splitio-commons": "1.16.1-rc.5", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.4", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.4.tgz", - "integrity": "sha512-xL0zAbq6/iDUQU5TInCDIPzWVA9K2YlT/dWbSYpyIzbLVk/Hqir1TcTzulYw86Ant/nfWZJaE4sCygb1y3q2TA==", + "version": "1.16.1-rc.5", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.5.tgz", + "integrity": "sha512-Kzy/lCHV8BXrI7uJCpH3kynMY5zApgkGOt1aG+7iJy1cK5V1+lHWaTGD5XjophF7lmbpR+VGaNM60+rDqswkIg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.4", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.4.tgz", - "integrity": "sha512-xL0zAbq6/iDUQU5TInCDIPzWVA9K2YlT/dWbSYpyIzbLVk/Hqir1TcTzulYw86Ant/nfWZJaE4sCygb1y3q2TA==", + "version": "1.16.1-rc.5", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.5.tgz", + "integrity": "sha512-Kzy/lCHV8BXrI7uJCpH3kynMY5zApgkGOt1aG+7iJy1cK5V1+lHWaTGD5XjophF7lmbpR+VGaNM60+rDqswkIg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 0d3bacfb3..d0e064b06 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.0", + "version": "10.27.1-rc.0", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.4", + "@splitsoftware/splitio-commons": "1.16.1-rc.5", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 9974d45bc..6e55955c8 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.27.0'; +export const packageVersion = '10.27.1-rc.0'; From 71e0fec7f2f8dda6ad4837146cb0e90b6faadb18 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 26 Jul 2024 13:54:51 +0100 Subject: [PATCH 09/58] Handle localhost mode --- src/__tests__/offline/browser.spec.js | 6 +++++- src/settings/browser.js | 8 +++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/__tests__/offline/browser.spec.js b/src/__tests__/offline/browser.spec.js index 10ef846d5..bb1961b0b 100644 --- a/src/__tests__/offline/browser.spec.js +++ b/src/__tests__/offline/browser.spec.js @@ -59,7 +59,11 @@ tape('Browser offline mode', function (assert) { startup: { eventsFirstPushWindow: 0 }, - features: originalFeaturesMap + features: originalFeaturesMap, + sync: { + // ignored + largeSegmentsEnabled: true + } }; const factory = SplitFactory(config); const manager = factory.manager(); diff --git a/src/settings/browser.js b/src/settings/browser.js index d3f04443e..ffe7b2a06 100644 --- a/src/settings/browser.js +++ b/src/settings/browser.js @@ -3,6 +3,7 @@ import { validateRuntime } from '@splitsoftware/splitio-commons/src/utils/settin import { validateLogger } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/logger/builtinLogger'; import { LocalhostFromObject } from '@splitsoftware/splitio-commons/src/sync/offline/LocalhostFromObject'; import { validateConsent } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/consent'; +import { STANDALONE_MODE } from '@splitsoftware/splitio-commons/src/utils/constants'; import { defaults } from './defaults/browser'; import { validateStorage } from './storage/browser'; @@ -20,5 +21,10 @@ const params = { }; export function settingsFactory(config) { - return settingsValidation(config, params); + const settings = settingsValidation(config, params); + + // Override in localhost mode to properly emit SDK_READY + if (settings.mode !== STANDALONE_MODE) settings.sync.largeSegmentsEnabled = false; + + return settings; } From b00904948488ce199bfcff2b97e4603a56314d7b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 31 Jul 2024 16:40:39 +0100 Subject: [PATCH 10/58] Upgrade JS-commons with FLAG_SPEC_VERSION 1.2 --- package-lock.json | 14 +++---- package.json | 2 +- .../browserSuites/evaluations-semver.spec.js | 4 +- .../fetch-specific-splits.spec.js | 10 ++--- src/__tests__/browserSuites/flag-sets.spec.js | 24 +++++------ .../ignore-ip-addresses-setting.spec.js | 4 +- .../browserSuites/impressions.debug.spec.js | 4 +- .../browserSuites/impressions.none.spec.js | 4 +- .../browserSuites/impressions.spec.js | 4 +- src/__tests__/browserSuites/manager.spec.js | 2 +- .../browserSuites/push-corner-cases.spec.js | 6 +-- .../browserSuites/push-fallback.spec.js | 30 ++++++------- .../browserSuites/push-flag-sets.spec.js | 14 +++---- .../push-initialization-nopush.spec.js | 12 +++--- .../push-initialization-retries.spec.js | 40 +++++++++--------- .../browserSuites/push-refresh-token.spec.js | 14 +++---- .../push-synchronization-retries.spec.js | 18 ++++---- .../push-synchronization.spec.js | 18 ++++---- .../readiness-large-segments.spec.js | 4 +- src/__tests__/browserSuites/readiness.spec.js | 36 ++++++++-------- .../browserSuites/ready-from-cache.spec.js | 42 +++++++++---------- .../browserSuites/ready-promise.spec.js | 34 +++++++-------- .../browserSuites/single-sync.spec.js | 2 +- src/__tests__/browserSuites/telemetry.spec.js | 6 +-- .../use-beacon-api.debug.spec.js | 4 +- .../browserSuites/use-beacon-api.spec.js | 4 +- src/__tests__/destroy/browser.spec.js | 4 +- src/__tests__/destroy/node.spec.js | 4 +- src/__tests__/errorCatching/browser.spec.js | 8 ++-- src/__tests__/errorCatching/node.spec.js | 6 +-- src/__tests__/gaIntegration/browser.spec.js | 2 +- .../nodeSuites/evaluations-semver.spec.js | 4 +- .../nodeSuites/expected-treatments.spec.js | 2 +- .../nodeSuites/fetch-specific-splits.spec.js | 10 ++--- src/__tests__/nodeSuites/flag-sets.spec.js | 24 +++++------ .../nodeSuites/impressions.debug.spec.js | 4 +- .../nodeSuites/impressions.none.spec.js | 4 +- src/__tests__/nodeSuites/impressions.spec.js | 4 +- .../ip-addresses-setting.debug.spec.js | 4 +- .../nodeSuites/ip-addresses-setting.spec.js | 4 +- src/__tests__/nodeSuites/manager.spec.js | 2 +- .../nodeSuites/push-fallback.spec.js | 28 ++++++------- .../nodeSuites/push-flag-sets.spec.js | 14 +++---- .../push-initialization-nopush.spec.js | 14 +++---- .../push-initialization-retries.spec.js | 36 ++++++++-------- .../nodeSuites/push-refresh-token.spec.js | 14 +++---- .../push-synchronization-retries.spec.js | 18 ++++---- .../nodeSuites/push-synchronization.spec.js | 20 ++++----- src/__tests__/nodeSuites/readiness.spec.js | 4 +- .../nodeSuites/ready-promise.spec.js | 32 +++++++------- src/__tests__/nodeSuites/telemetry.spec.js | 4 +- src/__tests__/online/browser.spec.js | 4 +- src/__tests__/online/node.spec.js | 4 +- 53 files changed, 317 insertions(+), 317 deletions(-) diff --git a/package-lock.json b/package-lock.json index 554ba8d28..662e0f1d8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.1-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.5", + "@splitsoftware/splitio-commons": "1.16.1-rc.6", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.5", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.5.tgz", - "integrity": "sha512-Kzy/lCHV8BXrI7uJCpH3kynMY5zApgkGOt1aG+7iJy1cK5V1+lHWaTGD5XjophF7lmbpR+VGaNM60+rDqswkIg==", + "version": "1.16.1-rc.6", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.6.tgz", + "integrity": "sha512-h4+hYpJoDjkFMgube9KFPQDz5a+O3eII4VSlzh0KJpQJukesq0Isf3T0C5ICP4pYHfkm4E+Yy+ohYfISxaDd6w==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.5", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.5.tgz", - "integrity": "sha512-Kzy/lCHV8BXrI7uJCpH3kynMY5zApgkGOt1aG+7iJy1cK5V1+lHWaTGD5XjophF7lmbpR+VGaNM60+rDqswkIg==", + "version": "1.16.1-rc.6", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.6.tgz", + "integrity": "sha512-h4+hYpJoDjkFMgube9KFPQDz5a+O3eII4VSlzh0KJpQJukesq0Isf3T0C5ICP4pYHfkm4E+Yy+ohYfISxaDd6w==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index d0e064b06..ce5f2ecfd 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.5", + "@splitsoftware/splitio-commons": "1.16.1-rc.6", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/evaluations-semver.spec.js b/src/__tests__/browserSuites/evaluations-semver.spec.js index 29d2540fe..97e7ddb43 100644 --- a/src/__tests__/browserSuites/evaluations-semver.spec.js +++ b/src/__tests__/browserSuites/evaluations-semver.spec.js @@ -25,8 +25,8 @@ const config = { export default async function (fetchMock, assert) { - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: { mySegments: [] } }); fetchMock.getOnce(config.urls.sdk + '/mySegments/2nd', { status: 200, body: { mySegments: [] } }); diff --git a/src/__tests__/browserSuites/fetch-specific-splits.spec.js b/src/__tests__/browserSuites/fetch-specific-splits.spec.js index fb64a4b82..13196594c 100644 --- a/src/__tests__/browserSuites/fetch-specific-splits.spec.js +++ b/src/__tests__/browserSuites/fetch-specific-splits.spec.js @@ -25,9 +25,9 @@ export function fetchSpecificSplits(fetchMock, assert) { const queryString = queryStrings[i] || ''; let factory; - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, function () { + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, function () { factory.client().destroy().then(() => { assert.pass(`splitFilters #${i}`); }); @@ -70,8 +70,8 @@ export function fetchSpecificSplitsForFlagSets(fetchMock, assert) { const queryString = '&sets=4_valid,set_2,set_3,set_ww,set_x'; fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, async function () { t.pass('flag set query correctly formed'); t.true(logSpy.calledWithExactly('[WARN] splitio => settings: bySet filter value "set_x " has extra whitespace, trimming.')); t.true(logSpy.calledWithExactly('[WARN] splitio => settings: you passed invalid+, flag set must adhere to the regular expressions /^[a-z0-9][_a-z0-9]{0,49}$/. This means a flag set must start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. invalid+ was discarded.')); diff --git a/src/__tests__/browserSuites/flag-sets.spec.js b/src/__tests__/browserSuites/flag-sets.spec.js index 60396eb81..14b335768 100644 --- a/src/__tests__/browserSuites/flag-sets.spec.js +++ b/src/__tests__/browserSuites/flag-sets.spec.js @@ -24,12 +24,12 @@ export default function flagSets(fetchMock, t) { let manager; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1, 'only one feature flag should be added'); @@ -41,7 +41,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1); @@ -52,7 +52,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344&sets=set_1,set_2', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344&sets=set_1,set_2', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 0, 'the feature flag should be removed'); @@ -75,12 +75,12 @@ export default function flagSets(fetchMock, t) { let manager; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2, 'every feature flag should be added'); @@ -94,7 +94,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -107,7 +107,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -137,11 +137,11 @@ export default function flagSets(fetchMock, t) { fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet('set_1'), {workm: 'on'}, 'only the flag in set_1 can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet('set_2'), {}, 'only the flag in set_1 can be evaluated'); @@ -174,11 +174,11 @@ export default function flagSets(fetchMock, t) { fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet('set_1'), {workm: 'on'}, 'all flags can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet('set_2'), {workm: 'on'}, 'all flags can be evaluated'); diff --git a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js index c2c391d52..285c9a2b6 100644 --- a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js +++ b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js @@ -101,8 +101,8 @@ export default function (fetchMock, assert) { // Mock GET endpoints before creating the client const settings = settingsFactory(config); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, `/mySegments/${encodeURIComponent(config.core.key)}`), { status: 200, body: { mySegments: [] } }); // Init Split client diff --git a/src/__tests__/browserSuites/impressions.debug.spec.js b/src/__tests__/browserSuites/impressions.debug.spec.js index 3a2eeb488..3f8b5e136 100644 --- a/src/__tests__/browserSuites/impressions.debug.spec.js +++ b/src/__tests__/browserSuites/impressions.debug.spec.js @@ -21,8 +21,8 @@ const settings = settingsFactory({ export default function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); const splitio = SplitFactory({ diff --git a/src/__tests__/browserSuites/impressions.none.spec.js b/src/__tests__/browserSuites/impressions.none.spec.js index 89aee3ab0..d71de1428 100644 --- a/src/__tests__/browserSuites/impressions.none.spec.js +++ b/src/__tests__/browserSuites/impressions.none.spec.js @@ -41,8 +41,8 @@ const config = { export default async function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); fetchMock.get(url(settings, '/mySegments/emma%40split.io'), { status: 200, body: mySegmentsFacundo }); diff --git a/src/__tests__/browserSuites/impressions.spec.js b/src/__tests__/browserSuites/impressions.spec.js index 42c85809b..be5a60a33 100644 --- a/src/__tests__/browserSuites/impressions.spec.js +++ b/src/__tests__/browserSuites/impressions.spec.js @@ -24,8 +24,8 @@ let truncatedTimeFrame; export default function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); const splitio = SplitFactory({ diff --git a/src/__tests__/browserSuites/manager.spec.js b/src/__tests__/browserSuites/manager.spec.js index 15b250bab..a5a09ff6d 100644 --- a/src/__tests__/browserSuites/manager.spec.js +++ b/src/__tests__/browserSuites/manager.spec.js @@ -4,7 +4,7 @@ import map from 'lodash/map'; import { url } from '../testUtils'; export default async function (settings, fetchMock, assert) { - fetchMock.getOnce({ url: url(settings, '/splitChanges?s=1.1&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); + fetchMock.getOnce({ url: url(settings, '/splitChanges?s=1.2&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); const mockSplits = splitChangesMockReal; diff --git a/src/__tests__/browserSuites/push-corner-cases.spec.js b/src/__tests__/browserSuites/push-corner-cases.spec.js index bc7e8bb09..61c953e28 100644 --- a/src/__tests__/browserSuites/push-corner-cases.spec.js +++ b/src/__tests__/browserSuites/push-corner-cases.spec.js @@ -71,13 +71,13 @@ export function testSplitKillOnReadyFromCache(fetchMock, assert) { }); // 1 auth request - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }); // 2 mySegments requests: initial sync and after SSE opened fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: { mySegments: [] } }); // 2 splitChanges request: initial sync and after SSE opened. Sync after SPLIT_KILL is not performed because SplitsSyncTask is "executing" - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=25'), { status: 200, body: splitChangesMock1 }, { delay: MILLIS_SPLIT_CHANGES_RESPONSE, /* delay response */ }); - fetchMock.getOnce(url(settings, `/splitChanges?s=1.1&since=${splitChangesMock1.till}`), { status: 200, body: { splits: [], since: splitChangesMock1.till, till: splitChangesMock1.till } }, { delay: MILLIS_SPLIT_CHANGES_RESPONSE - 100, /* delay response */ }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=25'), { status: 200, body: splitChangesMock1 }, { delay: MILLIS_SPLIT_CHANGES_RESPONSE, /* delay response */ }); + fetchMock.getOnce(url(settings, `/splitChanges?s=1.2&since=${splitChangesMock1.till}`), { status: 200, body: { splits: [], since: splitChangesMock1.till, till: splitChangesMock1.till } }, { delay: MILLIS_SPLIT_CHANGES_RESPONSE - 100, /* delay response */ }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/browserSuites/push-fallback.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js index 90f698b5d..80860891f 100644 --- a/src/__tests__/browserSuites/push-fallback.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -211,7 +211,7 @@ export function testFallback(fetchMock, assert) { }); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; @@ -222,17 +222,17 @@ export function testFallback(fetchMock, assert) { fetchMock.get({ url: url(settings, '/myLargeSegments/marcio%40split.io'), repeat: 10 }, { status: 200, body: { myLargeSegments: [] } }); // initial split and mySegment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // fetches due to first fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DOWN_OCCUPANCY + settings.scheduler.featuresRefreshRate), 'fetch due to first fallback to polling'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; @@ -240,34 +240,34 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // split and segment sync due to streaming up (OCCUPANCY event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // creating of second client during streaming: initial mysegment sync, reauth and syncAll due to new client fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); - fetchMock.get({ url: url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}&users=${encodeURIComponent(secondUserKey)}`), repeat: 3 /* initial + 2 STREAMING_RESET */ }, (url, opts) => { + fetchMock.get({ url: url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}&users=${encodeURIComponent(secondUserKey)}`), repeat: 3 /* initial + 2 STREAMING_RESET */ }, (url, opts) => { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('second auth success'); return { status: 200, body: authPushEnabledNicolasAndMarcio }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH), 'sync due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock2 }; }); // fetches due to second fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); // continue fetches due to second fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to second fallback to polling'); return { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }; @@ -276,7 +276,7 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); // split and segment sync due to streaming up (CONTROL event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); @@ -288,17 +288,17 @@ export function testFallback(fetchMock, assert) { }); // fetches due to third fallback to polling (STREAMING_PAUSED), two sync all (two STREAMING_RESET events) and fourth fallback (STREAMING_DISABLED) - fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=1457552649999'), repeat: 4 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=1457552649999'), repeat: 4 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock1 }); fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsMarcio }); // Periodic fetch due to polling (mySegments is not fetched due to smart pausing) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to fourth fallback to polling'); return { status: 200, body: splitChangesMock3 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552669999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552669999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate * 2), 'fetch due to fourth fallback to polling'); return { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }; diff --git a/src/__tests__/browserSuites/push-flag-sets.spec.js b/src/__tests__/browserSuites/push-flag-sets.spec.js index 8898f9759..40cba6ffc 100644 --- a/src/__tests__/browserSuites/push-flag-sets.spec.js +++ b/src/__tests__/browserSuites/push-flag-sets.spec.js @@ -38,19 +38,19 @@ export function testFlagSets(fetchMock, t) { fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); - fetchMock.get(baseUrls.auth + '/v2/auth?s=1.1&users=nicolas%40split.io', function () { + fetchMock.get(baseUrls.auth + '/v2/auth?s=1.2&users=nicolas%40split.io', function () { return { status: 200, body: authPushEnabled }; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: { splits: [], since: -1, till: 0}}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: -1, till: 0 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); @@ -189,7 +189,7 @@ export function testFlagSets(fetchMock, t) { t.test(async (assert) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=2&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=2&sets=set_1,set_2', function () { assert.pass('4 - A fetch is triggered due to the SPLIT_KILL'); return { status: 200, body: { splits: [], since: 2, till: 3 }}; }); @@ -229,7 +229,7 @@ export function testFlagSets(fetchMock, t) { t.test(async (assert) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1&sets=set_1,set_2', function () { assert.pass('5 - A fetch is triggered due to the SPLIT_KILL'); return { status: 200, body: { splits: [], since: 1, till: 5 }}; }); diff --git a/src/__tests__/browserSuites/push-initialization-nopush.spec.js b/src/__tests__/browserSuites/push-initialization-nopush.spec.js index 568739970..63d06ab2c 100644 --- a/src/__tests__/browserSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/browserSuites/push-initialization-nopush.spec.js @@ -46,14 +46,14 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { let start, splitio, client, ready = false; fetchMock.get(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolas }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); if (fallbackToPolling) { - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'polling (first fetch)'); @@ -61,7 +61,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { }); } - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling (second fetch)'); @@ -83,7 +83,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { export function testAuthWithPushDisabled(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(`https://auth.push-initialization-nopush/api/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`, function (url, opts) { + fetchMock.getOnce(`https://auth.push-initialization-nopush/api/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 200, body: authPushDisabled }; @@ -96,7 +96,7 @@ export function testAuthWithPushDisabled(fetchMock, assert) { export function testAuthWith401(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 401, body: authInvalidCredentials }; @@ -122,7 +122,7 @@ export function testSSEWithNonRetryableError(fetchMock, assert) { assert.plan(7); // Auth successes - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth successes'); return { status: 200, body: authPushEnabledNicolas }; diff --git a/src/__tests__/browserSuites/push-initialization-retries.spec.js b/src/__tests__/browserSuites/push-initialization-retries.spec.js index d907d21e8..f2b4e501a 100644 --- a/src/__tests__/browserSuites/push-initialization-retries.spec.js +++ b/src/__tests__/browserSuites/push-initialization-retries.spec.js @@ -51,13 +51,13 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { let start, splitio, client, ready = false; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('first auth attempt'); return { status: 200, body: authPushBadToken }; }); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { throws: new TypeError('Network error') }); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); const lapse = Date.now() - start; const expected = (settings.scheduler.pushRetryBackoffBase * Math.pow(2, 0) + settings.scheduler.pushRetryBackoffBase * Math.pow(2, 1)); @@ -66,23 +66,23 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { }); fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate * 2), 'keep polling since auth success buth with push disabled'); client.destroy().then(() => { @@ -130,30 +130,30 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { sseattempts++; }); - fetchMock.get({ url: url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), repeat: 3 /* 3 push attempts */ }, function (url, opts) { + fetchMock.get({ url: url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), repeat: 3 /* 3 push attempts */ }, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; }); fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, expectedTimeToSSEsuccess), 'sync due to success SSE connection'); client.destroy().then(() => { @@ -189,10 +189,10 @@ export function testSdkDestroyWhileAuthSuccess(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }, { delay: 100 }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }, { delay: 100 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); setTimeout(() => { client.destroy().then(() => { @@ -224,9 +224,9 @@ export function testSdkDestroyWhileConnDelay(fetchMock, assert) { assert.fail('unexpected EventSource request with url: ' + eventSourceInstance.url); }); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { status: 200, body: { ...authPushEnabledNicolas, connDelay: 0.1 } }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: { ...authPushEnabledNicolas, connDelay: 0.1 } }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); const client = SplitFactory(config).client(); setTimeout(() => { @@ -255,12 +255,12 @@ export function testSdkDestroyWhileAuthRetries(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushBadToken }); - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), { throws: new TypeError('Network error') }, { delay: 100 }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushBadToken }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { throws: new TypeError('Network error') }, { delay: 100 }); fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: mySegmentsNicolasMock }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/browserSuites/push-refresh-token.spec.js b/src/__tests__/browserSuites/push-refresh-token.spec.js index d1f929925..848b75d0b 100644 --- a/src/__tests__/browserSuites/push-refresh-token.spec.js +++ b/src/__tests__/browserSuites/push-refresh-token.spec.js @@ -77,22 +77,22 @@ export function testRefreshToken(fetchMock, assert) { }); // initial sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // first auth - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; }); // sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // re-auth due to refresh token, with connDelay of 0.5 seconds - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN), 'reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -100,7 +100,7 @@ export function testRefreshToken(fetchMock, assert) { }); // sync after SSE reopened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'sync after SSE connection is reopened'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; @@ -108,7 +108,7 @@ export function testRefreshToken(fetchMock, assert) { fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // second re-auth due to refresh token, this time responding with pushEnabled false - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'second reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -116,7 +116,7 @@ export function testRefreshToken(fetchMock, assert) { }); // split sync after SSE closed due to push disabled - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'sync after SSE connection is reopened a second time'); setTimeout(() => { diff --git a/src/__tests__/browserSuites/push-synchronization-retries.spec.js b/src/__tests__/browserSuites/push-synchronization-retries.spec.js index c7031b7c9..b0a0af372 100644 --- a/src/__tests__/browserSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/browserSuites/push-synchronization-retries.spec.js @@ -135,19 +135,19 @@ export function testSynchronizationRetries(fetchMock, assert) { }); // initial auth - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&users=${encodeURIComponent(userKey)}&users=${encodeURIComponent(otherUserKeySync)}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}&users=${encodeURIComponent(otherUserKeySync)}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; }); // initial split and mySegments sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 2 }, { status: 200, body: mySegmentsMarcio }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); return { status: 200, body: splitChangesMock2 }; @@ -155,9 +155,9 @@ export function testSynchronizationRetries(fetchMock, assert) { fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); // fetch retry for SPLIT_UPDATE event, due to previous unexpected response (response till minor than SPLIT_UPDATE changeNumber) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_RETRY_FOR_FIRST_SPLIT_UPDATE_EVENT), 'fetch retry due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock3 }; @@ -177,18 +177,18 @@ export function testSynchronizationRetries(fetchMock, assert) { }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { assert.equal(client.getTreatment('whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_KILL_EVENT), 'sync due to SPLIT_KILL event'); return { status: 200, body: { since: 1457552649999, till: 1457552649999, splits: [] } }; // returning old state }); // first fetch retry for SPLIT_KILL event, due to previous unexpected response (response till minor than SPLIT_KILL changeNumber) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { throws: new TypeError('Network error') }); // second fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response // third fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT), 'third fetch retry due to SPLIT_KILL event'); diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index b9e99a439..8ac362fd8 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -300,7 +300,7 @@ export function testSynchronization(fetchMock, assert) { // initial auth let authParams = `users=${encodeURIComponent(userKey)}`; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&${authParams}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&${authParams}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; @@ -308,7 +308,7 @@ export function testSynchronization(fetchMock, assert) { // reauth due to new client authParams += `&users=${encodeURIComponent(otherUserKey)}`; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&${authParams}`), function (url, opts) { + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&${authParams}`), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('second auth success'); return { status: 200, body: authPushEnabledNicolasAndMarcio }; @@ -316,10 +316,10 @@ export function testSynchronization(fetchMock, assert) { // reauth due to more clients authParams += `&users=${encodeURIComponent(keylistAddKey)}&users=${encodeURIComponent(keylistRemoveKey)}&users=${encodeURIComponent(bitmapTrueKey)}`; - fetchMock.getOnce(url(settings, `/v2/auth?s=1.1&${authParams}`), { status: 200, body: authPushEnabledNicolasAndMarcio }); + fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&${authParams}`), { status: 200, body: authPushEnabledNicolasAndMarcio }); // initial sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -332,7 +332,7 @@ export function testSynchronization(fetchMock, assert) { fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -345,7 +345,7 @@ export function testSynchronization(fetchMock, assert) { fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock3 }; }); @@ -357,7 +357,7 @@ export function testSynchronization(fetchMock, assert) { }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); assert.equal(client.getTreatment('whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); return { status: 200, body: splitChangesMock4 }; @@ -372,7 +372,7 @@ export function testSynchronization(fetchMock, assert) { // sync after second SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SECOND_SSE_OPEN), 'sync after second SSE connection is opened'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -400,7 +400,7 @@ export function testSynchronization(fetchMock, assert) { }); // initial fetch of mySegments and myLargeSegments for other clients + sync after third SSE opened + 3 unbounded fetch requests for mySegments - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); fetchMock.get({ url: url(settings, '/mySegments/key1'), repeat: 5 }, { status: 200, body: { mySegments: [] } }); fetchMock.get({ url: url(settings, '/mySegments/key3'), repeat: 5 }, { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); fetchMock.get({ url: url(settings, `/mySegments/${bitmapTrueKey}`), repeat: 5 }, { status: 200, body: { mySegments: [] } }); diff --git a/src/__tests__/browserSuites/readiness-large-segments.spec.js b/src/__tests__/browserSuites/readiness-large-segments.spec.js index 8146842e0..def7007c0 100644 --- a/src/__tests__/browserSuites/readiness-large-segments.spec.js +++ b/src/__tests__/browserSuites/readiness-large-segments.spec.js @@ -110,8 +110,8 @@ export default function (fetchMock, assert) { const shouldEmitSdkUpdate = waitForLargeSegments === false && featureFlagsWithLS === true && (LARGE_SEGMENTS_DELAY > SEGMENTS_DELAY || featureFlagsWithSegments === false); assert.test(t => { - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { since: 1457552620999, till: 1457552620999, splits: [] } }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { since: 1457552620999, till: 1457552620999, splits: [] } }); fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: mySegments }, { delay: SEGMENTS_DELAY }); fetchMock.getOnce(config.urls.sdk + '/myLargeSegments/emi%40split.io', { status: myLargeSegmentsForbidden ? 403 : 200, body: myLargeSegments }, { delay: LARGE_SEGMENTS_DELAY }); diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 024ff8277..8f0c6ef8e 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -38,13 +38,13 @@ export default function (fetchMock, assert) { sdk: 'https://sdk.baseurl/readinessSuite1', events: 'https://events.baseurl/readinessSuite1' }; - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); const splitio = SplitFactory({ ...baseConfig, urls: testUrls @@ -67,13 +67,13 @@ export default function (fetchMock, assert) { sdk: 'https://sdk.baseurl/readinessSuite2', events: 'https://events.baseurl/readinessSuite2' }; - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); const splitio = SplitFactory({ ...baseConfig, urls: testUrls }); const client = splitio.client(); @@ -95,16 +95,16 @@ export default function (fetchMock, assert) { events: 'https://events.baseurl/readinessSuite3' }; - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); }); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); // Faster, it should get ready on the retry. }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); const splitio = SplitFactory({ ...baseConfig, urls: testUrls }); const client = splitio.client(); @@ -130,18 +130,18 @@ export default function (fetchMock, assert) { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: { mySegments: [] } }); }, mySegmentsEndpointDelay); }); }); // Now mock the no more updates state - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552669999', { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }); if (startWithSegments) { // Adjust since and till so the order is inverted. - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesStartWithSegmentsMock }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { ...splitChangesUpdateWithoutSegmentsMock, since: 1457552620999, till: 1457552649999 } }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552649999', { status: 200, body: { ...splitChangesUpdateWithSegmentsMock, since: 1457552649999, till: 1457552669999 } }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesStartWithSegmentsMock }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { ...splitChangesUpdateWithoutSegmentsMock, since: 1457552620999, till: 1457552649999 } }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552649999', { status: 200, body: { ...splitChangesUpdateWithSegmentsMock, since: 1457552649999, till: 1457552669999 } }); } else { - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesStartWithoutSegmentsMock }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesUpdateWithSegmentsMock }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552649999', { status: 200, body: splitChangesUpdateWithoutSegmentsMock }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesStartWithoutSegmentsMock }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesUpdateWithSegmentsMock }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552649999', { status: 200, body: splitChangesUpdateWithoutSegmentsMock }); } return () => mySegmentsHits; @@ -562,8 +562,8 @@ export default function (fetchMock, assert) { const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); // I'm having the first update of Splits come with segments. In this scenario it'll wait for mySegments to download before being ready. - fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.1&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithSegmentsMock, since: 1457552669999, till: 1457552679999 } }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); + fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithSegmentsMock, since: 1457552669999, till: 1457552679999 } }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); const start = Date.now(); const splitio = SplitFactory({ @@ -659,8 +659,8 @@ export default function (fetchMock, assert) { }; const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); // I'm having the first update of Splits come without segments. In this scenario it'll NOT wait for mySegments to download before being ready. - fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.1&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithoutSegmentsMock, since: 1457552669999, till: 1457552679999 } }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); + fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithoutSegmentsMock, since: 1457552669999, till: 1457552679999 } }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); const start = Date.now(); const splitio = SplitFactory({ diff --git a/src/__tests__/browserSuites/ready-from-cache.spec.js b/src/__tests__/browserSuites/ready-from-cache.spec.js index 70eb2cda9..36c0adf87 100644 --- a/src/__tests__/browserSuites/ready-from-cache.spec.js +++ b/src/__tests__/browserSuites/ready-from-cache.spec.js @@ -83,8 +83,8 @@ const baseConfig = { streamingEnabled: false }; -const expectedHashNullFilter = '2a2c20bb'; // for SDK key '', filter query null, and flags spec version '1.1' -const expectedHashWithFilter = 'fdf7bd89'; // for SDK key '', filter query '&names=p1__split,p2__split', and flags spec version '1.1' +const expectedHashNullFilter = 'db8943b4'; // for SDK key '', filter query null, and flags spec version '1.2' +const expectedHashWithFilter = '7ccd6b31'; // for SDK key '', filter query '&names=p1__split,p2__split', and flags spec version '1.2' export default function (fetchMock, assert) { @@ -96,8 +96,8 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(3); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: mySegmentsNicolas }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas2%40split.io', { status: 200, body: { 'mySegments': [] } }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas3%40split.io', { status: 200, body: { 'mySegments': [] } }); @@ -147,10 +147,10 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(12 * 2 + 3); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=25', function () { + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=25', function () { return new Promise(res => { setTimeout(() => res({ status: 200, body: { ...splitChangesMock1, since: 25 }, headers: {} }), 200); }); // 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that. }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); @@ -255,11 +255,11 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(12 * 2 + 5); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=25', function () { + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=25', function () { t.equal(localStorage.getItem('readyFromCache_3.SPLITIO.split.always_on'), alwaysOnSplitInverted, 'feature flags must not be cleaned from cache'); return new Promise(res => { setTimeout(() => res({ status: 200, body: { ...splitChangesMock1, since: 25 }, headers: {} }), 200); }); // 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that. }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); @@ -372,13 +372,13 @@ export default function (fetchMock, assert) { }; localStorage.clear(); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { t.equal(localStorage.getItem('some_user_item'), 'user_item', 'user items at localStorage must not be changed'); t.equal(localStorage.getItem('readyFromCache_4.SPLITIO.hash'), expectedHashNullFilter, 'storage hash must not be changed'); t.equal(localStorage.length, 2, 'feature flags cache data must be cleaned from localStorage'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.get(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); @@ -488,8 +488,8 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(7); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - // fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999&names=p1__split', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + // fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999&names=p1__split', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); localStorage.setItem('some_user_item', 'user_item'); @@ -541,7 +541,7 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(5); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); const splitio = SplitFactory({ @@ -585,10 +585,10 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(7); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=25&names=p2__split&prefixes=p1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: 25, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=25&names=p2__split&prefixes=p1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: 25, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); - const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=p2__split&prefixes=p1' }, flagSpecVersion: '1.1' } }); + const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=p2__split&prefixes=p1' }, flagSpecVersion: '1.2' } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_6.SPLITIO.splits.till', 25); localStorage.setItem('readyFromCache_6.SPLITIO.split.p1__split', JSON.stringify(splitDeclarations.p1__split)); @@ -636,10 +636,10 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(6); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1&prefixes=p1,p2', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&prefixes=p1,p2', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); - const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&prefixes=p1,p2' }, flagSpecVersion: '1.1' } }); + const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&prefixes=p1,p2' }, flagSpecVersion: '1.2' } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_7.SPLITIO.splits.till', 25); localStorage.setItem('readyFromCache_7.SPLITIO.split.p1__split', JSON.stringify(splitDeclarations.p1__split)); @@ -702,7 +702,7 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(7); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); localStorage.setItem('some_user_item', 'user_item'); @@ -756,14 +756,14 @@ export default function (fetchMock, assert) { localStorage.clear(); t.plan(6); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1&names=no%20exist%20trim,no_exist,p3__split&prefixes=no%20exist%20trim,p2', { status: 200, body: { splits: [splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=no%20exist%20trim,no_exist,p3__split&prefixes=no%20exist%20trim,p2', { status: 200, body: { splits: [splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_9.SPLITIO.splits.till', 25); localStorage.setItem('readyFromCache_9.SPLITIO.split.p1__split', JSON.stringify(splitDeclarations.p1__split)); localStorage.setItem('readyFromCache_9.SPLITIO.split.p2__split', JSON.stringify(splitDeclarations.p2__split)); - localStorage.setItem('readyFromCache_9.SPLITIO.hash', getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=p2__split&prefixes=p1' }, flagSpecVersion: '1.1' } })); + localStorage.setItem('readyFromCache_9.SPLITIO.hash', getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=p2__split&prefixes=p1' }, flagSpecVersion: '1.2' } })); const splitio = SplitFactory({ ...baseConfig, @@ -788,7 +788,7 @@ export default function (fetchMock, assert) { t.equal(localStorage.getItem('readyFromCache_9.SPLITIO.splits.till'), '1457552620999', 'splits.till must correspond to the till of the last successfully fetched Splits'); t.equal(localStorage.getItem('readyFromCache_9.SPLITIO.split.p2__split'), JSON.stringify(splitDeclarations.p2__split), 'feature flag declarations must be cached'); t.equal(localStorage.getItem('readyFromCache_9.SPLITIO.split.p3__split'), JSON.stringify(splitDeclarations.p3__split), 'feature flag declarations must be cached'); - t.equal(localStorage.getItem('readyFromCache_9.SPLITIO.hash'), getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=no%20exist%20trim,no_exist,p3__split&prefixes=no%20exist%20trim,p2' }, flagSpecVersion: '1.1' } }), 'Storage hash must correspond to the split filter query and SDK key'); + t.equal(localStorage.getItem('readyFromCache_9.SPLITIO.hash'), getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=no%20exist%20trim,no_exist,p3__split&prefixes=no%20exist%20trim,p2' }, flagSpecVersion: '1.2' } }), 'Storage hash must correspond to the split filter query and SDK key'); t.end(); }); }); diff --git a/src/__tests__/browserSuites/ready-promise.spec.js b/src/__tests__/browserSuites/ready-promise.spec.js index 56ac7922e..6d54d1432 100644 --- a/src/__tests__/browserSuites/ready-promise.spec.js +++ b/src/__tests__/browserSuites/ready-promise.spec.js @@ -59,8 +59,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -107,8 +107,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -157,8 +157,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -226,12 +226,12 @@ export default function readyPromiseAssertions(fetchMock, assert) { config.scheduler.featuresRefreshRate) - config.startup.readyTimeout) + refreshTimeMillis; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both initial attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); // main client endpoint configured to fetch segments before request timeout fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=1457552620999', { splits: [], since: 1457552620999, till: 1457552620999 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=1457552620999', { splits: [], since: 1457552620999, till: 1457552620999 }); // shared client endpoint configured to fetch segments immediately, in order to emit SDK_READY as soon as splits arrives fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo); // shared client endpoint configured to emit SDK_READY_TIMED_OUT @@ -310,7 +310,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -360,7 +360,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // Both /splitChanges and /mySegments take less than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -407,8 +407,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -496,8 +496,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo); fetchMock.get(config.urls.sdk + '/mySegments/emiliano%40split.io', mySegmentsFacundo); @@ -581,7 +581,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); diff --git a/src/__tests__/browserSuites/single-sync.spec.js b/src/__tests__/browserSuites/single-sync.spec.js index 19e46db52..b7ae61757 100644 --- a/src/__tests__/browserSuites/single-sync.spec.js +++ b/src/__tests__/browserSuites/single-sync.spec.js @@ -36,7 +36,7 @@ const settings = settingsFactory(config); export default function singleSync(fetchMock, assert) { - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { assert.pass('first splitChanges fetch'); return { status: 200, body: splitChangesMock1 }; }); diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 39be3e20f..08fd69571 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -33,8 +33,8 @@ const SplitFactoryForTest = (config) => { export default async function telemetryBrowserSuite(fetchMock, t) { t.test(async (assert) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', 500); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', 500); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', 500); fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', { status: 200, body: { 'mySegments': ['one_segment'] } }); @@ -188,7 +188,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { const splitFilters = [{ type: 'bySet', values: ['a', '_b', 'a', 'a', 'c', 'd', '_d'] }]; fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=a,c,d', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=a,c,d', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/config', (url, opts) => { const data = JSON.parse(opts.body); diff --git a/src/__tests__/browserSuites/use-beacon-api.debug.spec.js b/src/__tests__/browserSuites/use-beacon-api.debug.spec.js index 2dede6e28..7e673afff 100644 --- a/src/__tests__/browserSuites/use-beacon-api.debug.spec.js +++ b/src/__tests__/browserSuites/use-beacon-api.debug.spec.js @@ -66,8 +66,8 @@ function beaconApiNotSendTestDebug(fetchMock, assert) { sendBeaconSpyDebug = sinon.spy(window.navigator, 'sendBeacon'); // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); // Init and run Split client diff --git a/src/__tests__/browserSuites/use-beacon-api.spec.js b/src/__tests__/browserSuites/use-beacon-api.spec.js index 9065cfd61..ed08eb8e2 100644 --- a/src/__tests__/browserSuites/use-beacon-api.spec.js +++ b/src/__tests__/browserSuites/use-beacon-api.spec.js @@ -78,8 +78,8 @@ function beaconApiNotSendTest(fetchMock, assert) { sendBeaconSpy = sinon.spy(window.navigator, 'sendBeacon'); // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); // Init and run Split client diff --git a/src/__tests__/destroy/browser.spec.js b/src/__tests__/destroy/browser.spec.js index 5cbf88fa5..b7df518c7 100644 --- a/src/__tests__/destroy/browser.spec.js +++ b/src/__tests__/destroy/browser.spec.js @@ -18,8 +18,8 @@ const settings = settingsFactory({ streamingEnabled: false }); -fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); -fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }); +fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); +fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); fetchMock.getOnce(url(settings, '/mySegments/ut1'), { status: 200, body: mySegmentsMock }); fetchMock.getOnce(url(settings, '/mySegments/ut2'), { status: 200, body: mySegmentsMock }); fetchMock.getOnce(url(settings, '/mySegments/ut3'), { status: 200, body: mySegmentsMock }); diff --git a/src/__tests__/destroy/node.spec.js b/src/__tests__/destroy/node.spec.js index 7f9f9b541..13fe4dc7c 100644 --- a/src/__tests__/destroy/node.spec.js +++ b/src/__tests__/destroy/node.spec.js @@ -17,8 +17,8 @@ import splitChangesMock1 from '../mocks/splitChanges.since.-1.till.1500492097547 import splitChangesMock2 from '../mocks/splitChanges.since.1500492097547.json'; import impressionsMock from '../mocks/impressions.json'; -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); tape('SDK destroy for NodeJS', async function (assert) { diff --git a/src/__tests__/errorCatching/browser.spec.js b/src/__tests__/errorCatching/browser.spec.js index c5719ed3b..25315666d 100644 --- a/src/__tests__/errorCatching/browser.spec.js +++ b/src/__tests__/errorCatching/browser.spec.js @@ -21,13 +21,13 @@ const settings = settingsFactory({ // prepare localstorage to emit SDK_READY_FROM_CACHE localStorage.clear(); localStorage.setItem('SPLITIO.splits.till', 25); -localStorage.setItem('SPLITIO.hash', getStorageHash({ core: { authorizationKey: '' }, sync: { __splitFiltersValidation: { queryString: null }, flagSpecVersion: '1.1' } })); +localStorage.setItem('SPLITIO.hash', getStorageHash({ core: { authorizationKey: '' }, sync: { __splitFiltersValidation: { queryString: null }, flagSpecVersion: '1.2' } })); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=25'), function () { +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=25'), function () { return new Promise((res) => { setTimeout(() => res({ status: 200, body: splitChangesMock1 }), 1000); }); }); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492297547'), { status: 200, body: splitChangesMock3 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492297547'), { status: 200, body: splitChangesMock3 }); fetchMock.get(url(settings, '/mySegments/nico%40split.io'), { status: 200, body: mySegmentsMock }); fetchMock.post('*', 200); diff --git a/src/__tests__/errorCatching/node.spec.js b/src/__tests__/errorCatching/node.spec.js index b7838685a..dc2a3db70 100644 --- a/src/__tests__/errorCatching/node.spec.js +++ b/src/__tests__/errorCatching/node.spec.js @@ -21,9 +21,9 @@ const settings = settingsFactory({ streamingEnabled: false }); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }, responseDelay); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }, responseDelay); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492297547'), { status: 200, body: splitChangesMock3 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492297547'), { status: 200, body: splitChangesMock3 }, responseDelay); fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); // SDK_READY fetchMock.postOnce(url(settings, '/v1/metrics/usage'), 200); // SDK destroyed diff --git a/src/__tests__/gaIntegration/browser.spec.js b/src/__tests__/gaIntegration/browser.spec.js index c97a2922b..3eb6b3144 100644 --- a/src/__tests__/gaIntegration/browser.spec.js +++ b/src/__tests__/gaIntegration/browser.spec.js @@ -18,7 +18,7 @@ const settings = settingsFactory({ tape('## E2E CI Tests ##', function (assert) { - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); fetchMock.post(/\/v1\/metrics/, 200); // 0.1% sample rate diff --git a/src/__tests__/nodeSuites/evaluations-semver.spec.js b/src/__tests__/nodeSuites/evaluations-semver.spec.js index 5885a2b16..5f75d481f 100644 --- a/src/__tests__/nodeSuites/evaluations-semver.spec.js +++ b/src/__tests__/nodeSuites/evaluations-semver.spec.js @@ -24,8 +24,8 @@ const config = { export default async function (fetchMock, assert) { - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); const splitio = SplitFactory(config); const client = splitio.client(); diff --git a/src/__tests__/nodeSuites/expected-treatments.spec.js b/src/__tests__/nodeSuites/expected-treatments.spec.js index 552db56b3..918a533c8 100644 --- a/src/__tests__/nodeSuites/expected-treatments.spec.js +++ b/src/__tests__/nodeSuites/expected-treatments.spec.js @@ -6,7 +6,7 @@ import { url } from '../testUtils'; import splitChangesMockReal from '../mocks/splitchanges.real.json'; export default async function (config, settings, fetchMock, assert) { - fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); const splitio = SplitFactory({ ...config, diff --git a/src/__tests__/nodeSuites/fetch-specific-splits.spec.js b/src/__tests__/nodeSuites/fetch-specific-splits.spec.js index 35d96d26d..0f67253c3 100644 --- a/src/__tests__/nodeSuites/fetch-specific-splits.spec.js +++ b/src/__tests__/nodeSuites/fetch-specific-splits.spec.js @@ -23,9 +23,9 @@ export function fetchSpecificSplits(fetchMock, assert) { const queryString = queryStrings[i] || ''; let factory; - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, function () { + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, function () { factory.client().destroy().then(() => { assert.pass(`splitFilters #${i}`); }); @@ -64,8 +64,8 @@ export function fetchSpecificSplitsForFlagSets(fetchMock, assert) { let factory; const queryString = '&sets=4_valid,set_2,set_3,set_ww,set_x'; - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, async function () { t.pass('flag set query correctly formed'); factory.client().destroy().then(() => { t.end(); diff --git a/src/__tests__/nodeSuites/flag-sets.spec.js b/src/__tests__/nodeSuites/flag-sets.spec.js index e8dd725e0..fafbdb8cb 100644 --- a/src/__tests__/nodeSuites/flag-sets.spec.js +++ b/src/__tests__/nodeSuites/flag-sets.spec.js @@ -26,12 +26,12 @@ export default function flagSets(fetchMock, t) { let factory, manager, client = []; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1, 'only one feature flag should be added'); @@ -43,7 +43,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1); @@ -54,7 +54,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344&sets=set_1,set_2', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344&sets=set_1,set_2', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 0, 'the feature flag should be removed'); @@ -79,12 +79,12 @@ export default function flagSets(fetchMock, t) { let factory, manager, client = []; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2, 'every feature flag should be added'); @@ -98,7 +98,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -111,7 +111,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -142,11 +142,11 @@ export default function flagSets(fetchMock, t) { mockSegmentChanges(fetchMock, new RegExp(baseUrls.sdk + '/segmentChanges/*'), []); fetchMock.post('*', 200); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_1'), {workm: 'on'}, 'only the flag in set_1 can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_2'), {}, 'only the flag in set_1 can be evaluated'); @@ -180,11 +180,11 @@ export default function flagSets(fetchMock, t) { fetchMock.post('*', 200); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_1'), {workm: 'on'}, 'all flags can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_2'), {workm: 'on'}, 'all flags can be evaluated'); diff --git a/src/__tests__/nodeSuites/impressions.debug.spec.js b/src/__tests__/nodeSuites/impressions.debug.spec.js index 9d09415c0..cfab6e7c0 100644 --- a/src/__tests__/nodeSuites/impressions.debug.spec.js +++ b/src/__tests__/nodeSuites/impressions.debug.spec.js @@ -40,8 +40,8 @@ const config = { export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/impressions.none.spec.js b/src/__tests__/nodeSuites/impressions.none.spec.js index 4c726bca4..d664b6dbd 100644 --- a/src/__tests__/nodeSuites/impressions.none.spec.js +++ b/src/__tests__/nodeSuites/impressions.none.spec.js @@ -39,8 +39,8 @@ const config = { export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/impressions.spec.js b/src/__tests__/nodeSuites/impressions.spec.js index b5fb102a7..4f3b364dd 100644 --- a/src/__tests__/nodeSuites/impressions.spec.js +++ b/src/__tests__/nodeSuites/impressions.spec.js @@ -37,8 +37,8 @@ let truncatedTimeFrame; export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js index 674873ad4..2103f78c3 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js @@ -77,8 +77,8 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { })(); // Mock GET endpoints to run client normally - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); // Mock and assert POST endpoints diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js index 2fbf92f12..49e29e505 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js @@ -121,8 +121,8 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { })(); // Mock GET endpoints to run client normally - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); // Mock and assert POST endpoints diff --git a/src/__tests__/nodeSuites/manager.spec.js b/src/__tests__/nodeSuites/manager.spec.js index 00a707dc9..378ad018d 100644 --- a/src/__tests__/nodeSuites/manager.spec.js +++ b/src/__tests__/nodeSuites/manager.spec.js @@ -4,7 +4,7 @@ import map from 'lodash/map'; import { url } from '../testUtils'; export default async function (settings, fetchMock, assert) { - fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); const mockSplits = splitChangesMockReal; diff --git a/src/__tests__/nodeSuites/push-fallback.spec.js b/src/__tests__/nodeSuites/push-fallback.spec.js index 7789236a1..863e475f3 100644 --- a/src/__tests__/nodeSuites/push-fallback.spec.js +++ b/src/__tests__/nodeSuites/push-fallback.spec.js @@ -190,26 +190,26 @@ export function testFallback(fetchMock, assert) { }); - fetchMock.get({ url: url(settings, '/v2/auth?s=1.1'), repeat: 3 /* initial + 2 STREAMING_RESET */ }, function (url, opts) { + fetchMock.get({ url: url(settings, '/v2/auth?s=1.2'), repeat: 3 /* initial + 2 STREAMING_RESET */ }, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=-1'), { status: 200, body: { since: -1, till: 1457552620999, name: 'employees', added: [key], removed: [] } }); // extra retry due to double request (greedy fetch until since === till) fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // fetches due to first fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DOWN_OCCUPANCY + settings.scheduler.featuresRefreshRate), 'fetch due to first fallback to polling'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; @@ -217,22 +217,22 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // split and segment sync due to streaming up (OCCUPANCY event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552621999, name: 'employees', added: ['other_key'], removed: [] } }); // extra retry due to double request (greedy fetch until since === till) fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH), 'sync due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock2 }; }); // fetches due to second fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to second fallback to polling'); return { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }; @@ -240,7 +240,7 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // split and segment sync due to streaming up (CONTROL event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // fetch due to SEGMENT_UPDATE event @@ -249,19 +249,19 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); // Fetches due to third fallback to polling (second STREAMING_PAUSED event) and two syncAll ( SSE opened twice due to two STREAMING_RESET events) - fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=1457552649999'), repeat: 3 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=1457552649999'), repeat: 3 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.get({ url: url(settings, '/segmentChanges/employees?since=1457552650000'), repeat: 3 }, { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); // fetches due to fourth fallback to polling due to STREAMING_DISABLED event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to fourth fallback to polling'); return { status: 200, body: splitChangesMock3 }; }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552669999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552669999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate * 2), 'fetch due to third fallback to polling'); return { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }; diff --git a/src/__tests__/nodeSuites/push-flag-sets.spec.js b/src/__tests__/nodeSuites/push-flag-sets.spec.js index d8beb05ac..8cb7c0472 100644 --- a/src/__tests__/nodeSuites/push-flag-sets.spec.js +++ b/src/__tests__/nodeSuites/push-flag-sets.spec.js @@ -39,21 +39,21 @@ export function testFlagSets(fetchMock, t) { mockSegmentChanges(fetchMock, new RegExp(baseUrls.sdk + '/segmentChanges/*'), ['some-key']); fetchMock.post('*', 200); - fetchMock.get(baseUrls.auth + '/v2/auth?s=1.1', function (url, opts) { + fetchMock.get(baseUrls.auth + '/v2/auth?s=1.2', function (url, opts) { if (!opts.headers['Authorization']) t.fail('`/v2/auth` request must include `Authorization` header'); t.pass('auth success'); return { status: 200, body: authPushEnabled }; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: { splits: [], since: -1, till: 0}}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: -1, till: 0 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); @@ -194,7 +194,7 @@ export function testFlagSets(fetchMock, t) { setMockListener((eventSourceInstance) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=2&sets=set_1,set_2', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=2&sets=set_1,set_2', async function () { assert.pass('4 - A fetch is triggered due to the SPLIT_KILL'); await client.destroy(); assert.end(); @@ -232,7 +232,7 @@ export function testFlagSets(fetchMock, t) { t.test(async (assert) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1&sets=set_1,set_2', function () { assert.pass('5 - A fetch is triggered due to the SPLIT_KILL'); return { status: 200, body: { splits: [], since: 1, till: 5 }}; }); diff --git a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js index b79db1f1f..d1baa10df 100644 --- a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js @@ -42,7 +42,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; // using a higher error margin for Travis, due to a lower performance than local execution assert.true(nearlyEqual(lapse, 0), 'initial sync'); @@ -50,7 +50,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { }); if (fallbackToPolling) { - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0, 100), 'polling (first fetch)'); @@ -58,7 +58,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { }); } - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate, 100), 'polling (second fetch)'); @@ -80,7 +80,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { export function testAuthWithPushDisabled(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce('https://auth.push-initialization-nopush/api/v2/auth?s=1.1', function (url, opts) { + fetchMock.getOnce('https://auth.push-initialization-nopush/api/v2/auth?s=1.2', function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 200, body: authPushDisabled }; @@ -93,7 +93,7 @@ export function testAuthWithPushDisabled(fetchMock, assert) { export function testAuthWith401(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 401, body: authInvalidCredentials }; @@ -106,7 +106,7 @@ export function testAuthWith401(fetchMock, assert) { export function testAuthWith400(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 400, body: authNoUserSpecified }; @@ -131,7 +131,7 @@ export function testSSEWithNonRetryableError(fetchMock, assert) { assert.plan(7); // Auth successes - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth successes'); return { status: 200, body: authPushEnabled }; diff --git a/src/__tests__/nodeSuites/push-initialization-retries.spec.js b/src/__tests__/nodeSuites/push-initialization-retries.spec.js index 54c681f18..ace87370e 100644 --- a/src/__tests__/nodeSuites/push-initialization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-retries.spec.js @@ -45,13 +45,13 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { let start, splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('first auth attempt'); return { status: 200, body: authPushBadToken }; }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { throws: new TypeError('Network error') }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); const lapse = Date.now() - start; const expected = (settings.scheduler.pushRetryBackoffBase * Math.pow(2, 0) + settings.scheduler.pushRetryBackoffBase * Math.pow(2, 1)); @@ -60,23 +60,23 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate * 2), 'keep polling since auth success buth with push disabled'); client.destroy().then(() => { @@ -122,30 +122,30 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { sseattempts++; }); - fetchMock.get({ url: url(settings, '/v2/auth?s=1.1'), repeat: 3 /* 3 push attempts */ }, function (url, opts) { + fetchMock.get({ url: url(settings, '/v2/auth?s=1.2'), repeat: 3 /* 3 push attempts */ }, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, expectedTimeToSSEsuccess), 'sync due to success SSE connection'); client.destroy().then(() => { @@ -181,10 +181,10 @@ export function testSdkDestroyWhileAuthSuccess(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { status: 200, body: authPushEnabled }, { delay: 100 }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { status: 200, body: authPushEnabled }, { delay: 100 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); setTimeout(() => { client.destroy().then(() => { @@ -219,12 +219,12 @@ export function testSdkDestroyWhileAuthRetries(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { status: 200, body: authPushBadToken }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { throws: new TypeError('Network error') }, { delay: 100 }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { status: 200, body: authPushBadToken }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { throws: new TypeError('Network error') }, { delay: 100 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/nodeSuites/push-refresh-token.spec.js b/src/__tests__/nodeSuites/push-refresh-token.spec.js index b3246a2c4..ed030806f 100644 --- a/src/__tests__/nodeSuites/push-refresh-token.spec.js +++ b/src/__tests__/nodeSuites/push-refresh-token.spec.js @@ -77,20 +77,20 @@ export function testRefreshToken(fetchMock, assert) { }); // initial split sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); // first auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // split sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); // re-auth due to refresh token, with connDelay of 0.5 seconds - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN), 'reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -98,14 +98,14 @@ export function testRefreshToken(fetchMock, assert) { }); // split sync after SSE reopened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'sync after SSE connection is reopened'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; }); // second re-auth due to refresh token, this time responding with pushEnabled false - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'second reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -113,7 +113,7 @@ export function testRefreshToken(fetchMock, assert) { }); // split sync after SSE closed due to push disabled - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'sync after SSE connection is reopened a second time'); setTimeout(() => { diff --git a/src/__tests__/nodeSuites/push-synchronization-retries.spec.js b/src/__tests__/nodeSuites/push-synchronization-retries.spec.js index e1154e9d6..147e18f3b 100644 --- a/src/__tests__/nodeSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization-retries.spec.js @@ -126,14 +126,14 @@ export function testSynchronizationRetries(fetchMock, assert) { }); // initial auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/segmentChanges/splitters?since=-1'), { status: 200, body: { since: -1, till: 1457552620999, name: 'splitters', added: [key], removed: [] } } ); @@ -143,7 +143,7 @@ export function testSynchronizationRetries(fetchMock, assert) { ); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); return { status: 200, body: splitChangesMock2 }; @@ -153,9 +153,9 @@ export function testSynchronizationRetries(fetchMock, assert) { ); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { throws: new TypeError('Network error') }); // fetch retry for SPLIT_UPDATE event, due to previous fail - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_RETRY_FOR_FIRST_SPLIT_UPDATE_EVENT), 'fetch retry due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock3 }; @@ -182,18 +182,18 @@ export function testSynchronizationRetries(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/splitters?since=1457552640000'), { status: 200, body: { since: 1457552640000, till: 1457552640000, name: 'splitters', added: [], removed: [] } }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { assert.equal(client.getTreatment(key, 'whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_KILL_EVENT), 'sync due to SPLIT_KILL event'); return { status: 200, body: { since: 1457552649999, till: 1457552649999, splits: [] } }; // returning old state }); // first fetch retry for SPLIT_KILL event, due to previous unexpected response (response till minor than SPLIT_KILL changeNumber) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON // second fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { throws: new TypeError('Network error') }); // third fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT), 'third fetch retry due to SPLIT_KILL event'); diff --git a/src/__tests__/nodeSuites/push-synchronization.spec.js b/src/__tests__/nodeSuites/push-synchronization.spec.js index 954f8a560..cb60de633 100644 --- a/src/__tests__/nodeSuites/push-synchronization.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization.spec.js @@ -218,14 +218,14 @@ export function testSynchronization(fetchMock, assert) { }); // initial auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -242,7 +242,7 @@ export function testSynchronization(fetchMock, assert) { }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -254,7 +254,7 @@ export function testSynchronization(fetchMock, assert) { }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock3 }; }); @@ -271,14 +271,14 @@ export function testSynchronization(fetchMock, assert) { }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); assert.equal(client.getTreatment(key, 'whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); return { status: 200, body: splitChangesMock4 }; }); // fetch due to SPLIT_UPDATE event, with an update that involves a new segment - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock5 }; }); @@ -289,25 +289,25 @@ export function testSynchronization(fetchMock, assert) { }); // fetch feature flags due to IFFU SPLIT_UPDATE event with wrong compress code - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694505'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694505'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock6 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with previous change number = 0 - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694506'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694506'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock7 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with previous change number !== current change number - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694526'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694526'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock8 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with ARCHIVED feature flag - fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694546'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694546'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock9 }; }); diff --git a/src/__tests__/nodeSuites/readiness.spec.js b/src/__tests__/nodeSuites/readiness.spec.js index 519571ea3..e11026faa 100644 --- a/src/__tests__/nodeSuites/readiness.spec.js +++ b/src/__tests__/nodeSuites/readiness.spec.js @@ -23,8 +23,8 @@ export default function (fetchMock, assert) { events: 'https://events.baseurl/readinessSuite1' }; - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(testUrls.sdk + '/segmentChanges/*'), 403); fetchMock.postOnce(testUrls.events + '/events/bulk', 200); diff --git a/src/__tests__/nodeSuites/ready-promise.spec.js b/src/__tests__/nodeSuites/ready-promise.spec.js index e5811b302..59693d330 100644 --- a/src/__tests__/nodeSuites/ready-promise.spec.js +++ b/src/__tests__/nodeSuites/ready-promise.spec.js @@ -56,8 +56,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -103,8 +103,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -153,8 +153,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -222,9 +222,9 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { config.scheduler.featuresRefreshRate) - config.startup.readyTimeout) + refreshTimeMillis; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both initial attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -281,7 +281,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -331,7 +331,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes less than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -378,8 +378,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -467,8 +467,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -538,7 +538,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index a6a6bb66f..32a3f5d7e 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -22,8 +22,8 @@ const config = { export default async function telemetryNodejsSuite(key, fetchMock, assert) { - fetchMock.getOnce(url(config, '/splitChanges?s=1.1&since=-1'), 500); // record http exception - fetchMock.getOnce(url(config, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=-1'), 500); // record http exception + fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(url(config, '/testImpressions/bulk'), 200); diff --git a/src/__tests__/online/browser.spec.js b/src/__tests__/online/browser.spec.js index 8da674e95..4616ae22a 100644 --- a/src/__tests__/online/browser.spec.js +++ b/src/__tests__/online/browser.spec.js @@ -88,8 +88,8 @@ tape('## E2E CI Tests ##', function (assert) { //If we change the mocks, we need to clear localstorage. Cleaning up after testing ensures "fresh data". localStorage.clear(); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); fetchMock.get(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolas }); fetchMock.get(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); diff --git a/src/__tests__/online/node.spec.js b/src/__tests__/online/node.spec.js index 94ca9d830..46bd9fca9 100644 --- a/src/__tests__/online/node.spec.js +++ b/src/__tests__/online/node.spec.js @@ -38,8 +38,8 @@ const config = { const settings = settingsFactory(config); const key = 'facundo@split.io'; -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); -fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); +fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges')}/*`), { status: 200, body: { 'name': 'segment', From ec40f5490787d2f9e8d6a44e2d386ff37f05eb79 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 1 Aug 2024 19:06:55 +0100 Subject: [PATCH 11/58] Upgrade JS-commons --- package-lock.json | 14 +++++++------- package.json | 2 +- src/__tests__/browserSuites/telemetry.spec.js | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/package-lock.json b/package-lock.json index 662e0f1d8..3fea2578e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.1-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.6", + "@splitsoftware/splitio-commons": "1.16.1-rc.7", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.6", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.6.tgz", - "integrity": "sha512-h4+hYpJoDjkFMgube9KFPQDz5a+O3eII4VSlzh0KJpQJukesq0Isf3T0C5ICP4pYHfkm4E+Yy+ohYfISxaDd6w==", + "version": "1.16.1-rc.7", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.7.tgz", + "integrity": "sha512-sy0Qzm1loQRsSF95D+t7zCZm/yj4LoQ3nYL6Tg7vZlQHW7Y/HAGx5zJPBIb6Vvlhh81uCfL4Cg3mSm3rHvubhg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.6", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.6.tgz", - "integrity": "sha512-h4+hYpJoDjkFMgube9KFPQDz5a+O3eII4VSlzh0KJpQJukesq0Isf3T0C5ICP4pYHfkm4E+Yy+ohYfISxaDd6w==", + "version": "1.16.1-rc.7", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.7.tgz", + "integrity": "sha512-sy0Qzm1loQRsSF95D+t7zCZm/yj4LoQ3nYL6Tg7vZlQHW7Y/HAGx5zJPBIb6Vvlhh81uCfL4Cg3mSm3rHvubhg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index ce5f2ecfd..4edfcee5b 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.6", + "@splitsoftware/splitio-commons": "1.16.1-rc.7", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 08fd69571..8ae2910b9 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -108,7 +108,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { delete data.tR; // delete to validate other properties assert.deepEqual(data, { - oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, lE: false, + oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, rR: { sp: 99999, ms: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], i: [], uC: 2 /* Default GRANTED */, From 957df00966432fe9632a351b6d6bbc48125107ef Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 2 Aug 2024 17:07:16 +0100 Subject: [PATCH 12/58] rc --- .github/workflows/ci-cd.yml | 4 ++-- package-lock.json | 4 ++-- package.json | 2 +- src/settings/defaults/version.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..bb06d957d 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_polishing' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_polishing' }} strategy: matrix: environment: diff --git a/package-lock.json b/package-lock.json index 3fea2578e..990d54afc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.0", + "version": "10.27.1-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.0", + "version": "10.27.1-rc.1", "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "1.16.1-rc.7", diff --git a/package.json b/package.json index 4edfcee5b..2bae19e3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.0", + "version": "10.27.1-rc.1", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 6e55955c8..224af171b 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.27.1-rc.0'; +export const packageVersion = '10.27.1-rc.1'; From 052ba46c3e6e0616c6878742a6d32da09eb97343 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 6 Aug 2024 17:54:51 +0100 Subject: [PATCH 13/58] rc with update JS-commons version --- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- ...EGMENTS_UPDATE.UNBOUNDED.1457552650000.json | 2 +- src/settings/defaults/version.js | 2 +- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/package-lock.json b/package-lock.json index 990d54afc..919bc2eca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.1", + "version": "10.27.1-rc.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.1", + "version": "10.27.1-rc.2", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.7", + "@splitsoftware/splitio-commons": "1.16.1-rc.8", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.7", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.7.tgz", - "integrity": "sha512-sy0Qzm1loQRsSF95D+t7zCZm/yj4LoQ3nYL6Tg7vZlQHW7Y/HAGx5zJPBIb6Vvlhh81uCfL4Cg3mSm3rHvubhg==", + "version": "1.16.1-rc.8", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.8.tgz", + "integrity": "sha512-scvmDXE3aY72kYtKTkzMc06uZ6O/FZjaet+vAekSofRuzAkpmKzgvk4xiCBjFfONaPb66Dvw4SO7M34ym3gwQg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8437,9 +8437,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.7", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.7.tgz", - "integrity": "sha512-sy0Qzm1loQRsSF95D+t7zCZm/yj4LoQ3nYL6Tg7vZlQHW7Y/HAGx5zJPBIb6Vvlhh81uCfL4Cg3mSm3rHvubhg==", + "version": "1.16.1-rc.8", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.8.tgz", + "integrity": "sha512-scvmDXE3aY72kYtKTkzMc06uZ6O/FZjaet+vAekSofRuzAkpmKzgvk4xiCBjFfONaPb66Dvw4SO7M34ym3gwQg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 2bae19e3b..f81018443 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.1", + "version": "10.27.1-rc.2", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.7", + "@splitsoftware/splitio-commons": "1.16.1-rc.8", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json index 8563135d0..f6fa59825 100644 --- a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json +++ b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json @@ -1,4 +1,4 @@ { "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552650000,\\\"largeSegments\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":0,\\\"s\\\":0}\"}" + "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552650000,\\\"largeSegments\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" } \ No newline at end of file diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 224af171b..d64abdf90 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.27.1-rc.1'; +export const packageVersion = '10.27.1-rc.2'; From 623add39ae1619de40c9c728070ab344fb13d8d6 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 6 Aug 2024 18:23:03 +0100 Subject: [PATCH 14/58] rollback ci-cd --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index bb06d957d..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_polishing' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_polishing' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: From 0b4c07b612cae0b0022db78aaa6e4c7f713ace8d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 6 Aug 2024 18:28:47 +0100 Subject: [PATCH 15/58] Removed node-polyfill-webpack-plugin dev dependency, not used anymore, to fix vulnerability issues --- package-lock.json | 1433 +-------------------------------------------- package.json | 1 - 2 files changed, 16 insertions(+), 1418 deletions(-) diff --git a/package-lock.json b/package-lock.json index 919bc2eca..1532ee16e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,7 +34,6 @@ "karma-tap": "^4.2.0", "karma-webpack": "^5.0.0", "lodash": "^4.17.21", - "node-polyfill-webpack-plugin": "^1.1.4", "proxyquire": "^2.1.3", "puppeteer": "^3.3.0", "redis-dumpz": "0.1.12", @@ -1376,36 +1375,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/asn1.js/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "dependencies": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, "node_modules/ast-metadata-inferer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.0.tgz", @@ -1427,18 +1396,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "node_modules/available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -1594,12 +1551,6 @@ "node": ">=12" } }, - "node_modules/bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -1661,88 +1612,6 @@ "node": ">=8" } }, - "node_modules/brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "node_modules/browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "dependencies": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "dependencies": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "node_modules/browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "dependencies": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" - } - }, - "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", - "dev": true, - "dependencies": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "dependencies": { - "pako": "~1.0.5" - } - }, "node_modules/browserslist": { "version": "4.21.11", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz", @@ -1775,30 +1644,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1814,18 +1659,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "node_modules/builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1956,16 +1789,6 @@ "node": ">=6.0" } }, - "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -2077,18 +1900,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, - "node_modules/console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "node_modules/constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -2162,49 +1973,6 @@ "node": ">= 0.10" } }, - "node_modules/create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - } - }, - "node_modules/create-ecdh/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, - "node_modules/create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "node_modules/create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "dependencies": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2243,28 +2011,6 @@ "node": ">= 8" } }, - "node_modules/crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "dependencies": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - }, - "engines": { - "node": "*" - } - }, "node_modules/csv-streamify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/csv-streamify/-/csv-streamify-4.0.0.tgz", @@ -2439,16 +2185,6 @@ "node": ">= 0.8" } }, - "node_modules/des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -2474,23 +2210,6 @@ "node": ">=0.3.1" } }, - "node_modules/diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "node_modules/diffie-hellman/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2521,18 +2240,6 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, - "node_modules/domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://bevry.me/fund" - } - }, "node_modules/dotignore": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", @@ -2563,27 +2270,6 @@ "integrity": "sha512-EafxEiEDzk2aLrdbtVczylHflHdHkNrpGNHIgDyA63sUQLQVS2ayj2hPw3RsVB42qkwURH+T2OxV7kGPUuYszA==", "dev": true }, - "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "dependencies": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "node_modules/elliptic/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2760,12 +2446,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -3105,16 +2785,6 @@ "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", "dev": true }, - "node_modules/evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "dependencies": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3256,15 +2926,6 @@ "node": ">=8" } }, - "node_modules/filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -3677,30 +3338,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "node_modules/hirestime": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hirestime/-/hirestime-3.2.2.tgz", @@ -3710,17 +3347,6 @@ "node": ">=4.0" } }, - "node_modules/hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "dependencies": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -3760,12 +3386,6 @@ "node": ">=8.0.0" } }, - "node_modules/https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, "node_modules/https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -4063,21 +3683,6 @@ "node": ">=8" } }, - "node_modules/is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -4090,22 +3695,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -4236,25 +3825,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4658,17 +4228,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "node_modules/md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4703,25 +4262,6 @@ "node": ">=8.6" } }, - "node_modules/miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "dependencies": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "bin": { - "miller-rabin": "bin/miller-rabin" - } - }, - "node_modules/miller-rabin/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -4764,18 +4304,6 @@ "dom-walk": "^0.1.0" } }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "node_modules/minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4929,44 +4457,6 @@ "webidl-conversions": "^3.0.0" } }, - "node_modules/node-polyfill-webpack-plugin": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", - "integrity": "sha512-Z0XTKj1wRWO8o/Vjobsw5iOJCN+Sua3EZEUc2Ziy9CyVvmHKu6o+t4gUH9GOE0czyPR94LI6ZCV/PpcM8b5yow==", - "dev": true, - "dependencies": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.19.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "webpack": ">=5" - } - }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -5141,12 +4631,6 @@ "node": ">= 0.8.0" } }, - "node_modules/os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5194,12 +4678,6 @@ "node": ">=6" } }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -5212,19 +4690,6 @@ "node": ">=6" } }, - "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "node_modules/parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", @@ -5243,12 +4708,6 @@ "node": ">= 0.8" } }, - "node_modules/path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5288,22 +4747,6 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, - "node_modules/pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "dependencies": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -5413,15 +4856,6 @@ "node": ">=6" } }, - "node_modules/process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true, - "engines": { - "node": ">= 0.6.0" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -5463,26 +4897,6 @@ "resolve": "^1.11.1" } }, - "node_modules/public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "dependencies": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "node_modules/public-encrypt/node_modules/bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -5559,15 +4973,6 @@ "node": ">=0.4.x" } }, - "node_modules/querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5597,16 +5002,6 @@ "safe-buffer": "^5.1.0" } }, - "node_modules/randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "dependencies": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -6126,16 +5521,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "dependencies": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -6252,31 +5637,12 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "node_modules/setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, - "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - }, - "bin": { - "sha.js": "bin.js" - } - }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -6442,28 +5808,6 @@ "node": ">= 0.6" } }, - "node_modules/stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "dependencies": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "node_modules/stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "dependencies": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, "node_modules/streamroller": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", @@ -6952,18 +6296,6 @@ "safe-buffer": "~5.1.0" } }, - "node_modules/timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "dependencies": { - "setimmediate": "^1.0.4" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -7106,12 +6438,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "node_modules/tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7310,45 +6636,6 @@ "punycode": "^2.1.0" } }, - "node_modules/url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "dependencies": { - "punycode": "1.3.2", - "querystring": "0.2.0" - } - }, - "node_modules/url/node_modules/punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "node_modules/url/node_modules/querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", - "dev": true, - "engines": { - "node": ">=0.4.x" - } - }, - "node_modules/util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -7379,12 +6666,6 @@ "node": ">= 0.8" } }, - "node_modules/vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -7608,26 +6889,6 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, - "node_modules/which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "dependencies": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -8871,38 +8132,6 @@ "es-shim-unscopables": "^1.0.0" } }, - "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "assert": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", - "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", - "dev": true, - "requires": { - "es6-object-assign": "^1.1.0", - "is-nan": "^1.2.1", - "object-is": "^1.0.1", - "util": "^0.12.0" - } - }, "ast-metadata-inferer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.0.tgz", @@ -8924,12 +8153,6 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, - "available-typed-arrays": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", - "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", - "dev": true - }, "babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -9047,12 +8270,6 @@ "xxhashjs": "^0.2.2" } }, - "bn.js": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", - "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", - "dev": true - }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -9083,109 +8300,30 @@ } }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "requires": { - "fill-range": "^7.1.1" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", - "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", - "dev": true, - "requires": { - "bn.js": "^5.0.0", - "randombytes": "^2.0.1" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } } }, - "browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "bn.js": "^5.2.1", - "browserify-rsa": "^4.1.0", - "create-hash": "^1.2.0", - "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", - "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", - "safe-buffer": "^5.2.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dev": true, "requires": { - "pako": "~1.0.5" + "fill-range": "^7.1.1" } }, "browserslist": { @@ -9200,16 +8338,6 @@ "update-browserslist-db": "^1.0.13" } }, - "buffer": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.2.1" - } - }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -9222,18 +8350,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", - "dev": true - }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -9317,16 +8433,6 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -9425,18 +8531,6 @@ } } }, - "console-browserify": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", - "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", - "dev": true - }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -9492,51 +8586,6 @@ "vary": "^1" } }, - "create-ecdh": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", - "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.5.3" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -9563,25 +8612,6 @@ "which": "^2.0.1" } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, "csv-streamify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/csv-streamify/-/csv-streamify-4.0.0.tgz", @@ -9717,16 +8747,6 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, - "des.js": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", - "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -9745,25 +8765,6 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -9791,12 +8792,6 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, - "domain-browser": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", - "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", - "dev": true - }, "dotignore": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", @@ -9824,29 +8819,6 @@ "integrity": "sha512-EafxEiEDzk2aLrdbtVczylHflHdHkNrpGNHIgDyA63sUQLQVS2ayj2hPw3RsVB42qkwURH+T2OxV7kGPUuYszA==", "dev": true }, - "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", - "dev": true, - "requires": { - "bn.js": "^4.11.9", - "brorand": "^1.1.0", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.1", - "inherits": "^2.0.4", - "minimalistic-assert": "^1.0.1", - "minimalistic-crypto-utils": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -9981,12 +8953,6 @@ "is-symbol": "^1.0.2" } }, - "es6-object-assign": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", - "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", - "dev": true - }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -10250,16 +9216,6 @@ "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", "dev": true }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -10366,12 +9322,6 @@ "to-regex-range": "^5.0.1" } }, - "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", - "dev": true - }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -10674,44 +9624,12 @@ "has-symbols": "^1.0.2" } }, - "hash-base": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", - "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "safe-buffer": "^5.2.0" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, "hirestime": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hirestime/-/hirestime-3.2.2.tgz", "integrity": "sha512-X+4w5O6JMW7zlgAhad6OPA/MwYTW1FqrF27+6ItRUmDT4jklsXd4N5S5hNCmd9AIGVp8SLsCoGwRe5ddBp/CKg==", "dev": true }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -10744,12 +9662,6 @@ "requires-port": "^1.0.0" } }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", - "dev": true - }, "https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -10937,15 +9849,6 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, - "is-generator-function": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", - "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -10955,16 +9858,6 @@ "is-extglob": "^2.1.1" } }, - "is-nan": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", - "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", - "dev": true, - "requires": { - "call-bind": "^1.0.0", - "define-properties": "^1.1.3" - } - }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -11050,19 +9943,6 @@ "has-symbols": "^1.0.2" } }, - "is-typed-array": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", - "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0" - } - }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -11396,17 +10276,6 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -11435,24 +10304,6 @@ "picomatch": "^2.3.1" } }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -11483,18 +10334,6 @@ "dom-walk": "^0.1.0" } }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", - "dev": true - }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -11628,38 +10467,6 @@ } } }, - "node-polyfill-webpack-plugin": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", - "integrity": "sha512-Z0XTKj1wRWO8o/Vjobsw5iOJCN+Sua3EZEUc2Ziy9CyVvmHKu6o+t4gUH9GOE0czyPR94LI6ZCV/PpcM8b5yow==", - "dev": true, - "requires": { - "assert": "^2.0.0", - "browserify-zlib": "^0.2.0", - "buffer": "^6.0.3", - "console-browserify": "^1.2.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.12.0", - "domain-browser": "^4.19.0", - "events": "^3.3.0", - "filter-obj": "^2.0.2", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "^1.0.1", - "process": "^0.11.10", - "punycode": "^2.1.1", - "querystring-es3": "^0.2.1", - "readable-stream": "^3.6.0", - "stream-browserify": "^3.0.0", - "stream-http": "^3.2.0", - "string_decoder": "^1.3.0", - "timers-browserify": "^2.0.12", - "tty-browserify": "^0.0.1", - "url": "^0.11.0", - "util": "^0.12.4", - "vm-browserify": "^1.1.2" - } - }, "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -11800,12 +10607,6 @@ "type-check": "^0.4.0" } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", - "dev": true - }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -11835,12 +10636,6 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -11850,19 +10645,6 @@ "callsites": "^3.0.0" } }, - "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", - "dev": true, - "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, "parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", @@ -11875,12 +10657,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, - "path-browserify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", - "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", - "dev": true - }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11911,19 +10687,6 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, - "pbkdf2": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", - "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -12005,12 +10768,6 @@ "parse-ms": "^2.0.0" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", - "dev": true - }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -12046,28 +10803,6 @@ "resolve": "^1.11.1" } }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - }, - "dependencies": { - "bn.js": { - "version": "4.12.0", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", - "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", - "dev": true - } - } - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -12123,12 +10858,6 @@ "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "dev": true }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", - "dev": true - }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -12144,16 +10873,6 @@ "safe-buffer": "^5.1.0" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -12553,16 +11272,6 @@ "glob": "^7.1.3" } }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -12635,28 +11344,12 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", - "dev": true - }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -12782,28 +11475,6 @@ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true }, - "stream-browserify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", - "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", - "dev": true, - "requires": { - "inherits": "~2.0.4", - "readable-stream": "^3.5.0" - } - }, - "stream-http": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", - "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.4", - "readable-stream": "^3.6.0", - "xtend": "^4.0.2" - } - }, "streamroller": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", @@ -13178,15 +11849,6 @@ } } }, - "timers-browserify": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", - "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -13287,12 +11949,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, - "tty-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", - "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", - "dev": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -13412,43 +12068,6 @@ "punycode": "^2.1.0" } }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", - "dev": true - } - } - }, - "util": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", - "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "is-arguments": "^1.0.4", - "is-generator-function": "^1.0.7", - "is-typed-array": "^1.1.3", - "which-typed-array": "^1.1.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -13473,12 +12092,6 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, - "vm-browserify": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", - "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", - "dev": true - }, "void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -13634,20 +12247,6 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, - "which-typed-array": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", - "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", - "dev": true, - "requires": { - "available-typed-arrays": "^1.0.5", - "call-bind": "^1.0.2", - "es-abstract": "^1.20.0", - "for-each": "^0.3.3", - "has-tostringtag": "^1.0.0", - "is-typed-array": "^1.1.9" - } - }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", diff --git a/package.json b/package.json index f81018443..d42616c8c 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "karma-tap": "^4.2.0", "karma-webpack": "^5.0.0", "lodash": "^4.17.21", - "node-polyfill-webpack-plugin": "^1.1.4", "proxyquire": "^2.1.3", "puppeteer": "^3.3.0", "redis-dumpz": "0.1.12", From 3ecea9c7d1aef9cd4939f4ea6800eb1ac2bb08f7 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 7 Aug 2024 16:39:06 +0000 Subject: [PATCH 16/58] Revert "Removed node-polyfill-webpack-plugin dev dependency, not used anymore, to fix vulnerability issues" This reverts commit 0b4c07b612cae0b0022db78aaa6e4c7f713ace8d. --- package-lock.json | 1423 ++++++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 2 files changed, 1413 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1532ee16e..919bc2eca 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "karma-tap": "^4.2.0", "karma-webpack": "^5.0.0", "lodash": "^4.17.21", + "node-polyfill-webpack-plugin": "^1.1.4", "proxyquire": "^2.1.3", "puppeteer": "^3.3.0", "redis-dumpz": "0.1.12", @@ -1375,6 +1376,36 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "dev": true, + "dependencies": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, "node_modules/ast-metadata-inferer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.0.tgz", @@ -1396,6 +1427,18 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -1551,6 +1594,12 @@ "node": ">=12" } }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -1612,6 +1661,88 @@ "node": ">=8" } }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "dev": true, + "dependencies": { + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, "node_modules/browserslist": { "version": "4.21.11", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.11.tgz", @@ -1644,6 +1775,30 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1659,6 +1814,18 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -1789,6 +1956,16 @@ "node": ">=6.0" } }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -1900,6 +2077,18 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, "node_modules/content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -1973,6 +2162,49 @@ "node": ">= 0.10" } }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "node_modules/create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -2011,6 +2243,28 @@ "node": ">= 8" } }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, "node_modules/csv-streamify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/csv-streamify/-/csv-streamify-4.0.0.tgz", @@ -2185,6 +2439,16 @@ "node": ">= 0.8" } }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -2210,6 +2474,23 @@ "node": ">=0.3.1" } }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -2240,6 +2521,18 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, + "node_modules/domain-browser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", + "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://bevry.me/fund" + } + }, "node_modules/dotignore": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", @@ -2270,6 +2563,27 @@ "integrity": "sha512-EafxEiEDzk2aLrdbtVczylHflHdHkNrpGNHIgDyA63sUQLQVS2ayj2hPw3RsVB42qkwURH+T2OxV7kGPUuYszA==", "dev": true }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -2446,6 +2760,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", + "dev": true + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -2785,6 +3105,16 @@ "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", "dev": true }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -2926,6 +3256,15 @@ "node": ">=8" } }, + "node_modules/filter-obj": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", + "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -3338,6 +3677,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "node_modules/hirestime": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hirestime/-/hirestime-3.2.2.tgz", @@ -3347,6 +3710,17 @@ "node": ">=4.0" } }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -3386,6 +3760,12 @@ "node": ">=8.0.0" } }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, "node_modules/https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -3683,6 +4063,21 @@ "node": ">=8" } }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -3695,6 +4090,22 @@ "node": ">=0.10.0" } }, + "node_modules/is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -3825,6 +4236,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -4228,6 +4658,17 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4262,6 +4703,25 @@ "node": ">=8.6" } }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -4304,6 +4764,18 @@ "dom-walk": "^0.1.0" } }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -4457,6 +4929,44 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/node-polyfill-webpack-plugin": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", + "integrity": "sha512-Z0XTKj1wRWO8o/Vjobsw5iOJCN+Sua3EZEUc2Ziy9CyVvmHKu6o+t4gUH9GOE0czyPR94LI6ZCV/PpcM8b5yow==", + "dev": true, + "dependencies": { + "assert": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.19.0", + "events": "^3.3.0", + "filter-obj": "^2.0.2", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "punycode": "^2.1.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^3.6.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "^0.0.1", + "url": "^0.11.0", + "util": "^0.12.4", + "vm-browserify": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "webpack": ">=5" + } + }, "node_modules/node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -4631,6 +5141,12 @@ "node": ">= 0.8.0" } }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -4678,6 +5194,12 @@ "node": ">=6" } }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -4690,6 +5212,19 @@ "node": ">=6" } }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, "node_modules/parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", @@ -4708,6 +5243,12 @@ "node": ">= 0.8" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -4747,6 +5288,22 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -4856,6 +5413,15 @@ "node": ">=6" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -4897,6 +5463,26 @@ "resolve": "^1.11.1" } }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -4973,6 +5559,15 @@ "node": ">=0.4.x" } }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -5002,6 +5597,16 @@ "safe-buffer": "^5.1.0" } }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "node_modules/range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -5521,6 +6126,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -5637,12 +6252,31 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, "node_modules/shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -5808,6 +6442,28 @@ "node": ">= 0.6" } }, + "node_modules/stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "dependencies": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "node_modules/stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, "node_modules/streamroller": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", @@ -6296,6 +6952,18 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -6438,6 +7106,12 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "node_modules/tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -6636,6 +7310,45 @@ "punycode": "^2.1.0" } }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "node_modules/url/node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -6666,6 +7379,12 @@ "node": ">= 0.8" } }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "node_modules/void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -6889,6 +7608,26 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "node_modules/which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", @@ -8132,6 +8871,38 @@ "es-shim-unscopables": "^1.0.0" } }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "assert": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-2.0.0.tgz", + "integrity": "sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==", + "dev": true, + "requires": { + "es6-object-assign": "^1.1.0", + "is-nan": "^1.2.1", + "object-is": "^1.0.1", + "util": "^0.12.0" + } + }, "ast-metadata-inferer": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.8.0.tgz", @@ -8153,6 +8924,12 @@ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, + "available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true + }, "babel-polyfill": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", @@ -8270,6 +9047,12 @@ "xxhashjs": "^0.2.2" } }, + "bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -8307,23 +9090,102 @@ } } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "requires": { + "fill-range": "^7.1.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" } }, - "braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "browserify-sign": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", + "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", "dev": true, "requires": { - "fill-range": "^7.1.1" + "bn.js": "^5.2.1", + "browserify-rsa": "^4.1.0", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.4", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.6", + "readable-stream": "^3.6.2", + "safe-buffer": "^5.2.1" + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" } }, "browserslist": { @@ -8338,6 +9200,16 @@ "update-browserslist-db": "^1.0.13" } }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -8350,6 +9222,18 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", @@ -8433,6 +9317,16 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -8531,6 +9425,18 @@ } } }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", @@ -8586,6 +9492,51 @@ "vary": "^1" } }, + "create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "create-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", @@ -8612,6 +9563,25 @@ "which": "^2.0.1" } }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, "csv-streamify": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/csv-streamify/-/csv-streamify-4.0.0.tgz", @@ -8747,6 +9717,16 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, "destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -8765,6 +9745,25 @@ "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", @@ -8792,6 +9791,12 @@ "integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==", "dev": true }, + "domain-browser": { + "version": "4.22.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-4.22.0.tgz", + "integrity": "sha512-IGBwjF7tNk3cwypFNH/7bfzBcgSCbaMOD3GsaY1AU/JRrnHnYgEM0+9kQt52iZxjNsjBtJYtao146V+f8jFZNw==", + "dev": true + }, "dotignore": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", @@ -8819,6 +9824,29 @@ "integrity": "sha512-EafxEiEDzk2aLrdbtVczylHflHdHkNrpGNHIgDyA63sUQLQVS2ayj2hPw3RsVB42qkwURH+T2OxV7kGPUuYszA==", "dev": true }, + "elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "requires": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", @@ -8953,6 +9981,12 @@ "is-symbol": "^1.0.2" } }, + "es6-object-assign": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/es6-object-assign/-/es6-object-assign-1.1.0.tgz", + "integrity": "sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==", + "dev": true + }, "escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -9216,6 +10250,16 @@ "integrity": "sha512-inRWzRY7nG+aXZxBzEqYKB3HPgwflZRopAjDCHv0whhRx+MTUr1ei0ICZUypdyE0HRm4L2d5VEcIqLD6yl+BFA==", "dev": true }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -9322,6 +10366,12 @@ "to-regex-range": "^5.0.1" } }, + "filter-obj": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", + "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "dev": true + }, "finalhandler": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", @@ -9624,12 +10674,44 @@ "has-symbols": "^1.0.2" } }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, "hirestime": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/hirestime/-/hirestime-3.2.2.tgz", "integrity": "sha512-X+4w5O6JMW7zlgAhad6OPA/MwYTW1FqrF27+6ItRUmDT4jklsXd4N5S5hNCmd9AIGVp8SLsCoGwRe5ddBp/CKg==", "dev": true }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, "http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -9662,6 +10744,12 @@ "requires-port": "^1.0.0" } }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, "https-proxy-agent": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", @@ -9849,6 +10937,15 @@ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, + "is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-glob": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", @@ -9858,6 +10955,16 @@ "is-extglob": "^2.1.1" } }, + "is-nan": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/is-nan/-/is-nan-1.3.2.tgz", + "integrity": "sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3" + } + }, "is-negative-zero": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", @@ -9943,6 +11050,19 @@ "has-symbols": "^1.0.2" } }, + "is-typed-array": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.9.tgz", + "integrity": "sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0" + } + }, "is-weakref": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", @@ -10276,6 +11396,17 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -10304,6 +11435,24 @@ "picomatch": "^2.3.1" } }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "mime": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", @@ -10334,6 +11483,18 @@ "dom-walk": "^0.1.0" } }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, "minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -10467,6 +11628,38 @@ } } }, + "node-polyfill-webpack-plugin": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/node-polyfill-webpack-plugin/-/node-polyfill-webpack-plugin-1.1.4.tgz", + "integrity": "sha512-Z0XTKj1wRWO8o/Vjobsw5iOJCN+Sua3EZEUc2Ziy9CyVvmHKu6o+t4gUH9GOE0czyPR94LI6ZCV/PpcM8b5yow==", + "dev": true, + "requires": { + "assert": "^2.0.0", + "browserify-zlib": "^0.2.0", + "buffer": "^6.0.3", + "console-browserify": "^1.2.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.12.0", + "domain-browser": "^4.19.0", + "events": "^3.3.0", + "filter-obj": "^2.0.2", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "^1.0.1", + "process": "^0.11.10", + "punycode": "^2.1.1", + "querystring-es3": "^0.2.1", + "readable-stream": "^3.6.0", + "stream-browserify": "^3.0.0", + "stream-http": "^3.2.0", + "string_decoder": "^1.3.0", + "timers-browserify": "^2.0.12", + "tty-browserify": "^0.0.1", + "url": "^0.11.0", + "util": "^0.12.4", + "vm-browserify": "^1.1.2" + } + }, "node-releases": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz", @@ -10607,6 +11800,12 @@ "type-check": "^0.4.0" } }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -10636,6 +11835,12 @@ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -10645,6 +11850,19 @@ "callsites": "^3.0.0" } }, + "parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "requires": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, "parse-ms": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-2.1.0.tgz", @@ -10657,6 +11875,12 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true }, + "path-browserify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-1.0.1.tgz", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -10687,6 +11911,19 @@ "integrity": "sha512-G6zHoVqC6GGTQkZwF4lkuEyMbVOjoBKAEybQUypI1WTkqinCOrq2x6U2+phkJ1XsEMTy4LjtwPI7HW+NVrRR2w==", "dev": true }, + "pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -10768,6 +12005,12 @@ "parse-ms": "^2.0.0" } }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true + }, "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -10803,6 +12046,28 @@ "resolve": "^1.11.1" } }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + } + } + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -10858,6 +12123,12 @@ "integrity": "sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg==", "dev": true }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10873,6 +12144,16 @@ "safe-buffer": "^5.1.0" } }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -11272,6 +12553,16 @@ "glob": "^7.1.3" } }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, "run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -11344,12 +12635,28 @@ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, "shallow-clone": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", @@ -11475,6 +12782,28 @@ "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", "dev": true }, + "stream-browserify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz", + "integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==", + "dev": true, + "requires": { + "inherits": "~2.0.4", + "readable-stream": "^3.5.0" + } + }, + "stream-http": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz", + "integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "xtend": "^4.0.2" + } + }, "streamroller": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.3.tgz", @@ -11849,6 +13178,15 @@ } } }, + "timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, "tmp": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", @@ -11949,6 +13287,12 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "dev": true + }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -12068,6 +13412,43 @@ "punycode": "^2.1.0" } }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "dev": true + } + } + }, + "util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -12092,6 +13473,12 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, "void-elements": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", @@ -12247,6 +13634,20 @@ "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, + "which-typed-array": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.8.tgz", + "integrity": "sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==", + "dev": true, + "requires": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "es-abstract": "^1.20.0", + "for-each": "^0.3.3", + "has-tostringtag": "^1.0.0", + "is-typed-array": "^1.1.9" + } + }, "wildcard": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", diff --git a/package.json b/package.json index d42616c8c..f81018443 100644 --- a/package.json +++ b/package.json @@ -65,6 +65,7 @@ "karma-tap": "^4.2.0", "karma-webpack": "^5.0.0", "lodash": "^4.17.21", + "node-polyfill-webpack-plugin": "^1.1.4", "proxyquire": "^2.1.3", "puppeteer": "^3.3.0", "redis-dumpz": "0.1.12", From bbdc7d90ed8a8d95ed51c2b075418ff277c86772 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 7 Aug 2024 16:40:38 +0000 Subject: [PATCH 17/58] Update MyLargeSegments payload mock --- src/__tests__/mocks/mylargesegments.employees.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__tests__/mocks/mylargesegments.employees.json b/src/__tests__/mocks/mylargesegments.employees.json index 13e67ed94..e820681d0 100644 --- a/src/__tests__/mocks/mylargesegments.employees.json +++ b/src/__tests__/mocks/mylargesegments.employees.json @@ -2,5 +2,5 @@ "myLargeSegments": [ "employees" ], - "changeNumber": 1234567890 + "till": 1234567890 } From f9e24ed30c55b9987a42424c01acb6e929cc7874 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 21 Aug 2024 01:00:03 +0200 Subject: [PATCH 18/58] Remove LS configs and unify endpoint --- package-lock.json | 4 +- package.json | 2 +- .../browserSuites/push-fallback.spec.js | 31 ++-- .../push-synchronization.spec.js | 48 ++---- .../readiness-large-segments.spec.js | 149 ------------------ .../browserSuites/ready-from-cache.spec.js | 1 - .../mocks/mylargesegments.employees.json | 6 - .../mocks/splitchanges.real.withSegments.json | 42 ----- .../nodeSuites/push-synchronization.spec.js | 3 - src/__tests__/offline/browser.spec.js | 6 +- src/__tests__/online/browser.spec.js | 2 - src/settings/browser.js | 8 +- src/settings/defaults/browser.js | 4 +- src/settings/defaults/node.js | 4 +- src/settings/defaults/version.js | 2 +- src/settings/node.js | 5 - ts-tests/index.ts | 11 +- types/splitio.d.ts | 29 +--- 18 files changed, 40 insertions(+), 317 deletions(-) delete mode 100644 src/__tests__/browserSuites/readiness-large-segments.spec.js delete mode 100644 src/__tests__/mocks/mylargesegments.employees.json diff --git a/package-lock.json b/package-lock.json index 919bc2eca..94e9163aa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.2", + "version": "10.27.1-rc.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.2", + "version": "10.27.1-rc.3", "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "1.16.1-rc.8", diff --git a/package.json b/package.json index f81018443..7dd987331 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.2", + "version": "10.27.1-rc.3", "description": "Split SDK", "files": [ "README.md", diff --git a/src/__tests__/browserSuites/push-fallback.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js index 80860891f..339936510 100644 --- a/src/__tests__/browserSuites/push-fallback.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -51,14 +51,10 @@ const config = { scheduler: { featuresRefreshRate: 0.2, segmentsRefreshRate: 0.25, - largeSegmentsRefreshRate: 0.25, impressionsRefreshRate: 3000 }, urls: baseUrls, streamingEnabled: true, - sync: { - largeSegmentsEnabled: true - } }; const settings = settingsFactory(config); @@ -82,27 +78,26 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /my(Large)Segments/nicolas), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /my(Large)Segments/nicolas) - * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas) + * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/nicolas), auth, SSE connection + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/nicolas) + * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas) * 0.3 secs: SPLIT_UPDATE event ignored * 0.4 secs: periodic fetch due to polling (/splitChanges) - * 0.45 secs: periodic fetch due to polling (/my(Large)Segments/*) - * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /my(Large)Segments/nicolas) - * 0.55 secs: create a new client while streaming -> initial fetch (/my(Large)Segments/marcio), auth, SSE connection and syncAll (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio) + * 0.45 secs: periodic fetch due to polling (/mySegments/nicolas) + * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /mySegments/nicolas) + * 0.55 secs: create a new client while streaming -> initial fetch (/mySegments/marcio), auth, SSE connection and syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio) * 0.6 secs: SPLIT_UPDATE event -> /splitChanges - * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio) + * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio) * 0.8 secs: MY_SEGMENTS_UPDATE event ignored * 0.9 secs: periodic fetch due to polling (/splitChanges) - * 0.95 secs: periodic fetch due to polling (/my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) - * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) + * 0.95 secs: periodic fetch due to polling (/mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) + * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) * 1.1 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas - * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /my(Large)Segments/nicolas, /my(Large)Segments/marcio, /my(Large)Segments/facundo) + * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) * 1.3 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll and stop polling * 1.5 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll * 1.6 secs: Streaming closed (CONTROL STREAMING_DISABLED event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.8 secs: periodic fetch due to polling (/splitChanges) - * 1.85 secs: periodic fetch due to polling (/myLargeSegments/*). /mySegments/* are not fetched due to update without segments + * 1.8 secs: periodic fetch due to polling (/splitChanges): due to update without segments, mySegments are not fetched * 2.0 secs: periodic fetch due to polling (/splitChanges) * 2.1 secs: destroy client */ @@ -217,10 +212,6 @@ export function testFallback(fetchMock, assert) { return { status: 200, body: authPushEnabledNicolas }; }); - // MyLargeSegments are fetched one more time than MySegments due to smart pausing of MySegments sync at the end of the test - fetchMock.get({ url: url(settings, '/myLargeSegments/nicolas%40split.io'), repeat: 14 }, { status: 200, body: { myLargeSegments: [] } }); - fetchMock.get({ url: url(settings, '/myLargeSegments/marcio%40split.io'), repeat: 10 }, { status: 200, body: { myLargeSegments: [] } }); - // initial split and mySegment sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 8ac362fd8..be7153a16 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -51,9 +51,6 @@ const config = { }, urls: baseUrls, streamingEnabled: true, - sync: { - largeSegmentsEnabled: true - } }; const settings = settingsFactory(config); @@ -79,13 +76,13 @@ const MILLIS_SEGMENT_REMOVAL_LS = 2100; /** * Sequence of calls: * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*, /myLargeSegments/*) + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) * 0.2 secs: SPLIT_UPDATE event -> /splitChanges * 0.3 secs: SPLIT_UPDATE event with old changeNumber * 0.4 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io * 0.5 secs: SPLIT_KILL event -> /splitChanges * 0.6 secs: creates a new client -> new auth and SSE connection - * 0.7 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*, /myLargeSegments/*) + * 0.7 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) * 0.8 secs: MY_SEGMENTS_UPDATE event for new client (with payload). * 0.9 secs: MY_SEGMENTS_UPDATE event for new client (with empty payload). * 1.0 secs: creates more clients @@ -96,8 +93,8 @@ const MILLIS_SEGMENT_REMOVAL_LS = 2100; * 1.5 secs: MY_SEGMENTS_UPDATE_V2 KeyList event. * 1.6 secs: MY_SEGMENTS_UPDATE_V2 SegmentRemoval event. * 1.7 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) - * 1.941 secs: /myLargeSegments/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SPLIT_UPDATE event - * 2.1 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 1.941 secs: /mySegments/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SDK_UPDATE event + * 2.2 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { assert.plan(44); @@ -258,7 +255,7 @@ export function testSynchronization(fetchMock, assert) { const EXPECTED_DELAY = 241; client.once(client.Event.SDK_UPDATE, () => { - assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching myLargeSegments with a delay'); + assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching mySegments with a delay'); assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation after myLargeSegment fetch'); }); @@ -267,7 +264,7 @@ export function testSynchronization(fetchMock, assert) { setTimeout(() => { assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation before large segment removal'); - assert.deepEqual(sharedClients.map(c => c.getTreatment('in_large_segment')), ['no', 'no', 'no', 'no'], 'evaluation before segment removal'); + assert.deepEqual(sharedClients.map(c => c.getTreatment('in_large_segment')), ['no', 'no', 'no', 'no'], 'evaluation before large segment removal'); client.once(client.Event.SDK_UPDATE, () => { assert.equal(client.getTreatment('in_large_segment'), 'no', 'evaluation after large segment removal'); @@ -329,9 +326,8 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsNicolasMock1 }; }); - fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); - // split and segment sync after SSE opened + // sync all after SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); @@ -342,7 +338,6 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsNicolasMock1 }; }); - fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: [] } }); // fetch due to SPLIT_UPDATE event fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { @@ -363,15 +358,13 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: splitChangesMock4 }; }); - // initial fetch of mySegments and myLargeSegments for new client + // initial fetch of mySegments for new client fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsMarcio }; }); - fetchMock.getOnce(url(settings, '/myLargeSegments/marcio%40split.io'), { status: 200, body: { myLargeSegments: [] } }); - - // sync after second SSE opened + // sync all after second SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SECOND_SSE_OPEN), 'sync after second SSE connection is opened'); @@ -386,38 +379,27 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsMarcio }; }); - fetchMock.get({ url: url(settings, '/myLargeSegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); - fetchMock.get({ url: url(settings, '/myLargeSegments/marcio%40split.io'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); - // 3 unbounded fetch requests + // 3 unbounded fetch for MY_SEGMENTS_UPDATE_V2 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 3 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsNicolasMock2 }; }); - fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 3 }, function (url, opts) { + fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: { ...mySegmentsNicolasMock2, myLargeSegments: ['employees', 'splitters'] } }); + fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 4 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: mySegmentsMarcio }; }); - // initial fetch of mySegments and myLargeSegments for other clients + sync after third SSE opened + 3 unbounded fetch requests for mySegments + // initial fetch of mySegments for other clients + sync all after third SSE opened + 3 unbounded fetch for MY_SEGMENTS_UPDATE_V2 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); - fetchMock.get({ url: url(settings, '/mySegments/key1'), repeat: 5 }, { status: 200, body: { mySegments: [] } }); - fetchMock.get({ url: url(settings, '/mySegments/key3'), repeat: 5 }, { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); + fetchMock.get({ url: url(settings, '/mySegments/key1'), repeat: 6 }, { status: 200, body: { mySegments: [] } }); + fetchMock.get({ url: url(settings, '/mySegments/key3'), repeat: 6 }, { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); fetchMock.get({ url: url(settings, `/mySegments/${bitmapTrueKey}`), repeat: 5 }, { status: 200, body: { mySegments: [] } }); - fetchMock.get({ url: url(settings, '/myLargeSegments/key1'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); - fetchMock.get({ url: url(settings, '/myLargeSegments/key3'), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); - fetchMock.get({ url: url(settings, `/myLargeSegments/${bitmapTrueKey}`), repeat: 2 }, { status: 200, body: { myLargeSegments: [] } }); // bounded fetch request fetchMock.get(url(settings, `/mySegments/${bitmapTrueKey}`), { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); - // unbounded myLargeSegments fetch requests - fetchMock.getOnce(url(settings, '/myLargeSegments/nicolas%40split.io'), { status: 200, body: { myLargeSegments: ['employees', 'splitters'] } }); - fetchMock.getOnce(url(settings, '/myLargeSegments/marcio%40split.io'), { status: 200, body: { myLargeSegments: [] } }); - fetchMock.getOnce(url(settings, '/myLargeSegments/key1'), { status: 200, body: { myLargeSegments: [] } }); - fetchMock.getOnce(url(settings, '/myLargeSegments/key3'), { status: 200, body: { myLargeSegments: [] } }); - fetchMock.getOnce(url(settings, `/myLargeSegments/${bitmapTrueKey}`), { status: 200, body: { myLargeSegments: [] } }); - fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); }); diff --git a/src/__tests__/browserSuites/readiness-large-segments.spec.js b/src/__tests__/browserSuites/readiness-large-segments.spec.js deleted file mode 100644 index def7007c0..000000000 --- a/src/__tests__/browserSuites/readiness-large-segments.spec.js +++ /dev/null @@ -1,149 +0,0 @@ -import { SplitFactory } from '../../'; - -// Mocks -import mySegments from '../mocks/mysegments.nicolas@split.io.json'; -import myLargeSegments from '../mocks/mylargesegments.employees.json'; -import { nearlyEqual } from '../testUtils'; - -const FF = { - name: 'FF', - status: 'ACTIVE', - conditions: [{ - matcherGroup: { - combiner: 'AND', - matchers: [] - } - }] -}; - -const FF_WITH_SEGMENTS = { - name: 'FF_WITH_SEGMENTS', - status: 'ACTIVE', - conditions: [{ - matcherGroup: { - combiner: 'AND', - matchers: [{ - matcherType: 'IN_SEGMENT', - userDefinedSegmentMatcherData: { - segmentName: 'A' - } - }] - } - }] -}; - -const FF_WITH_LARGE_SEGMENTS = { - name: 'FF_WITH_LARGE_SEGMENTS', - status: 'ACTIVE', - conditions: [{ - matcherGroup: { - combiner: 'AND', - matchers: [{ - matcherType: 'IN_LARGE_SEGMENT', - userDefinedSegmentMatcherData: { - segmentName: 'A' - } - }] - } - }] -}; - -const waitConfig = { - core: { - authorizationKey: '', - key: 'emi@split.io' - }, - urls: { - sdk: 'https://sdk.baseurl/largeSegments', - }, - sync: { - largeSegmentsEnabled: true - }, - streamingEnabled: false -}; - -const noWaitConfig = { - ...waitConfig, - startup: { - waitForLargeSegments: false - } -}; - -const SEGMENTS_DELAY = 50; -const LARGE_SEGMENTS_DELAY = 100; -const TEST_END_DELAY = 150; - -export default function (fetchMock, assert) { - - const testCases = [ - { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: true }, - { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: false }, - { waitForLargeSegments: true, featureFlagsWithSegments: false, featureFlagsWithLS: true }, - { waitForLargeSegments: true, featureFlagsWithSegments: false, featureFlagsWithLS: false }, - { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: true }, - { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: false }, - { waitForLargeSegments: false, featureFlagsWithSegments: false, featureFlagsWithLS: true }, - { waitForLargeSegments: false, featureFlagsWithSegments: false, featureFlagsWithLS: false }, - - // Special cases where large segments are not supported for the given SDK key: `/myLargeSegments/*` responds with 403 and there cannot be FFs with large segments - { waitForLargeSegments: true, featureFlagsWithSegments: true, featureFlagsWithLS: false, myLargeSegmentsForbidden: true }, - { waitForLargeSegments: false, featureFlagsWithSegments: true, featureFlagsWithLS: false, myLargeSegmentsForbidden: true }, - ]; - - testCases.forEach(({ waitForLargeSegments, featureFlagsWithSegments, featureFlagsWithLS, myLargeSegmentsForbidden }) => { - - const config = waitForLargeSegments ? waitConfig : noWaitConfig; - - const splitChangesMock = { - since: -1, - till: 1457552620999, - splits: [FF, featureFlagsWithSegments && FF_WITH_SEGMENTS, featureFlagsWithLS && FF_WITH_LARGE_SEGMENTS].filter(ff => ff) - }; - - // smart ready: if FFs are not using segments (or LS) we don't need to wait for them - const SDK_READY_DELAY = Math.max( - featureFlagsWithSegments ? SEGMENTS_DELAY : 0, - featureFlagsWithLS && waitForLargeSegments ? LARGE_SEGMENTS_DELAY : 0 - ); - - // emit SDK_UPDATE if large segments arrive after SDK_READY event is emitted and FFs are using them - const shouldEmitSdkUpdate = waitForLargeSegments === false && featureFlagsWithLS === true && (LARGE_SEGMENTS_DELAY > SEGMENTS_DELAY || featureFlagsWithSegments === false); - - assert.test(t => { - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { since: 1457552620999, till: 1457552620999, splits: [] } }); - fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: mySegments }, { delay: SEGMENTS_DELAY }); - fetchMock.getOnce(config.urls.sdk + '/myLargeSegments/emi%40split.io', { status: myLargeSegmentsForbidden ? 403 : 200, body: myLargeSegments }, { delay: LARGE_SEGMENTS_DELAY }); - - // smart pausing: if FFs are not using segments (or LS) we don't need to fetch them - if (featureFlagsWithSegments) fetchMock.getOnce(config.urls.sdk + '/mySegments/shared', { status: 200, body: mySegments }, { delay: SEGMENTS_DELAY }); - if (featureFlagsWithLS) fetchMock.getOnce(config.urls.sdk + '/myLargeSegments/shared', { status: myLargeSegmentsForbidden ? 403 : 200, body: myLargeSegments }, { delay: LARGE_SEGMENTS_DELAY }); - - const splitio = SplitFactory(config); - const client = splitio.client(); - - const start = Date.now(); - client.once(client.Event.SDK_READY, () => { - assert.true(nearlyEqual(Date.now() - start, SDK_READY_DELAY)); - - splitio.client('shared').ready().then(() => { - assert.true(nearlyEqual(Date.now() - start, 2 * SDK_READY_DELAY)); - }); - }); - - let updateEmitted = false; - - client.once(client.Event.SDK_UPDATE, () => { - assert.true(nearlyEqual(Date.now() - start, LARGE_SEGMENTS_DELAY)); - updateEmitted = true; - }); - - setTimeout(() => { - assert.true(updateEmitted === shouldEmitSdkUpdate); - client.destroy().then(() => { t.end(); }); - }, TEST_END_DELAY); - }); - - }); - -} diff --git a/src/__tests__/browserSuites/ready-from-cache.spec.js b/src/__tests__/browserSuites/ready-from-cache.spec.js index 36c0adf87..16adc2d3e 100644 --- a/src/__tests__/browserSuites/ready-from-cache.spec.js +++ b/src/__tests__/browserSuites/ready-from-cache.spec.js @@ -489,7 +489,6 @@ export default function (fetchMock, assert) { t.plan(7); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - // fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999&names=p1__split', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); localStorage.setItem('some_user_item', 'user_item'); diff --git a/src/__tests__/mocks/mylargesegments.employees.json b/src/__tests__/mocks/mylargesegments.employees.json deleted file mode 100644 index e820681d0..000000000 --- a/src/__tests__/mocks/mylargesegments.employees.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "myLargeSegments": [ - "employees" - ], - "till": 1234567890 -} diff --git a/src/__tests__/mocks/splitchanges.real.withSegments.json b/src/__tests__/mocks/splitchanges.real.withSegments.json index 3f474a14f..a9d4149f4 100644 --- a/src/__tests__/mocks/splitchanges.real.withSegments.json +++ b/src/__tests__/mocks/splitchanges.real.withSegments.json @@ -1,47 +1,5 @@ { "splits": [ - { - "orgId": null, - "environment": null, - "trafficTypeId": null, - "trafficTypeName": null, - "name": "in_large_segment", - "seed": -1984784937, - "status": "ACTIVE", - "killed": false, - "defaultTreatment": "no", - "conditions": [ - { - "matcherGroup": { - "combiner": "AND", - "matchers": [ - { - "keySelector": { - "trafficType": "user", - "attribute": null - }, - "matcherType": "IN_LARGE_SEGMENT", - "negate": false, - "userDefinedSegmentMatcherData": { - "segmentName": "harnessians" - }, - "whitelistMatcherData": null, - "unaryNumericMatcherData": null, - "betweenMatcherData": null, - "unaryStringMatcherData": null - } - ] - }, - "partitions": [ - { - "treatment": "yes", - "size": 100 - } - ] - } - ], - "configurations": {} - }, { "trafficTypeName": "user", "name": "real_split", diff --git a/src/__tests__/nodeSuites/push-synchronization.spec.js b/src/__tests__/nodeSuites/push-synchronization.spec.js index cb60de633..67ee0c18c 100644 --- a/src/__tests__/nodeSuites/push-synchronization.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization.spec.js @@ -44,9 +44,6 @@ const config = { }, urls: baseUrls, streamingEnabled: true, - sync: { - largeSegmentsEnabled: true // ignored in node - } }; const settings = settingsFactory(config); diff --git a/src/__tests__/offline/browser.spec.js b/src/__tests__/offline/browser.spec.js index bb1961b0b..10ef846d5 100644 --- a/src/__tests__/offline/browser.spec.js +++ b/src/__tests__/offline/browser.spec.js @@ -59,11 +59,7 @@ tape('Browser offline mode', function (assert) { startup: { eventsFirstPushWindow: 0 }, - features: originalFeaturesMap, - sync: { - // ignored - largeSegmentsEnabled: true - } + features: originalFeaturesMap }; const factory = SplitFactory(config); const manager = factory.manager(); diff --git a/src/__tests__/online/browser.spec.js b/src/__tests__/online/browser.spec.js index 4616ae22a..74574666a 100644 --- a/src/__tests__/online/browser.spec.js +++ b/src/__tests__/online/browser.spec.js @@ -9,7 +9,6 @@ import impressionsSuiteNone from '../browserSuites/impressions.none.spec'; import telemetrySuite from '../browserSuites/telemetry.spec'; import impressionsListenerSuite from '../browserSuites/impressions-listener.spec'; import readinessSuite from '../browserSuites/readiness.spec'; -import readinessWithLargeSegmentsSuite from '../browserSuites/readiness-large-segments.spec'; import readyFromCache from '../browserSuites/ready-from-cache.spec'; import { withoutBindingTT, bindingTT } from '../browserSuites/events.spec'; import sharedInstantiationSuite from '../browserSuites/shared-instantiation.spec'; @@ -123,7 +122,6 @@ tape('## E2E CI Tests ##', function (assert) { assert.test('E2E / Manager API', managerSuite.bind(null, settings, fetchMock)); /* Validate readiness */ assert.test('E2E / Readiness', readinessSuite.bind(null, fetchMock)); - assert.test('E2E / Readiness with large segments', readinessWithLargeSegmentsSuite.bind(null, fetchMock)); /* Validate headers for ip and hostname are not sended with requests (ignore setting IPAddressesEnabled) */ assert.test('E2E / Ignore setting IPAddressesEnabled', ignoreIpAddressesSettingSuite.bind(null, fetchMock)); /* Check that impressions and events are sended to backend via Beacon API or Fetch when pagehide/visibilitychange events are triggered. */ diff --git a/src/settings/browser.js b/src/settings/browser.js index 2c8d4dd9d..d3f04443e 100644 --- a/src/settings/browser.js +++ b/src/settings/browser.js @@ -3,7 +3,6 @@ import { validateRuntime } from '@splitsoftware/splitio-commons/src/utils/settin import { validateLogger } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/logger/builtinLogger'; import { LocalhostFromObject } from '@splitsoftware/splitio-commons/src/sync/offline/LocalhostFromObject'; import { validateConsent } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/consent'; -import { STANDALONE_MODE } from '@splitsoftware/splitio-commons/src/utils/constants'; import { defaults } from './defaults/browser'; import { validateStorage } from './storage/browser'; @@ -21,10 +20,5 @@ const params = { }; export function settingsFactory(config) { - const settings = settingsValidation(config, params); - - // Override in localhost mode to emit SDK_READY event - if (settings.mode !== STANDALONE_MODE) settings.sync.largeSegmentsEnabled = false; - - return settings; + return settingsValidation(config, params); } diff --git a/src/settings/defaults/browser.js b/src/settings/defaults/browser.js index 3ee779a0c..60d47f324 100644 --- a/src/settings/defaults/browser.js +++ b/src/settings/defaults/browser.js @@ -10,9 +10,7 @@ export const defaults = { // Maximum amount of time used before notifies me a timeout. readyTimeout: 10, // Amount of time we will wait before the first push of events. - eventsFirstPushWindow: 10, - // Wait for large segments to emit SDK_READY event. - waitForLargeSegments: true, + eventsFirstPushWindow: 10 }, // Consent is considered granted by default diff --git a/src/settings/defaults/node.js b/src/settings/defaults/node.js index 9fa045334..6ba27b528 100644 --- a/src/settings/defaults/node.js +++ b/src/settings/defaults/node.js @@ -13,9 +13,7 @@ export const defaults = { // Maximum amount of time used before notifies me a timeout. readyTimeout: 15, // Don't wait a specific time for first flush on Node, no page load here. - eventsFirstPushWindow: 0, - // Don't wait for large segments to emit SDK_READY event. - waitForLargeSegments: false, + eventsFirstPushWindow: 0 }, features: '.split', diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index d64abdf90..22f2f5139 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.27.1-rc.2'; +export const packageVersion = '10.27.1-rc.3'; diff --git a/src/settings/node.js b/src/settings/node.js index c889b8499..e91c5a76b 100644 --- a/src/settings/node.js +++ b/src/settings/node.js @@ -20,10 +20,5 @@ export function settingsFactory(config) { // if provided, keeps reference to the `requestOptions` object if (settings.sync.requestOptions) settings.sync.requestOptions = config.sync.requestOptions; - - // Reset config options not supported in Node.js - if (settings.sync.largeSegmentsEnabled) settings.log.warn('Client instantiation: config.sync.largeSegmentsEnabled option is not supported in NodeJS. Ignoring it.'); - settings.sync.largeSegmentsEnabled = false; - return settings; } diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 0b1527ac0..60114899d 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -124,7 +124,7 @@ splitView = { configs: { off: '{"dimensions":"{\"height\":20,\"width\":40}"}' }, - sets: ['set_a','set_b'], + sets: ['set_a', 'set_b'], defaultTreatment: 'off' }; splitViews = [splitView]; @@ -178,7 +178,7 @@ const instantiatedSettingsCore: { } = SDK.settings.core; const instantiatedSettingsMode: ('standalone' | 'consumer') = SDK.settings.mode; const instantiatedSettingsScheduler: { [key: string]: number } = SDK.settings.scheduler; -const instantiatedSettingsStartup: { [key: string]: number | boolean } = SDK.settings.startup; +const instantiatedSettingsStartup: { [key: string]: number } = SDK.settings.startup; const instantiatedSettingsStorage: { prefix: string, options: Object, @@ -535,7 +535,6 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { metricsRefreshRate: 1, telemetryRefreshRate: 1, segmentsRefreshRate: 1, - largeSegmentsRefreshRate: 1, offlineRefreshRate: 1, eventsPushRate: 1, eventsQueueSize: 1, @@ -545,8 +544,7 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { readyTimeout: 1, requestTimeoutBeforeReady: 1, retriesOnFailureBeforeReady: 1, - eventsFirstPushWindow: 1, - waitForLargeSegments: true, + eventsFirstPushWindow: 1 }, urls: { sdk: 'https://asd.com/sdk', @@ -567,8 +565,7 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { sync: { splitFilters: splitFilters, impressionsMode: 'DEBUG', - enabled: true, - largeSegmentsEnabled: true, + enabled: true }, userConsent: 'GRANTED' }; diff --git a/types/splitio.d.ts b/types/splitio.d.ts index b7598f373..b3d4a4b67 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -78,7 +78,6 @@ interface ISettings { metricsRefreshRate?: number, telemetryRefreshRate: number, segmentsRefreshRate: number, - largeSegmentsRefreshRate: number, offlineRefreshRate: number, eventsPushRate: number, eventsQueueSize: number, @@ -88,8 +87,7 @@ interface ISettings { readyTimeout: number, requestTimeoutBeforeReady: number, retriesOnFailureBeforeReady: number, - eventsFirstPushWindow: number, - waitForLargeSegments: boolean + eventsFirstPushWindow: number }, readonly storage: { prefix: string, @@ -114,7 +112,6 @@ interface ISettings { splitFilters: SplitIO.SplitFilter[], impressionsMode: SplitIO.ImpressionsMode, enabled: boolean, - largeSegmentsEnabled: boolean, flagSpecVersion: string } /** @@ -985,13 +982,6 @@ declare namespace SplitIO { * @default 10 */ eventsFirstPushWindow?: number, - /** - * Whether the SDK should wait for large segments to be ready before emitting SDK_READY event. - * It only applies if largeSegmentsEnabled is true. - * @property {boolean} waitForLargeSegments - * @default true - */ - waitForLargeSegments?: boolean }, /** * SDK scheduler settings. @@ -1036,13 +1026,6 @@ declare namespace SplitIO { * @default 60 */ segmentsRefreshRate?: number, - /** - * The SDK polls Split servers for changes to large segment definitions. This parameter controls this polling period in seconds. - * It only applies if largeSegmentsEnabled is true. - * @property {number} largeSegmentsRefreshRate - * @default 60 - */ - largeSegmentsRefreshRate?: number, /** * The SDK posts the queued events data in bulks. This parameter controls the posting rate in seconds. * @property {number} eventsPushRate @@ -1144,15 +1127,7 @@ declare namespace SplitIO { * @typedef {string} userConsent * @default 'GRANTED' */ - userConsent?: ConsentStatus, - sync?: ISharedSettings['sync'] & { - /** - * Enables synchronization of large segments. - * @property {boolean} largeSegmentsEnabled - * @default false - */ - largeSegmentsEnabled?: boolean - } + userConsent?: ConsentStatus } /** * Settings interface for SDK instances created on NodeJS. From 3b3c3b5f725539ebf7306ebecfabd5465f30f489 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 29 Aug 2024 22:25:37 +0100 Subject: [PATCH 19/58] Test updates --- package-lock.json | 680 ++++++++---------- package.json | 2 +- .../browserSuites/evaluations-semver.spec.js | 4 +- .../browserSuites/evaluations.spec.js | 2 +- .../fetch-specific-splits.spec.js | 4 +- src/__tests__/browserSuites/flag-sets.spec.js | 6 +- .../ignore-ip-addresses-setting.spec.js | 2 +- .../browserSuites/impressions.debug.spec.js | 4 +- .../browserSuites/impressions.none.spec.js | 6 +- .../browserSuites/impressions.spec.js | 4 +- .../browserSuites/push-corner-cases.spec.js | 8 +- .../browserSuites/push-fallback.spec.js | 79 +- .../browserSuites/push-flag-sets.spec.js | 2 +- .../push-initialization-nopush.spec.js | 10 +- .../push-initialization-retries.spec.js | 34 +- .../browserSuites/push-refresh-token.spec.js | 10 +- .../push-synchronization-retries.spec.js | 42 +- .../push-synchronization.spec.js | 181 ++--- src/__tests__/browserSuites/readiness.spec.js | 164 ++--- .../browserSuites/ready-from-cache.spec.js | 88 +-- .../browserSuites/ready-promise.spec.js | 34 +- .../shared-instantiation.spec.js | 6 +- .../browserSuites/single-sync.spec.js | 14 +- src/__tests__/browserSuites/telemetry.spec.js | 10 +- .../use-beacon-api.debug.spec.js | 4 +- .../browserSuites/use-beacon-api.spec.js | 4 +- src/__tests__/destroy/browser.spec.js | 10 +- src/__tests__/errorCatching/browser.spec.js | 4 +- src/__tests__/gaIntegration/browser.spec.js | 4 +- .../mocks/memberships.emmanuel@split.io.json | 15 + .../mocks/memberships.facundo@split.io.json | 9 + .../mocks/memberships.marcio@split.io.json | 3 + .../mocks/memberships.nicolas@split.io.json | 15 + .../memberships.nicolas@split.io.mock2.json | 15 + src/__tests__/mocks/membershipsEmpty.json | 5 + ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 2 +- ...GMENTS_UPDATE.UNBOUNDED.1457552650000.json | 4 - ..._UPDATE.UNBOUNDED.DELAY.1457552650000.json | 4 + ..._UPDATE.marcio@split.io.1457552645000.json | 4 - ..._UPDATE.marcio@split.io.1457552646000.json | 4 - ...UPDATE.nicolas@split.io.1457552640000.json | 4 - ...UPDATE.nicolas@split.io.1457552641000.json | 4 - ..._UPDATE_V3.BOUNDED.GZIP.1457552651000.json | 4 + ..._UPDATE_V3.BOUNDED.ZLIB.1457552651000.json | 4 + ..._UPDATE_V3.KEYLIST.GZIP.1457552652000.json | 4 + ...DATE_V3.SEGMENT_REMOVAL.1457552653000.json | 4 + ...NTS_UPDATE_V3.UNBOUNDED.1457552640000.json | 4 + ...NTS_UPDATE_V3.UNBOUNDED.1457552650000.json | 4 + ...message.V2.BOUNDED.GZIP.1457552651000.json | 4 - ...message.V2.BOUNDED.ZLIB.1457552651000.json | 4 - ...message.V2.KEYLIST.GZIP.1457552652000.json | 4 - ...sage.V2.SEGMENT_REMOVAL.1457552653000.json | 4 - .../message.V2.UNBOUNDED.1457552650000.json | 4 - src/__tests__/mocks/mySegmentsEmpty.json | 3 - .../mocks/mysegments.emmanuel@split.io.json | 16 - .../mocks/mysegments.facundo@split.io.json | 8 - .../mocks/mysegments.marcio@split.io.json | 3 - .../mocks/mysegments.nicolas@split.io.json | 16 - .../mysegments.nicolas@split.io.mock2.json | 16 - .../push-initialization-retries.spec.js | 6 +- src/__tests__/offline/browser.spec.js | 6 +- src/__tests__/offline/node.spec.js | 6 +- src/__tests__/online/browser.spec.js | 16 +- 63 files changed, 768 insertions(+), 882 deletions(-) create mode 100644 src/__tests__/mocks/memberships.emmanuel@split.io.json create mode 100644 src/__tests__/mocks/memberships.facundo@split.io.json create mode 100644 src/__tests__/mocks/memberships.marcio@split.io.json create mode 100644 src/__tests__/mocks/memberships.nicolas@split.io.json create mode 100644 src/__tests__/mocks/memberships.nicolas@split.io.mock2.json create mode 100644 src/__tests__/mocks/membershipsEmpty.json delete mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json create mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552645000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552646000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552641000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json create mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json delete mode 100644 src/__tests__/mocks/message.V2.BOUNDED.GZIP.1457552651000.json delete mode 100644 src/__tests__/mocks/message.V2.BOUNDED.ZLIB.1457552651000.json delete mode 100644 src/__tests__/mocks/message.V2.KEYLIST.GZIP.1457552652000.json delete mode 100644 src/__tests__/mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json delete mode 100644 src/__tests__/mocks/message.V2.UNBOUNDED.1457552650000.json delete mode 100644 src/__tests__/mocks/mySegmentsEmpty.json delete mode 100644 src/__tests__/mocks/mysegments.emmanuel@split.io.json delete mode 100644 src/__tests__/mocks/mysegments.facundo@split.io.json delete mode 100644 src/__tests__/mocks/mysegments.marcio@split.io.json delete mode 100644 src/__tests__/mocks/mysegments.nicolas@split.io.json delete mode 100644 src/__tests__/mocks/mysegments.nicolas@split.io.mock2.json diff --git a/package-lock.json b/package-lock.json index 94e9163aa..f9283ab20 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.1-rc.3", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.8", + "@splitsoftware/splitio-commons": "1.16.1-rc.10", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -732,33 +732,33 @@ } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" } }, "node_modules/@jridgewell/source-map/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" @@ -771,13 +771,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@mdn/browser-compat-data": { @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.8", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.8.tgz", - "integrity": "sha512-scvmDXE3aY72kYtKTkzMc06uZ6O/FZjaet+vAekSofRuzAkpmKzgvk4xiCBjFfONaPb66Dvw4SO7M34ym3gwQg==", + "version": "1.16.1-rc.10", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.10.tgz", + "integrity": "sha512-FK8zFFgrSgPWZVDYsOMQPXMycwUzjwaTQLq7ZrGbCW2sGF8UujiRmwsCQEmghMAU+eq9rLlIvVFUIA5Px1sbqw==", "dependencies": { "tslib": "^2.3.1" }, @@ -926,30 +926,10 @@ "@types/node": "*" } }, - "node_modules/@types/eslint": { - "version": "8.4.8", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.8.tgz", - "integrity": "sha512-zUCKQI1bUCTi+0kQs5ZQzQ/XILWRLIlh15FXWNykJ+NG3TMKMVvwwC6GP3DR1Ylga15fB7iAExSzc4PNlR5i3w==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "node_modules/@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "node_modules/@types/google.analytics": { @@ -966,9 +946,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "node_modules/@types/json5": { @@ -1009,148 +989,148 @@ } }, "node_modules/@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "dependencies": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -1227,10 +1207,10 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "peerDependencies": { "acorn": "^8" @@ -2564,9 +2544,9 @@ "dev": true }, "node_modules/elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", "dev": true, "dependencies": { "bn.js": "^4.11.9", @@ -2660,9 +2640,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "dependencies": { "graceful-fs": "^4.2.4", @@ -2729,9 +2709,9 @@ } }, "node_modules/es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "node_modules/es-shim-unscopables": { @@ -3597,9 +3577,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/graphemer": { @@ -4691,12 +4671,12 @@ "dev": true }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -6200,9 +6180,9 @@ "dev": true }, "node_modules/schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.8", @@ -6238,9 +6218,9 @@ } }, "node_modules/serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "dependencies": { "randombytes": "^2.1.0" @@ -6849,13 +6829,13 @@ } }, "node_modules/terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "dependencies": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" }, @@ -6867,16 +6847,16 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "dependencies": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" }, "engines": { "node": ">= 10.13.0" @@ -7395,9 +7375,9 @@ } }, "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, "dependencies": { "glob-to-regexp": "^0.4.1", @@ -7414,34 +7394,33 @@ "dev": true }, "node_modules/webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "bin": { @@ -8313,30 +8292,30 @@ "dev": true }, "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true }, "@jridgewell/source-map": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz", - "integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==", + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz", + "integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==", "dev": true, "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.1", + "@jridgewell/set-array": "^1.2.1", "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/trace-mapping": "^0.3.24" } } } @@ -8348,13 +8327,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.17", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", - "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", + "version": "0.3.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@mdn/browser-compat-data": { @@ -8437,9 +8416,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.8", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.8.tgz", - "integrity": "sha512-scvmDXE3aY72kYtKTkzMc06uZ6O/FZjaet+vAekSofRuzAkpmKzgvk4xiCBjFfONaPb66Dvw4SO7M34ym3gwQg==", + "version": "1.16.1-rc.10", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.10.tgz", + "integrity": "sha512-FK8zFFgrSgPWZVDYsOMQPXMycwUzjwaTQLq7ZrGbCW2sGF8UujiRmwsCQEmghMAU+eq9rLlIvVFUIA5Px1sbqw==", "requires": { "tslib": "^2.3.1" } @@ -8483,30 +8462,10 @@ "@types/node": "*" } }, - "@types/eslint": { - "version": "8.4.8", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.8.tgz", - "integrity": "sha512-zUCKQI1bUCTi+0kQs5ZQzQ/XILWRLIlh15FXWNykJ+NG3TMKMVvwwC6GP3DR1Ylga15fB7iAExSzc4PNlR5i3w==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.4", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.4.tgz", - "integrity": "sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, "@types/estree": { - "version": "0.0.51", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.51.tgz", - "integrity": "sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@types/google.analytics": { @@ -8523,9 +8482,9 @@ } }, "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, "@types/json5": { @@ -8566,148 +8525,148 @@ } }, "@webassemblyjs/ast": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.1.tgz", - "integrity": "sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.12.1.tgz", + "integrity": "sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==", "dev": true, "requires": { - "@webassemblyjs/helper-numbers": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1" + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" } }, "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz", - "integrity": "sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz", - "integrity": "sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz", - "integrity": "sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.12.1.tgz", + "integrity": "sha512-nzJwQw99DNDKr9BVCOZcLuJJUlqkJh+kVzVl6Fmq/tI5ZtEyWT1KZMyOXltXLZJmDtvLCDgwsyrkohEtopTXCw==", "dev": true }, "@webassemblyjs/helper-numbers": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz", - "integrity": "sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", "@xtuc/long": "4.2.2" } }, "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz", - "integrity": "sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz", - "integrity": "sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.12.1.tgz", + "integrity": "sha512-Jif4vfB6FJlUlSbgEMHUyk1j234GTNG9dBJ4XJdOySoj518Xj0oGsNi59cUQF4RRMS9ouBUxDDdyBVfPTypa5g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.12.1" } }, "@webassemblyjs/ieee754": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz", - "integrity": "sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" } }, "@webassemblyjs/leb128": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.1.tgz", - "integrity": "sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" } }, "@webassemblyjs/utf8": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.1.tgz", - "integrity": "sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==", + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz", - "integrity": "sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz", + "integrity": "sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/helper-wasm-section": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-opt": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", - "@webassemblyjs/wast-printer": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-opt": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1", + "@webassemblyjs/wast-printer": "1.12.1" } }, "@webassemblyjs/wasm-gen": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz", - "integrity": "sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.12.1.tgz", + "integrity": "sha512-TDq4Ojh9fcohAw6OIMXqiIcTq5KUXTGRkVxbSo1hQnSy6lAM5GSdfwWeSxpAo0YzgsgF182E/U0mDNhuA0tW7w==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wasm-opt": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz", - "integrity": "sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.12.1.tgz", + "integrity": "sha512-Jg99j/2gG2iaz3hijw857AVYekZe2SAskcqlWIZXjji5WStnOpVoat3gQfT/Q5tb2djnCjBtMocY/Su1GfxPBg==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-buffer": "1.11.1", - "@webassemblyjs/wasm-gen": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-buffer": "1.12.1", + "@webassemblyjs/wasm-gen": "1.12.1", + "@webassemblyjs/wasm-parser": "1.12.1" } }, "@webassemblyjs/wasm-parser": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz", - "integrity": "sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz", + "integrity": "sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/helper-api-error": "1.11.1", - "@webassemblyjs/helper-wasm-bytecode": "1.11.1", - "@webassemblyjs/ieee754": "1.11.1", - "@webassemblyjs/leb128": "1.11.1", - "@webassemblyjs/utf8": "1.11.1" + "@webassemblyjs/ast": "1.12.1", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" } }, "@webassemblyjs/wast-printer": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz", - "integrity": "sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.12.1.tgz", + "integrity": "sha512-+X4WAlOisVWQMikjbcvY2e0rwPsKQ9F688lksZhBcPycBBuii3O7m8FACbDMWDojpAqvjIncrG8J0XHKyQfVeA==", "dev": true, "requires": { - "@webassemblyjs/ast": "1.11.1", + "@webassemblyjs/ast": "1.12.1", "@xtuc/long": "4.2.2" } }, @@ -8762,10 +8721,10 @@ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, - "acorn-import-assertions": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz", - "integrity": "sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==", + "acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", "dev": true, "requires": {} }, @@ -9825,9 +9784,9 @@ "dev": true }, "elliptic": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", - "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "version": "6.5.7", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.7.tgz", + "integrity": "sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==", "dev": true, "requires": { "bn.js": "^4.11.9", @@ -9902,9 +9861,9 @@ "dev": true }, "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "version": "5.17.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", + "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", "dev": true, "requires": { "graceful-fs": "^4.2.4", @@ -9956,9 +9915,9 @@ } }, "es-module-lexer": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", - "integrity": "sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==", + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.5.4.tgz", + "integrity": "sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==", "dev": true }, "es-shim-unscopables": { @@ -10618,9 +10577,9 @@ } }, "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "graphemer": { @@ -11426,12 +11385,12 @@ "dev": true }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, "requires": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" } }, @@ -12596,9 +12555,9 @@ "dev": true }, "schema-utils": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.1.tgz", - "integrity": "sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", + "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", "dev": true, "requires": { "@types/json-schema": "^7.0.8", @@ -12621,9 +12580,9 @@ } }, "serialize-javascript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.0.tgz", - "integrity": "sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", "dev": true, "requires": { "randombytes": "^2.1.0" @@ -13100,28 +13059,28 @@ } }, "terser": { - "version": "5.15.1", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz", - "integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==", + "version": "5.31.6", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.31.6.tgz", + "integrity": "sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg==", "dev": true, "requires": { - "@jridgewell/source-map": "^0.3.2", - "acorn": "^8.5.0", + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", "commander": "^2.20.0", "source-map-support": "~0.5.20" } }, "terser-webpack-plugin": { - "version": "5.3.6", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.6.tgz", - "integrity": "sha512-kfLFk+PoLUQIbLmB1+PZDMRSZS99Mp+/MHqDNmMA6tOItzRt+Npe3E+fsMs5mfcM0wCtrrdU387UnV+vnSffXQ==", + "version": "5.3.10", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz", + "integrity": "sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==", "dev": true, "requires": { - "@jridgewell/trace-mapping": "^0.3.14", + "@jridgewell/trace-mapping": "^0.3.20", "jest-worker": "^27.4.5", "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.0", - "terser": "^5.14.1" + "serialize-javascript": "^6.0.1", + "terser": "^5.26.0" } }, "text-table": { @@ -13486,9 +13445,9 @@ "dev": true }, "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", "dev": true, "requires": { "glob-to-regexp": "^0.4.1", @@ -13502,34 +13461,33 @@ "dev": true }, "webpack": { - "version": "5.76.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.76.0.tgz", - "integrity": "sha512-l5sOdYBDunyf72HW8dF23rFtWq/7Zgvt/9ftMof71E/yUb1YLOBmTgA2K4vQthB3kotMrSj609txVE0dnr2fjA==", + "version": "5.94.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.94.0.tgz", + "integrity": "sha512-KcsGn50VT+06JH/iunZJedYGUJS5FGjow8wb9c0v5n1Om8O1g4L6LjtfxwlXIATopoQu+vOXXa7gYisWxCoPyg==", "dev": true, "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^0.0.51", - "@webassemblyjs/ast": "1.11.1", - "@webassemblyjs/wasm-edit": "1.11.1", - "@webassemblyjs/wasm-parser": "1.11.1", + "@types/estree": "^1.0.5", + "@webassemblyjs/ast": "^1.12.1", + "@webassemblyjs/wasm-edit": "^1.12.1", + "@webassemblyjs/wasm-parser": "^1.12.1", "acorn": "^8.7.1", - "acorn-import-assertions": "^1.7.6", - "browserslist": "^4.14.5", + "acorn-import-attributes": "^1.9.5", + "browserslist": "^4.21.10", "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.10.0", - "es-module-lexer": "^0.9.0", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", "eslint-scope": "5.1.1", "events": "^3.2.0", "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", + "graceful-fs": "^4.2.11", "json-parse-even-better-errors": "^2.3.1", "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.1.0", + "schema-utils": "^3.2.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.1.3", - "watchpack": "^2.4.0", + "terser-webpack-plugin": "^5.3.10", + "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, "dependencies": { diff --git a/package.json b/package.json index 7dd987331..7c864214c 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.8", + "@splitsoftware/splitio-commons": "1.16.1-rc.10", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/evaluations-semver.spec.js b/src/__tests__/browserSuites/evaluations-semver.spec.js index 97e7ddb43..716c5467d 100644 --- a/src/__tests__/browserSuites/evaluations-semver.spec.js +++ b/src/__tests__/browserSuites/evaluations-semver.spec.js @@ -27,8 +27,8 @@ export default async function (fetchMock, assert) { fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); - fetchMock.getOnce(config.urls.sdk + '/mySegments/emi%40split.io', { status: 200, body: { mySegments: [] } }); - fetchMock.getOnce(config.urls.sdk + '/mySegments/2nd', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(config.urls.sdk + '/memberships/emi%40split.io', { status: 200, body: { ms: {} } }); + fetchMock.getOnce(config.urls.sdk + '/memberships/2nd', { status: 200, body: { ms: {} } }); const splitio = SplitFactory(config); const client = splitio.client(); diff --git a/src/__tests__/browserSuites/evaluations.spec.js b/src/__tests__/browserSuites/evaluations.spec.js index cc8bee2cc..b40b0b1d3 100644 --- a/src/__tests__/browserSuites/evaluations.spec.js +++ b/src/__tests__/browserSuites/evaluations.spec.js @@ -365,7 +365,7 @@ export default function (config, fetchMock, assert) { for (i; i < SDK_INSTANCES_TO_TEST; i++) { let splitio = SplitFactory(config); - fetchMock.getOnce('https://sdk.split.io/api/mySegments/aaaaaaklmnbv', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce('https://sdk.split.io/api/memberships/aaaaaaklmnbv', { status: 200, body: { ms: {} } }); // on TA tests, this is going to return one against the mocked seed. let clientTABucket1 = splitio.client('aaaaaaklmnbv'); diff --git a/src/__tests__/browserSuites/fetch-specific-splits.spec.js b/src/__tests__/browserSuites/fetch-specific-splits.spec.js index 13196594c..a9f6b383e 100644 --- a/src/__tests__/browserSuites/fetch-specific-splits.spec.js +++ b/src/__tests__/browserSuites/fetch-specific-splits.spec.js @@ -33,7 +33,7 @@ export function fetchSpecificSplits(fetchMock, assert) { }); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; }); - fetchMock.get(urls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(urls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); factory = SplitFactory(config); @@ -68,7 +68,7 @@ export function fetchSpecificSplitsForFlagSets(fetchMock, assert) { let factory; const queryString = '&sets=4_valid,set_2,set_3,set_ww,set_x'; - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, async function () { diff --git a/src/__tests__/browserSuites/flag-sets.spec.js b/src/__tests__/browserSuites/flag-sets.spec.js index 14b335768..214c1a1fb 100644 --- a/src/__tests__/browserSuites/flag-sets.spec.js +++ b/src/__tests__/browserSuites/flag-sets.spec.js @@ -17,7 +17,7 @@ const baseConfig = { }; export default function flagSets(fetchMock, t) { - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); t.test(async (assert) => { let factory; @@ -135,7 +135,7 @@ export default function flagSets(fetchMock, t) { let factory, client = []; - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1', function () { return { status: 200, body: splitChange2}; @@ -172,7 +172,7 @@ export default function flagSets(fetchMock, t) { let factory, client = []; - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return { status: 200, body: splitChange2}; diff --git a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js index 285c9a2b6..60108065a 100644 --- a/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js +++ b/src/__tests__/browserSuites/ignore-ip-addresses-setting.spec.js @@ -103,7 +103,7 @@ export default function (fetchMock, assert) { const settings = settingsFactory(config); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(url(settings, `/mySegments/${encodeURIComponent(config.core.key)}`), { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(url(settings, `/memberships/${encodeURIComponent(config.core.key)}`), { status: 200, body: { ms: {} } }); // Init Split client const splitio = SplitFactory(config); diff --git a/src/__tests__/browserSuites/impressions.debug.spec.js b/src/__tests__/browserSuites/impressions.debug.spec.js index 3f8b5e136..18d875b4e 100644 --- a/src/__tests__/browserSuites/impressions.debug.spec.js +++ b/src/__tests__/browserSuites/impressions.debug.spec.js @@ -2,7 +2,7 @@ import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; import { DEBUG } from '@splitsoftware/splitio-commons/src/utils/constants'; import { url } from '../testUtils'; @@ -23,7 +23,7 @@ export default function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); const splitio = SplitFactory({ core: { diff --git a/src/__tests__/browserSuites/impressions.none.spec.js b/src/__tests__/browserSuites/impressions.none.spec.js index d71de1428..d90c407a7 100644 --- a/src/__tests__/browserSuites/impressions.none.spec.js +++ b/src/__tests__/browserSuites/impressions.none.spec.js @@ -2,7 +2,7 @@ import { SplitFactory } from '../..'; import { settingsFactory } from '../../settings/node'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; import { NONE } from '@splitsoftware/splitio-commons/src/utils/constants'; import { truncateTimeFrame } from '@splitsoftware/splitio-commons/src/utils/time'; import { url } from '../testUtils'; @@ -43,8 +43,8 @@ export default async function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); - fetchMock.get(url(settings, '/mySegments/emma%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); + fetchMock.get(url(settings, '/memberships/emma%40split.io'), { status: 200, body: membershipsFacundo }); const splitio = SplitFactory(config); const client = splitio.client(); diff --git a/src/__tests__/browserSuites/impressions.spec.js b/src/__tests__/browserSuites/impressions.spec.js index be5a60a33..aa4cff4c0 100644 --- a/src/__tests__/browserSuites/impressions.spec.js +++ b/src/__tests__/browserSuites/impressions.spec.js @@ -2,7 +2,7 @@ import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; import { OPTIMIZED } from '@splitsoftware/splitio-commons/src/utils/constants'; import { truncateTimeFrame } from '@splitsoftware/splitio-commons/src/utils/time'; import { url } from '../testUtils'; @@ -26,7 +26,7 @@ export default function (fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); const splitio = SplitFactory({ core: { diff --git a/src/__tests__/browserSuites/push-corner-cases.spec.js b/src/__tests__/browserSuites/push-corner-cases.spec.js index 61c953e28..a07d1c162 100644 --- a/src/__tests__/browserSuites/push-corner-cases.spec.js +++ b/src/__tests__/browserSuites/push-corner-cases.spec.js @@ -37,8 +37,8 @@ const MILLIS_SPLIT_CHANGES_RESPONSE = 400; /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection, SDK_READY_FROM_CACHE - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*), auth, SSE connection, SDK_READY_FROM_CACHE + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) * 0.2 secs: SPLIT_KILL event -> /splitChanges * 0.4 secs: /splitChanges response --> SDK_READY */ @@ -72,8 +72,8 @@ export function testSplitKillOnReadyFromCache(fetchMock, assert) { // 1 auth request fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }); - // 2 mySegments requests: initial sync and after SSE opened - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: { mySegments: [] } }); + // 2 memberships requests: initial sync and after SSE opened + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 2 }, { status: 200, body: { ms: {} } }); // 2 splitChanges request: initial sync and after SSE opened. Sync after SPLIT_KILL is not performed because SplitsSyncTask is "executing" fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=25'), { status: 200, body: splitChangesMock1 }, { delay: MILLIS_SPLIT_CHANGES_RESPONSE, /* delay response */ }); diff --git a/src/__tests__/browserSuites/push-fallback.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js index 339936510..a2ab4a54c 100644 --- a/src/__tests__/browserSuites/push-fallback.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -5,9 +5,9 @@ import splitChangesMock1 from '../mocks/splitchanges.real.withSegments.json'; // since: -1, till: 1457552620999 (for initial fetch) import splitChangesMock2 from '../mocks/splitchanges.real.updateWithSegments.json'; // since: 1457552620999, till: 1457552649999 (for SPLIT_UPDATE event) import splitChangesMock3 from '../mocks/splitchanges.real.updateWithoutSegments.json'; // since: 1457552649999, till: 1457552669999 (for second polling fetch) -import mySegmentsNicolasMock1 from '../mocks/mysegments.nicolas@split.io.json'; -import mySegmentsNicolasMock2 from '../mocks/mysegments.nicolas@split.io.mock2.json'; -import mySegmentsMarcio from '../mocks/mysegments.marcio@split.io.json'; +import membershipsNicolasMock1 from '../mocks/memberships.nicolas@split.io.json'; +import membershipsNicolasMock2 from '../mocks/memberships.nicolas@split.io.mock2.json'; +import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; import occupancy0ControlPriMessage from '../mocks/message.OCCUPANCY.0.control_pri.1586987434550.json'; import occupancy1ControlPriMessage from '../mocks/message.OCCUPANCY.1.control_pri.1586987434450.json'; @@ -20,7 +20,7 @@ import streamingPausedControlPriMessage2 from '../mocks/message.CONTROL.STREAMIN import streamingDisabledControlPriMessage from '../mocks/message.CONTROL.STREAMING_DISABLED.control_pri.1586987434950.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -78,26 +78,26 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/nicolas), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/nicolas) - * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/nicolas), auth, SSE connection + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/nicolas) + * 0.2 secs: Streaming down (OCCUPANCY event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas) * 0.3 secs: SPLIT_UPDATE event ignored * 0.4 secs: periodic fetch due to polling (/splitChanges) - * 0.45 secs: periodic fetch due to polling (/mySegments/nicolas) - * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /mySegments/nicolas) - * 0.55 secs: create a new client while streaming -> initial fetch (/mySegments/marcio), auth, SSE connection and syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio) + * 0.45 secs: periodic fetch due to polling (/memberships/nicolas) + * 0.5 secs: Streaming up (OCCUPANCY event) -> syncAll (/splitChanges, /memberships/nicolas) + * 0.55 secs: create a new client while streaming -> initial fetch (/memberships/marcio), auth, SSE connection and syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) * 0.6 secs: SPLIT_UPDATE event -> /splitChanges - * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio) - * 0.8 secs: MY_SEGMENTS_UPDATE event ignored + * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) + * 0.8 secs: MY_SEGMENTS_UPDATE_V3 event ignored * 0.9 secs: periodic fetch due to polling (/splitChanges) - * 0.95 secs: periodic fetch due to polling (/mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.1 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas - * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) + * 0.95 secs: periodic fetch due to polling (/memberships/nicolas, /memberships/marcio) + * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) + * 1.1 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas, /memberships/marcio + * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) * 1.3 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll and stop polling * 1.5 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll - * 1.6 secs: Streaming closed (CONTROL STREAMING_DISABLED event) -> fetch due to fallback to polling (/splitChanges, /mySegments/nicolas, /mySegments/marcio, /mySegments/facundo) - * 1.8 secs: periodic fetch due to polling (/splitChanges): due to update without segments, mySegments are not fetched + * 1.6 secs: Streaming closed (CONTROL STREAMING_DISABLED event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) + * 1.8 secs: periodic fetch due to polling (/splitChanges): due to update without segments, memberships are not fetched * 2.0 secs: periodic fetch due to polling (/splitChanges) * 2.1 secs: destroy client */ @@ -212,38 +212,38 @@ export function testFallback(fetchMock, assert) { return { status: 200, body: authPushEnabledNicolas }; }); - // initial split and mySegment sync + // initial split and memberships sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // split and segment sync after SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // fetches due to first fallback to polling fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DOWN_OCCUPANCY + settings.scheduler.featuresRefreshRate), 'fetch due to first fallback to polling'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // split and segment sync due to streaming up (OCCUPANCY event) fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); - // creating of second client during streaming: initial mysegment sync, reauth and syncAll due to new client - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); + // creating of second client during streaming: initial memberships sync, reauth and syncAll due to new client + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); fetchMock.get({ url: url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}&users=${encodeURIComponent(secondUserKey)}`), repeat: 3 /* initial + 2 STREAMING_RESET */ }, (url, opts) => { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('second auth success'); return { status: 200, body: authPushEnabledNicolasAndMarcio }; }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); // fetch due to SPLIT_UPDATE event fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { @@ -254,8 +254,8 @@ export function testFallback(fetchMock, assert) { // fetches due to second fallback to polling fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); // continue fetches due to second fallback to polling fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { @@ -263,27 +263,28 @@ export function testFallback(fetchMock, assert) { assert.true(nearlyEqual(lapse, MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to second fallback to polling'); return { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); // split and segment sync due to streaming up (CONTROL event) fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); // fetch due to MY_SEGMENTS_UPDATE event - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function () { + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_PUSH), 'sync due to MY_SEGMENTS_UPDATE event'); - return { status: 200, body: mySegmentsNicolasMock2 }; + return { status: 200, body: membershipsNicolasMock2 }; }); + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); // fetches due to third fallback to polling (STREAMING_PAUSED), two sync all (two STREAMING_RESET events) and fourth fallback (STREAMING_DISABLED) fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=1457552649999'), repeat: 4 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsMarcio }); + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 4 }, { status: 200, body: membershipsNicolasMock1 }); + fetchMock.get({ url: url(settings, '/memberships/marcio%40split.io'), repeat: 4 }, { status: 200, body: membershipsMarcio }); - // Periodic fetch due to polling (mySegments is not fetched due to smart pausing) + // Periodic fetch due to polling (memberships is not fetched due to smart pausing) fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to fourth fallback to polling'); diff --git a/src/__tests__/browserSuites/push-flag-sets.spec.js b/src/__tests__/browserSuites/push-flag-sets.spec.js index 40cba6ffc..df3d502f2 100644 --- a/src/__tests__/browserSuites/push-flag-sets.spec.js +++ b/src/__tests__/browserSuites/push-flag-sets.spec.js @@ -36,7 +36,7 @@ const MILLIS_FIFTH_SPLIT_UPDATE_EVENT = 500; export function testFlagSets(fetchMock, t) { fetchMock.reset(); - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); fetchMock.get(baseUrls.auth + '/v2/auth?s=1.2&users=nicolas%40split.io', function () { return { status: 200, body: authPushEnabled }; diff --git a/src/__tests__/browserSuites/push-initialization-nopush.spec.js b/src/__tests__/browserSuites/push-initialization-nopush.spec.js index 63d06ab2c..1df52e58b 100644 --- a/src/__tests__/browserSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/browserSuites/push-initialization-nopush.spec.js @@ -2,7 +2,7 @@ import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsNicolas from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolas from '../mocks/memberships.nicolas@split.io.json'; import authPushDisabled from '../mocks/auth.pushDisabled.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authInvalidCredentials from '../mocks/auth.invalidCredentials.txt'; @@ -38,14 +38,14 @@ const settings = settingsFactory(config); /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and auth (success but push disabled) - * 0.0 secs: syncAll if falling back to polling (/splitChanges, /mySegments/*) - * 0.1 secs: polling (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and auth (success but push disabled) + * 0.0 secs: syncAll if falling back to polling (/splitChanges, /memberships/*) + * 0.1 secs: polling (/splitChanges, /memberships/*) */ function testInitializationFail(fetchMock, assert, fallbackToPolling) { let start, splitio, client, ready = false; - fetchMock.get(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolas }); + fetchMock.get(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolas }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); diff --git a/src/__tests__/browserSuites/push-initialization-retries.spec.js b/src/__tests__/browserSuites/push-initialization-retries.spec.js index f2b4e501a..49dc6295e 100644 --- a/src/__tests__/browserSuites/push-initialization-retries.spec.js +++ b/src/__tests__/browserSuites/push-initialization-retries.spec.js @@ -3,7 +3,7 @@ import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; import authPushDisabled from '../mocks/auth.pushDisabled.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushBadToken from '../mocks/auth.pushBadToken.json'; -import mySegmentsNicolasMock from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolasMock from '../mocks/memberships.nicolas@split.io.json'; import { nearlyEqual, url } from '../testUtils'; @@ -40,12 +40,12 @@ const settings = settingsFactory(config); /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and first auth attempt (fail due to bad token) - * 0.0 secs: polling (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and first auth attempt (fail due to bad token) + * 0.0 secs: polling (/splitChanges, /memberships/*) * 0.1 secs: second push connect attempt (auth fail due to network error) - * 0.2 secs: polling (/splitChanges, /mySegments/*) + * 0.2 secs: polling (/splitChanges, /memberships/*) * 0.3 secs: third push connect attempt (auth success but push disabled) - * 0.4 secs: polling (/splitChanges, /mySegments/*) + * 0.4 secs: polling (/splitChanges, /memberships/*) */ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { @@ -64,7 +64,7 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { assert.true(nearlyEqual(lapse, expected), 'third auth attempt (approximately in 0.3 seconds from first attempt)'); return { status: 200, body: authPushDisabled }; }); - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock }); + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 4 }, { status: 200, body: membershipsNicolasMock }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; @@ -102,11 +102,11 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth successes and sse fails - * 0.0 secs: polling (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*), auth successes and sse fails + * 0.0 secs: polling (/splitChanges, /memberships/*) * 0.1 secs: second push connect attempt (auth successes and sse fails again) - * 0.2 secs: polling (/splitChanges, /mySegments/*) - * 0.3 secs: third push connect attempt (auth and sse success), syncAll (/splitChanges, /mySegments/*) + * 0.2 secs: polling (/splitChanges, /memberships/*) + * 0.3 secs: third push connect attempt (auth and sse success), syncAll (/splitChanges, /memberships/*) */ export function testPushRetriesDueToSseErrors(fetchMock, assert) { window.EventSource = EventSourceMock; @@ -135,7 +135,7 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { assert.pass('auth success'); return { status: 200, body: authPushEnabledNicolas }; }); - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 4 }, { status: 200, body: mySegmentsNicolasMock }); + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 4 }, { status: 200, body: membershipsNicolasMock }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { const lapse = Date.now() - start; @@ -176,7 +176,7 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { * Assert that if the main client is destroyed while authentication request is in progress and successes, the SDK doesn't open the SSE connection * * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and first auth attempt + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and first auth attempt * 0.05 secs: client destroyed * 0.1 secs: auth success but not SSE connection opened since push was closed * 0.2 secs: test finished @@ -191,7 +191,7 @@ export function testSdkDestroyWhileAuthSuccess(fetchMock, assert) { fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushEnabledNicolas }, { delay: 100 }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); setTimeout(() => { @@ -225,7 +225,7 @@ export function testSdkDestroyWhileConnDelay(fetchMock, assert) { }); fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: { ...authPushEnabledNicolas, connDelay: 0.1 } }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); const client = SplitFactory(config).client(); @@ -243,8 +243,8 @@ export function testSdkDestroyWhileConnDelay(fetchMock, assert) { * Asserts that if the client is destroyed while authentication request is in progress and fails, the SDK doesn't schedule an auth retry * * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and first auth attempt (fail due to bad token) - * 0.0 secs: polling (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and first auth attempt (fail due to bad token) + * 0.0 secs: polling (/splitChanges, /memberships/*) * 0.1 secs: second auth attempt request * 0.15 secs: client destroyed * 0.2 secs: second auth attempt response (fail due to network error) @@ -258,7 +258,7 @@ export function testSdkDestroyWhileAuthRetries(fetchMock, assert) { fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { status: 200, body: authPushBadToken }); fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), { throws: new TypeError('Network error') }, { delay: 100 }); - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 2 }, { status: 200, body: mySegmentsNicolasMock }); + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 2 }, { status: 200, body: membershipsNicolasMock }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); diff --git a/src/__tests__/browserSuites/push-refresh-token.spec.js b/src/__tests__/browserSuites/push-refresh-token.spec.js index 848b75d0b..8e22592c9 100644 --- a/src/__tests__/browserSuites/push-refresh-token.spec.js +++ b/src/__tests__/browserSuites/push-refresh-token.spec.js @@ -1,6 +1,6 @@ import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsNicolasMock1 from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolasMock1 from '../mocks/memberships.nicolas@split.io.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.601secs.json'; import authPushDisabled from '../mocks/auth.pushDisabled.json'; @@ -78,7 +78,7 @@ export function testRefreshToken(fetchMock, assert) { // initial sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // first auth fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { @@ -89,7 +89,7 @@ export function testRefreshToken(fetchMock, assert) { // sync after SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // re-auth due to refresh token, with connDelay of 0.5 seconds fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { @@ -105,7 +105,7 @@ export function testRefreshToken(fetchMock, assert) { assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'sync after SSE connection is reopened'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // second re-auth due to refresh token, this time responding with pushEnabled false fetchMock.getOnce(url(settings, `/v2/auth?s=1.2&users=${encodeURIComponent(userKey)}`), function (url, opts) { @@ -126,7 +126,7 @@ export function testRefreshToken(fetchMock, assert) { }, 200); // destroy the client a little bit latter, to assert that there weren't new requests return { status: 500, body: 'server error' }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/browserSuites/push-synchronization-retries.spec.js b/src/__tests__/browserSuites/push-synchronization-retries.spec.js index b0a0af372..7bb76a9df 100644 --- a/src/__tests__/browserSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/browserSuites/push-synchronization-retries.spec.js @@ -1,13 +1,13 @@ import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; import splitChangesMock3 from '../mocks/splitchanges.since.1457552620999.till.1457552649999.SPLIT_UPDATE.json'; -import mySegmentsNicolasMock1 from '../mocks/mysegments.nicolas@split.io.json'; -import mySegmentsNicolasMock2 from '../mocks/mysegments.nicolas@split.io.mock2.json'; -import mySegmentsMarcio from '../mocks/mysegments.marcio@split.io.json'; +import membershipsNicolasMock1 from '../mocks/memberships.nicolas@split.io.json'; +import membershipsNicolasMock2 from '../mocks/memberships.nicolas@split.io.mock2.json'; +import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; @@ -48,7 +48,7 @@ const MILLIS_RETRY_FOR_FIRST_SPLIT_UPDATE_EVENT = 300; const MILLIS_SECOND_SPLIT_UPDATE_EVENT = 400; -const MILLIS_MYSEGMENT_UPDATE_EVENT = 500; +const MILLIS_MYSEGMENTS_UPDATE_V3_EVENT = 500; const MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT = 1200; const MILLIS_SPLIT_KILL_EVENT = 1300; @@ -56,18 +56,18 @@ const MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT = 2000; /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*), auth, SSE connection + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) * * 0.2 secs: SPLIT_UPDATE event -> /splitChanges: bad response -> SDK_UPDATE triggered * 0.3 secs: SPLIT_UPDATE event -> /splitChanges retry: success * * 0.4 secs: SPLIT_UPDATE event with old changeNumber -> SDK_UPDATE not triggered * - * 0.5 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io: network error - * 0.6 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io retry: invalid JSON response - * 0.8 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io: server error - * 1.2 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io retry: success -> SDK_UPDATE triggered + * 0.5 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/marcio@split.io OK, /memberships/nicolas@split.io: network error + * 0.6 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io retry: invalid JSON response + * 0.8 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io: server error + * 1.2 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io retry: success -> SDK_UPDATE triggered * * 1.3 secs: SPLIT_KILL event -> /splitChanges: outdated response -> SDK_UPDATE triggered although fetches fail * 1.4 secs: SPLIT_KILL event -> /splitChanges retry: network error @@ -118,7 +118,7 @@ export function testSynchronizationRetries(fetchMock, assert) { assert.equal(client.getTreatment('splitters'), 'on', 'evaluation with updated MySegments list'); }); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MYSEGMENT_UPDATE_EVENT); // send a MY_SEGMENTS_UPDATE event with a new changeNumber after 0.4 seconds + }, MILLIS_MYSEGMENTS_UPDATE_V3_EVENT); // send a MY_SEGMENTS_UPDATE_V3 event with a new changeNumber after 0.4 seconds setTimeout(() => { client.once(client.Event.SDK_UPDATE, () => { @@ -141,10 +141,10 @@ export function testSynchronizationRetries(fetchMock, assert) { return { status: 200, body: authPushEnabledNicolas }; }); - // initial split and mySegments sync + // initial split and memberships sync fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); - fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 2 }, { status: 200, body: mySegmentsMarcio }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); + fetchMock.get({ url: url(settings, '/memberships/marcio%40split.io'), repeat: 3 }, { status: 200, body: membershipsMarcio }); // split and segment sync after SSE opened fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { @@ -152,7 +152,7 @@ export function testSynchronizationRetries(fetchMock, assert) { assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolasMock1 }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); // fetch due to SPLIT_UPDATE event fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); @@ -164,16 +164,16 @@ export function testSynchronizationRetries(fetchMock, assert) { }); // fetch due to first MY_SEGMENTS_UPDATE event - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { throws: new TypeError('Network error') }); // fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response // fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 500, body: 'server error' }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 500, body: 'server error' }); // second fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function () { + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'sync second retry for MY_SEGMENTS_UPDATE event'); - return { status: 200, body: mySegmentsNicolasMock2 }; + return { status: 200, body: membershipsNicolasMock2 }; }); // fetch due to SPLIT_KILL event diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index be7153a16..88c946006 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -2,29 +2,24 @@ import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; import splitChangesMock3 from '../mocks/splitchanges.since.1457552620999.till.1457552649999.SPLIT_UPDATE.json'; import splitChangesMock4 from '../mocks/splitchanges.since.1457552649999.till.1457552650000.SPLIT_KILL.json'; -import mySegmentsNicolasMock1 from '../mocks/mysegments.nicolas@split.io.json'; -import mySegmentsNicolasMock2 from '../mocks/mysegments.nicolas@split.io.mock2.json'; -import mySegmentsMarcio from '../mocks/mysegments.marcio@split.io.json'; +import membershipsNicolasMock2 from '../mocks/memberships.nicolas@split.io.mock2.json'; +import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; -import mySegmentsUpdateMessageNoPayload from '../mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json'; -import mySegmentsUpdateMessageWithPayload from '../mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552645000.json'; -import mySegmentsUpdateMessageWithEmptyPayload from '../mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552646000.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; -import unboundedMessage from '../mocks/message.V2.UNBOUNDED.1457552650000.json'; -import boundedZlibMessage from '../mocks/message.V2.BOUNDED.ZLIB.1457552651000.json'; -import keylistGzipMessage from '../mocks/message.V2.KEYLIST.GZIP.1457552652000.json'; -import segmentRemovalMessage from '../mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json'; -import unboundedMyLargeSegmentsMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json'; +import unboundedMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json'; +import boundedZlibMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json'; +import keylistGzipMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json'; +import segmentRemovalMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMyLargeSegmentsMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; import myLargeSegmentRemovalMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; import { nearlyEqual, url, hasNoCacheHeader } from '../testUtils'; -import includes from 'lodash/includes'; // Replace original EventSource with mock import EventSourceMock, { setMockListener } from '../testUtils/eventSourceMock'; @@ -51,53 +46,48 @@ const config = { }, urls: baseUrls, streamingEnabled: true, + debug: true }; const settings = settingsFactory(config); const MILLIS_SSE_OPEN = 100; const MILLIS_FIRST_SPLIT_UPDATE_EVENT = 200; const MILLIS_SECOND_SPLIT_UPDATE_EVENT = 300; -const MILLIS_MY_SEGMENTS_UPDATE_EVENT_NO_PAYLOAD = 400; -const MILLIS_SPLIT_KILL_EVENT = 500; -const MILLIS_NEW_CLIENT = 600; -const MILLIS_SECOND_SSE_OPEN = 700; -const MILLIS_MY_SEGMENTS_UPDATE_WITH_PAYLOAD = 800; -const MILLIS_MY_SEGMENTS_UPDATE_WITH_EMPTY_PAYLOAD = 900; -const MILLIS_MORE_CLIENTS = 1000; -const MILLIS_UNBOUNDED_FETCH = 1100; -const MILLIS_BOUNDED_FALLBACK = 1200; -const MILLIS_KEYLIST_FALLBACK = 1300; -const MILLIS_BOUNDED = 1400; -const MILLIS_KEYLIST = 1500; -const MILLIS_SEGMENT_REMOVAL = 1600; -const MILLIS_UNBOUNDED_FETCH_LS = 1700; -const MILLIS_SEGMENT_REMOVAL_LS = 2100; +const MILLIS_SPLIT_KILL_EVENT = 400; +const MILLIS_NEW_CLIENT = 500; +const MILLIS_SECOND_SSE_OPEN = 600; +const MILLIS_MORE_CLIENTS = 700; +const MILLIS_UNBOUNDED_FETCH = 800; +const MILLIS_BOUNDED_FALLBACK = 900; +const MILLIS_KEYLIST_FALLBACK = 1000; +const MILLIS_BOUNDED = 1100; +const MILLIS_KEYLIST = 1200; +const MILLIS_SEGMENT_REMOVAL = 1300; +const MILLIS_UNBOUNDED_FETCH_LS = 1400; +const MILLIS_SEGMENT_REMOVAL_LS = 1800; /** * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*), auth, SSE connection - * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*), auth, SSE connection + * 0.1 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) * 0.2 secs: SPLIT_UPDATE event -> /splitChanges * 0.3 secs: SPLIT_UPDATE event with old changeNumber - * 0.4 secs: MY_SEGMENTS_UPDATE event -> /mySegments/nicolas@split.io - * 0.5 secs: SPLIT_KILL event -> /splitChanges - * 0.6 secs: creates a new client -> new auth and SSE connection - * 0.7 secs: SSE connection opened -> syncAll (/splitChanges, /mySegments/*) - * 0.8 secs: MY_SEGMENTS_UPDATE event for new client (with payload). - * 0.9 secs: MY_SEGMENTS_UPDATE event for new client (with empty payload). - * 1.0 secs: creates more clients - * 1.1 secs: MY_SEGMENTS_UPDATE_V2 UnboundedFetchRequest event. - * 1.2 secs: MY_SEGMENTS_UPDATE_V2 BoundedFetchRequest event error --> UnboundedFetchRequest. - * 1.3 secs: MY_SEGMENTS_UPDATE_V2 KeyList event error --> UnboundedFetchRequest. - * 1.4 secs: MY_SEGMENTS_UPDATE_V2 BoundedFetchRequest event. - * 1.5 secs: MY_SEGMENTS_UPDATE_V2 KeyList event. - * 1.6 secs: MY_SEGMENTS_UPDATE_V2 SegmentRemoval event. - * 1.7 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) - * 1.941 secs: /mySegments/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SDK_UPDATE event - * 2.2 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 0.4 secs: SPLIT_KILL event -> /splitChanges + * 0.5 secs: creates a new client -> new auth and SSE connection + * 0.6 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) + * 0.7 secs: creates more clients + * 0.8 secs: MY_SEGMENTS_UPDATE_V3 UnboundedFetchRequest event. + * 0.9 secs: MY_SEGMENTS_UPDATE_V3 BoundedFetchRequest event error --> UnboundedFetchRequest. + * 1.0 secs: MY_SEGMENTS_UPDATE_V3 KeyList event error --> UnboundedFetchRequest. + * 1.1 secs: MY_SEGMENTS_UPDATE_V3 BoundedFetchRequest event. + * 1.2 secs: MY_SEGMENTS_UPDATE_V3 KeyList event. + * 1.3 secs: MY_SEGMENTS_UPDATE_V3 SegmentRemoval event. + * 1.4 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) + * 1.641 secs: /memberships/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SDK_UPDATE event + * 1.8 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { - assert.plan(44); + assert.plan(34); fetchMock.reset(); let start, splitio, client, otherClient, keylistAddClient, keylistRemoveClient, bitmapTrueClient, sharedClients = []; @@ -126,16 +116,6 @@ export function testSynchronization(fetchMock, assert) { eventSourceInstance.emitMessage(oldSplitUpdateMessage); }, MILLIS_SECOND_SPLIT_UPDATE_EVENT); // send a SPLIT_UPDATE event with an old changeNumber after 0.3 seconds - setTimeout(() => { - assert.equal(client.getTreatment('splitters'), 'off', 'evaluation with initial MySegments list'); - client.once(client.Event.SDK_UPDATE, () => { - const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_MY_SEGMENTS_UPDATE_EVENT_NO_PAYLOAD), 'SDK_UPDATE due to MY_SEGMENTS_UPDATE event'); - assert.equal(client.getTreatment('splitters'), 'on', 'evaluation with updated MySegments list'); - }); - eventSourceInstance.emitMessage(mySegmentsUpdateMessageNoPayload); - }, MILLIS_MY_SEGMENTS_UPDATE_EVENT_NO_PAYLOAD); // send a MY_SEGMENTS_UPDATE event with a new changeNumber after 0.4 seconds - setTimeout(() => { assert.equal(client.getTreatment('whitelist'), 'allowed', 'evaluation with not killed Split'); const onUpdateCb = () => { @@ -161,41 +141,6 @@ export function testSynchronization(fetchMock, assert) { eventSourceInstance.emitOpen(); }, MILLIS_SECOND_SSE_OPEN - MILLIS_NEW_CLIENT); // open new SSE connection - setTimeout(() => { - assert.equal(otherClient.getTreatment('qc_team'), 'no', 'evaluation with initial MySegments list (shared client)'); - otherClient.once(otherClient.Event.SDK_UPDATE, () => { - const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_MY_SEGMENTS_UPDATE_WITH_PAYLOAD), 'SDK_UPDATE due to MY_SEGMENTS_UPDATE event (with payload)'); - assert.equal(otherClient.getTreatment('qc_team'), 'yes', 'evaluation with updated MySegments list (shared client)'); - }); - eventSourceInstance.emitMessage(mySegmentsUpdateMessageWithPayload); - }, MILLIS_MY_SEGMENTS_UPDATE_WITH_PAYLOAD - MILLIS_NEW_CLIENT); // send a MY_SEGMENTS_UPDATE event with payload after 0.1 seconds from new SSE connection opened - - setTimeout(() => { - assert.equal(otherClient.getTreatment('qc_team'), 'yes', 'evaluation with updated MySegments list (shared client)'); - otherClient.once(otherClient.Event.SDK_UPDATE, () => { - const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_MY_SEGMENTS_UPDATE_WITH_EMPTY_PAYLOAD), 'SDK_UPDATE due to MY_SEGMENTS_UPDATE event (with empty payload)'); - assert.equal(otherClient.getTreatment('qc_team'), 'no', 'evaluation with re-updated MySegments list (shared client)'); - }); - - // assert that user error on callback is an Uncaught Exception - otherClient.once(otherClient.Event.SDK_UPDATE, () => { - const previousErrorHandler = window.onerror; - const exceptionHandler = err => { - if (includes(err, 'willThrowFor')) { - assert.pass(`User error on SDK_UPDATE callback should throw as Uncaught Exception: ${err}`); - } else { - assert.fail(err); - } - window.onerror = previousErrorHandler; - }; - window.onerror = exceptionHandler; - null.willThrowForUpdate(); - }); - eventSourceInstance.emitMessage(mySegmentsUpdateMessageWithEmptyPayload); - }, MILLIS_MY_SEGMENTS_UPDATE_WITH_EMPTY_PAYLOAD - MILLIS_NEW_CLIENT); // send a MY_SEGMENTS_UPDATE event with payload after 0.1 seconds from new SSE connection opened - setTimeout(() => { keylistAddClient = splitio.client(keylistAddKey); keylistRemoveClient = splitio.client(keylistRemoveKey); @@ -255,7 +200,7 @@ export function testSynchronization(fetchMock, assert) { const EXPECTED_DELAY = 241; client.once(client.Event.SDK_UPDATE, () => { - assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching mySegments with a delay'); + assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching memberships with a delay'); assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation after myLargeSegment fetch'); }); @@ -273,7 +218,7 @@ export function testSynchronization(fetchMock, assert) { Promise.all(sharedClients.map(c => c.destroy())) .then(() => { assert.equal(otherClient.getTreatment('whitelist'), 'control', 'evaluation returns control for shared client if it is destroyed'); - assert.equal(client.getTreatment('whitelist'), 'not_allowed', 'evaluation returns correct tratment for main client'); + assert.equal(client.getTreatment('whitelist'), 'not_allowed', 'evaluation returns correct treatment for main client'); assert.equal(eventSourceInstance.readyState, EventSourceMock.OPEN, 'streaming is still open'); client.destroy().then(() => { @@ -322,9 +267,9 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function (url, opts) { + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsNicolasMock1 }; + return { status: 200, body: membershipsNicolasMock2 }; }); // sync all after SSE opened @@ -334,9 +279,9 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function (url, opts) { + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsNicolasMock1 }; + return { status: 200, body: membershipsNicolasMock2 }; }); // fetch due to SPLIT_UPDATE event @@ -345,12 +290,6 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: splitChangesMock3 }; }); - // fetch due to first MY_SEGMENTS_UPDATE event - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function (url, opts) { - if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); - return { status: 200, body: mySegmentsNicolasMock2 }; - }); - // fetch due to SPLIT_KILL event fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); @@ -358,10 +297,10 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: splitChangesMock4 }; }); - // initial fetch of mySegments for new client - fetchMock.getOnce(url(settings, '/mySegments/marcio%40split.io'), function (url, opts) { + // initial fetch of memberships for new client + fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsMarcio }; + return { status: 200, body: membershipsMarcio }; }); // sync all after second SSE opened @@ -371,34 +310,34 @@ export function testSynchronization(fetchMock, assert) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }; }); - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 2 }, function (url, opts) { + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 2 }, function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsNicolasMock2 }; + return { status: 200, body: membershipsNicolasMock2 }; }); - fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 2 }, function (url, opts) { + fetchMock.get({ url: url(settings, '/memberships/marcio%40split.io'), repeat: 2 }, function (url, opts) { if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsMarcio }; + return { status: 200, body: membershipsMarcio }; }); - // 3 unbounded fetch for MY_SEGMENTS_UPDATE_V2 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE - fetchMock.get({ url: url(settings, '/mySegments/nicolas%40split.io'), repeat: 3 }, function (url, opts) { + // 3 unbounded fetch for MY_SEGMENTS_UPDATE_V3 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 3 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsNicolasMock2 }; + return { status: 200, body: membershipsNicolasMock2 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: { ...mySegmentsNicolasMock2, myLargeSegments: ['employees', 'splitters'] } }); - fetchMock.get({ url: url(settings, '/mySegments/marcio%40split.io'), repeat: 4 }, function (url, opts) { + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: { ...membershipsNicolasMock2, ls: { k: [{ n: 'employees' }, { n: 'splitters' }] } } }); + fetchMock.get({ url: url(settings, '/memberships/marcio%40split.io'), repeat: 4 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: mySegmentsMarcio }; + return { status: 200, body: membershipsMarcio }; }); - // initial fetch of mySegments for other clients + sync all after third SSE opened + 3 unbounded fetch for MY_SEGMENTS_UPDATE_V2 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE + // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MY_SEGMENTS_UPDATE_V3 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); - fetchMock.get({ url: url(settings, '/mySegments/key1'), repeat: 6 }, { status: 200, body: { mySegments: [] } }); - fetchMock.get({ url: url(settings, '/mySegments/key3'), repeat: 6 }, { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); - fetchMock.get({ url: url(settings, `/mySegments/${bitmapTrueKey}`), repeat: 5 }, { status: 200, body: { mySegments: [] } }); + fetchMock.get({ url: url(settings, '/memberships/key1'), repeat: 6 }, { status: 200, body: { ms: {} } }); + fetchMock.get({ url: url(settings, '/memberships/key3'), repeat: 6 }, { status: 200, body: { ms: { k: [{ n: 'splitters' }] } } }); + fetchMock.get({ url: url(settings, `/memberships/${bitmapTrueKey}`), repeat: 5 }, { status: 200, body: { ms: { k: [] } } }); // bounded fetch request - fetchMock.get(url(settings, `/mySegments/${bitmapTrueKey}`), { status: 200, body: { mySegments: [{ name: 'splitters' }] } }); + fetchMock.get(url(settings, `/memberships/${bitmapTrueKey}`), { status: 200, body: { ms: { k: [{ n: 'splitters' }] } } }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 8f0c6ef8e..9ed15d8a0 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -2,9 +2,9 @@ import { SplitFactory } from '../../'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsNicolas from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolas from '../mocks/memberships.nicolas@split.io.json'; -// mocks for mySegments readiness tests +// mocks for memberships readiness tests import splitChangesStartWithoutSegmentsMock from '../mocks/splitchanges.real.json'; import splitChangesUpdateWithSegmentsMock from '../mocks/splitchanges.real.updateWithSegments.json'; import splitChangesUpdateWithoutSegmentsMock from '../mocks/splitchanges.real.updateWithoutSegments.json'; @@ -41,8 +41,8 @@ export default function (fetchMock, assert) { fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise((res) => { setTimeout(() => { res({ status: 200, body: membershipsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); @@ -62,7 +62,7 @@ export default function (fetchMock, assert) { }); }); - assert.test(t => { // Timeout test, we have retries but mySegments takes too long + assert.test(t => { // Timeout test, we have retries but memberships takes too long const testUrls = { sdk: 'https://sdk.baseurl/readinessSuite2', events: 'https://events.baseurl/readinessSuite2' @@ -70,8 +70,8 @@ export default function (fetchMock, assert) { fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise((res) => { setTimeout(() => { res({ status: 200, body: membershipsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 + 50); }); }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); @@ -101,8 +101,8 @@ export default function (fetchMock, assert) { fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { return new Promise((res) => { setTimeout(() => { res({ status: 200, body: splitChangesMock1, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); // Faster, it should get ready on the retry. }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise((res) => { setTimeout(() => { res({ status: 200, body: mySegmentsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise((res) => { setTimeout(() => { res({ status: 200, body: membershipsNicolas, headers: {} }); }, requestTimeoutBeforeReady * 1000 - 50); }); }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); @@ -119,15 +119,15 @@ export default function (fetchMock, assert) { }); }); - /************** Now we will validate the intelligent mySegments pausing, which requires lots of code. Related code below. **************/ + /************** Now we will validate the intelligent memberships pausing, which requires lots of code. Related code below. **************/ localStorage.clear(); - const mySegmentsEndpointDelay = 450; + const membershipsEndpointDelay = 450; function mockForSegmentsPauseTest(testUrls, startWithSegments = false) { - let mySegmentsHits = 0; + let membershipsHits = 0; - fetchMock.get(new RegExp(`${testUrls.sdk}/mySegments/nicolas\\d?%40split.io`), function () { // Mock any mySegments call, so we can test with multiple clients. - mySegmentsHits++; - return new Promise((res) => { setTimeout(() => { res({ status: 200, body: { mySegments: [] } }); }, mySegmentsEndpointDelay); }); + fetchMock.get(new RegExp(`${testUrls.sdk}/memberships/nicolas\\d?%40split.io`), function () { // Mock any memberships call, so we can test with multiple clients. + membershipsHits++; + return new Promise((res) => { setTimeout(() => { res({ status: 200, body: { ms: {} } }); }, membershipsEndpointDelay); }); }); // Now mock the no more updates state fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }); @@ -144,15 +144,15 @@ export default function (fetchMock, assert) { fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552649999', { status: 200, body: splitChangesUpdateWithoutSegmentsMock }); } - return () => mySegmentsHits; + return () => membershipsHits; } assert.test(t => { // Testing how the SDK pauses/resumes segments synchronization. const testUrls = { - sdk: 'https://sdk.baseurl/readinessMySegmentsSuite', - events: 'https://events.baseurl/readinessMySegmentsSuite' + sdk: 'https://sdk.baseurl/readinessMembershipsSuite', + events: 'https://events.baseurl/readinessMembershipsSuite' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); const start = Date.now(); const splitio = SplitFactory({ @@ -174,39 +174,39 @@ export default function (fetchMock, assert) { let readyCount = 0; client2.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; }); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'It should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'It should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; // create a client on a different event-loop tick than client and client2. client3 = splitio.client('nicolas3@split.io'); client3.once(client3.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; }); setTimeout(() => { - t.equal(getMySegmentsHits(), 1 * CLIENTS_COUNT - 1, 'mySegments should had been hit once per client on the first attempt (excluding client3), but it stopped syncing afterwards.'); + t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT - 1, 'memberships should had been hit once per client on the first attempt (excluding client3), but it stopped syncing afterwards.'); }, 2500); // Now we will wait until it picks up Splits, using the SDK_UPDATE event. Features are refreshed every 3s, but segments every 1s. client.once(client.Event.SDK_UPDATE, () => { - // This update came with segments, it should have tried to fetch mySegments for all used keys. + // This update came with segments, it should have tried to fetch memberships for all used keys. setTimeout(() => { - t.equal(getMySegmentsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize mySegments as soon as it received a new Split with segments.'); + t.equal(getMembershipsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships as soon as it received a new Split with segments.'); }, 0); setTimeout(() => { // Nasty ugly crap to avoid listening to the update coming from mySegment calls. client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with no segments (removed the matcher we fetched on the previous one), it should stop the producer and not trigger more requests. - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize mySegments periodically.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships periodically.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); Promise.all([ @@ -229,10 +229,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing how the SDK pauses/resumes segments synchronization in localstorage from scratch (no SDK_READY_FROM_CACHE). const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite', - events: 'https://events.baseurl/readinessLSMySegmentsSuite' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite', + events: 'https://events.baseurl/readinessLSMembershipsSuite' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); const start = Date.now(); const splitio = SplitFactory({ @@ -258,39 +258,39 @@ export default function (fetchMock, assert) { let readyCount = 0; client2.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; }); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'It should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'It should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; // create a client on a different event-loop tick than client and client2. client3 = splitio.client('nicolas3@split.io'); client3.once(client3.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for mySegments, as there were no segments in the first splits payload.'); + t.ok(Date.now() - start < 50, 'Shared client should be ready really quickly, without waiting for memberships, as there were no segments in the first splits payload.'); readyCount++; }); setTimeout(() => { - t.equal(getMySegmentsHits(), 1 * CLIENTS_COUNT -1, 'mySegments should had been hit once per client on the first attempt (excluding client3), but it stopped syncing afterwards.'); + t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT -1, 'memberships should had been hit once per client on the first attempt (excluding client3), but it stopped syncing afterwards.'); }, 2500); // Now we will wait until it picks up Splits, using the SDK_UPDATE event. Features are refreshed every 3s, but segments every 1s. client.once(client.Event.SDK_UPDATE, () => { - // This update came with segments, it should have tried to fetch mySegments for all used keys. + // This update came with segments, it should have tried to fetch memberships for all used keys. setTimeout(() => { - t.equal(getMySegmentsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize mySegments as soon as it received a new Split with segments.'); + t.equal(getMembershipsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships as soon as it received a new Split with segments.'); }, 0); setTimeout(() => { // Nasty ugly crap to avoid listening to the update coming from mySegment calls. client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with no segments (removed the matcher we fetched on the previous one), it should stop the producer and not trigger more requests. - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize mySegments periodically.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships periodically.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); Promise.all([ @@ -313,10 +313,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing how the SDK pauses/resumes segments synchronization. const testUrls = { - sdk: 'https://sdk.baseurl/readinessMySegmentsSuite2', - events: 'https://events.baseurl/readinessMySegmentsSuite2' + sdk: 'https://sdk.baseurl/readinessMembershipsSuite2', + events: 'https://events.baseurl/readinessMembershipsSuite2' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, true); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, true); const start = Date.now(); const splitio = SplitFactory({ @@ -338,39 +338,39 @@ export default function (fetchMock, assert) { let readyCount = 0; client2.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'Shared client should not be ready without waiting for mySegments, as there are segments in the first splits payload.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'Shared client should not be ready without waiting for memberships, as there are segments in the first splits payload.'); readyCount++; }); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'It should not be ready without waiting for mySegments, as there are segments in the first splits payload.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, as there are segments in the first splits payload.'); readyCount++; // create a client on a different event-loop tick than client and client2. client3 = splitio.client('nicolas3@split.io'); client3.once(client3.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'Shared client should not be ready without waiting for mySegments, as there are segments in the first splits payload.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'Shared client should not be ready without waiting for memberships, as there are segments in the first splits payload.'); readyCount++; }); setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT - 1, 'mySegments should had been hit once per client on the first attempt (excluding one for client3) and keep syncing afterwards.'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT - 1, 'memberships should had been hit once per client on the first attempt (excluding one for client3) and keep syncing afterwards.'); }, 2500); // Now we will wait until it picks up splits, using the SDK_UPDATE event. Features are refreshed every 3s, but segments every 1s (plus sync time). client.once(client.Event.SDK_UPDATE, () => { // This update came without segments, it should not trigger an extra fetch. setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT - 1, 'It should have stopped synchronizing mySegments since it transitioned to no segments state.'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT - 1, 'It should have stopped synchronizing memberships since it transitioned to no segments state.'); }, 0); setTimeout(() => { client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with segments again, it should trigger a request ASAP and restart the producer. - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize mySegments periodically.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships periodically.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 6 * CLIENTS_COUNT - 1, 'It should keep the producer synchronizing periodically..'); + t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT - 1, 'It should keep the producer synchronizing periodically..'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); Promise.all([ @@ -393,10 +393,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from scratch const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite2', - events: 'https://events.baseurl/readinessLSMySegmentsSuite2' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite2', + events: 'https://events.baseurl/readinessLSMembershipsSuite2' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, true); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, true); const start = Date.now(); const splitio = SplitFactory({ @@ -421,26 +421,26 @@ export default function (fetchMock, assert) { const client3 = splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'It should not be ready without waiting for mySegments, as there are segments in the first splits payload.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, as there are segments in the first splits payload.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt and keep syncing afterwards.'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and keep syncing afterwards.'); }, 2500); // Now we will wait until it picks up splits, using the SDK_UPDATE event. Features are refreshed every 3s, but segments every 1s (plus sync time). client.once(client.Event.SDK_UPDATE, () => { // This update came without segments, it should not trigger an extra fetch. setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT, 'It should have stopped synchronizing mySegments since it transitioned to no segments state.'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'It should have stopped synchronizing memberships since it transitioned to no segments state.'); }, 0); setTimeout(() => { client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with segments again, it should trigger a request ASAP and restart the producer. - t.equal(getMySegmentsHits(), 4 * CLIENTS_COUNT, 'It should have tried to synchronize mySegments periodically.'); + t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT, 'It should have tried to synchronize memberships periodically.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 6 * CLIENTS_COUNT, 'It should keep the producer synchronizing periodically..'); + t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT, 'It should keep the producer synchronizing periodically..'); Promise.all([ client2.destroy(), @@ -462,10 +462,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from scratch with segments being previously used const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite3', - events: 'https://events.baseurl/readinessLSMySegmentsSuite3' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite3', + events: 'https://events.baseurl/readinessLSMembershipsSuite3' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, true); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, true); const start = Date.now(); const splitio = SplitFactory({ @@ -490,10 +490,10 @@ export default function (fetchMock, assert) { const client3 = splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'It should not be ready without waiting for mySegments, when we start from cache it might be stale.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt and keep syncing afterwards.'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and keep syncing afterwards.'); Promise.all([ client2.destroy(), client3.destroy(), @@ -509,10 +509,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from cache without segments being previously used, and first update has no segments. const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite4', - events: 'https://events.baseurl/readinessLSMySegmentsSuite4' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite4', + events: 'https://events.baseurl/readinessLSMembershipsSuite4' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); const start = Date.now(); const splitio = SplitFactory({ @@ -540,7 +540,7 @@ export default function (fetchMock, assert) { t.ok(Date.now() - start < 50, 'It should be ready quickly, since it had no segments and update has no segments either.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 1 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt but stopped syncing afterwards'); + t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); Promise.all([ client2.destroy(), client3.destroy(), @@ -556,12 +556,12 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from cache without segments being previously used, and first update HAS segments. const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite5', - events: 'https://events.baseurl/readinessLSMySegmentsSuite5' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite5', + events: 'https://events.baseurl/readinessLSMembershipsSuite5' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); - // I'm having the first update of Splits come with segments. In this scenario it'll wait for mySegments to download before being ready. + // I'm having the first update of Splits come with segments. In this scenario it'll wait for memberships to download before being ready. fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithSegmentsMock, since: 1457552669999, till: 1457552679999 } }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); @@ -589,9 +589,9 @@ export default function (fetchMock, assert) { client.once(client.Event.SDK_READY, () => { const delay = Date.now() - start; - t.ok(delay >= mySegmentsEndpointDelay, 'It should not be ready without waiting for mySegments, when we start from cache it might be stale.'); + t.ok(delay >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt but stopped syncing afterwards'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); Promise.all([ client2.destroy(), client3.destroy(), @@ -607,10 +607,10 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from cache with segments being previously used, and update is empty. const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite6', - events: 'https://events.baseurl/readinessLSMySegmentsSuite6' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite6', + events: 'https://events.baseurl/readinessLSMembershipsSuite6' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); const start = Date.now(); const splitio = SplitFactory({ @@ -635,10 +635,10 @@ export default function (fetchMock, assert) { const client3 = splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start >= mySegmentsEndpointDelay, 'It should not be ready without waiting for mySegments, when we start from cache it might be stale and we had segments even though the update has nothing.'); + t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale and we had segments even though the update has nothing.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 3 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt and kept syncing afterwards'); + t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and kept syncing afterwards'); Promise.all([ client2.destroy(), client3.destroy(), @@ -654,11 +654,11 @@ export default function (fetchMock, assert) { assert.test(t => { // Testing when we start from cache with segments being previously used and first update removes segments const testUrls = { - sdk: 'https://sdk.baseurl/readinessLSMySegmentsSuite7', - events: 'https://events.baseurl/readinessLSMySegmentsSuite7' + sdk: 'https://sdk.baseurl/readinessLSMembershipsSuite7', + events: 'https://events.baseurl/readinessLSMembershipsSuite7' }; - const getMySegmentsHits = mockForSegmentsPauseTest(testUrls, false); - // I'm having the first update of Splits come without segments. In this scenario it'll NOT wait for mySegments to download before being ready. + const getMembershipsHits = mockForSegmentsPauseTest(testUrls, false); + // I'm having the first update of Splits come without segments. In this scenario it'll NOT wait for memberships to download before being ready. fetchMock.get({ url: testUrls.sdk + '/splitChanges?s=1.2&since=1457552669999', overwriteRoutes: true }, { status: 200, body: { ...splitChangesUpdateWithoutSegmentsMock, since: 1457552669999, till: 1457552679999 } }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552679999', { status: 200, body: { splits: [], since: 1457552679999, till: 1457552679999 } }); @@ -685,10 +685,10 @@ export default function (fetchMock, assert) { const client3 = splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { - t.ok(Date.now() - start < 50, 'It should be ready without waiting for mySegments, since when it downloads changes it will have no more use for them.'); + t.ok(Date.now() - start < 50, 'It should be ready without waiting for memberships, since when it downloads changes it will have no more use for them.'); setTimeout(() => { - t.equal(getMySegmentsHits(), 1 * CLIENTS_COUNT, 'mySegments should had been hit once per client on the first attempt and stopped syncing afterwards'); + t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and stopped syncing afterwards'); Promise.all([ client2.destroy(), client3.destroy(), diff --git a/src/__tests__/browserSuites/ready-from-cache.spec.js b/src/__tests__/browserSuites/ready-from-cache.spec.js index 16adc2d3e..b0ffd6706 100644 --- a/src/__tests__/browserSuites/ready-from-cache.spec.js +++ b/src/__tests__/browserSuites/ready-from-cache.spec.js @@ -3,7 +3,7 @@ import { SplitFactory } from '../../'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsNicolas from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolas from '../mocks/memberships.nicolas@split.io.json'; import { nearlyEqual } from '../testUtils'; @@ -98,9 +98,9 @@ export default function (fetchMock, assert) { fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: mySegmentsNicolas }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas2%40split.io', { status: 200, body: { 'mySegments': [] } }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas3%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: membershipsNicolas }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas2%40split.io', { status: 200, body: { 'ms': {} } }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas3%40split.io', { status: 200, body: { 'ms': {} } }); const splitio = SplitFactory({ ...baseConfig, @@ -151,14 +151,14 @@ export default function (fetchMock, assert) { return new Promise(res => { setTimeout(() => res({ status: 200, body: { ...splitChangesMock1, since: 25 }, headers: {} }), 200); }); // 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that. }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: membershipsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas2%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 700); }); // Second client gets segments after 700ms + fetchMock.get(testUrls.sdk + '/memberships/nicolas2%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 700); }); // Second client gets segments after 700ms }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas3%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 1000); }); // Third client mySegments will come after 1s + fetchMock.get(testUrls.sdk + '/memberships/nicolas3%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 1000); }); // Third client memberships will come after 1s }); fetchMock.postOnce(testUrls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(testUrls.events + '/testImpressions/count', 200); @@ -231,7 +231,7 @@ export default function (fetchMock, assert) { Promise.all([client3.destroy(), client2.destroy(), client.destroy()]).then(() => { t.equal(localStorage.getItem('some_user_item'), 'user_item', 'user items at localStorage must not be changed'); t.equal(localStorage.getItem('readyFromCache_2.SPLITIO.splits.till'), '1457552620999', 'splits.till must correspond to the till of the last successfully fetched Splits'); - t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_2.SPLITIO.splits.lastUpdated')), Date.now() - 800 /* 800 ms between last Split and MySegments fetch */), 'lastUpdated is added and must correspond to the timestamp of the last successfully fetched Splits'); + t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_2.SPLITIO.splits.lastUpdated')), Date.now() - 800 /* 800 ms between last splitChanges and memberships fetch */), 'lastUpdated is added and must correspond to the timestamp of the last successfully fetched Splits'); }); }); t.true(Date.now() - startTime >= 1000, 'It should emit SDK_READY too but after syncing with the cloud.'); @@ -239,11 +239,11 @@ export default function (fetchMock, assert) { }); client3.on(client3.Event.SDK_READY_TIMED_OUT, () => { client3.ready().catch(() => { - t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.'); }); - t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.'); }); }); @@ -260,16 +260,16 @@ export default function (fetchMock, assert) { return new Promise(res => { setTimeout(() => res({ status: 200, body: { ...splitChangesMock1, since: 25 }, headers: {} }), 200); }); // 400ms is how long it'll take to reply with Splits, no SDK_READY should be emitted before that. }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: membershipsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas2%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 700); }); // Second client gets segments after 700ms + fetchMock.get(testUrls.sdk + '/memberships/nicolas2%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 700); }); // Second client gets segments after 700ms }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas3%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 1000); }); // Third client mySegments will come after 1s + fetchMock.get(testUrls.sdk + '/memberships/nicolas3%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 1000); }); // Third client memberships will come after 1s }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas4%40split.io', { 'mySegments': [] }); + fetchMock.get(testUrls.sdk + '/memberships/nicolas4%40split.io', { 'ms': {} }); fetchMock.postOnce(testUrls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(testUrls.events + '/testImpressions/count', 200); @@ -349,7 +349,7 @@ export default function (fetchMock, assert) { Promise.all([client3.destroy(), client2.destroy(), client.destroy()]).then(() => { t.equal(localStorage.getItem('some_user_item'), 'user_item', 'user items at localStorage must not be changed'); t.equal(localStorage.getItem('readyFromCache_3.SPLITIO.splits.till'), '1457552620999', 'splits.till must correspond to the till of the last successfully fetched Splits'); - t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_3.SPLITIO.splits.lastUpdated')), Date.now() - 800 /* 800 ms between last Split and MySegments fetch */), 'lastUpdated must correspond to the timestamp of the last successfully fetched Splits'); + t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_3.SPLITIO.splits.lastUpdated')), Date.now() - 800 /* 800 ms between last Split and memberships fetch */), 'lastUpdated must correspond to the timestamp of the last successfully fetched Splits'); }); }); t.true(Date.now() - startTime >= 1000, 'It should emit SDK_READY too but after syncing with the cloud.'); @@ -357,11 +357,11 @@ export default function (fetchMock, assert) { }); client3.on(client3.Event.SDK_READY_TIMED_OUT, () => { client3.ready().catch(() => { - t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.'); }); - t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'on', 'It should evaluate treatments with memberships data from cache.'); }); }); @@ -379,14 +379,14 @@ export default function (fetchMock, assert) { return { status: 200, body: splitChangesMock1 }; }); fetchMock.get(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: mySegmentsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) + fetchMock.get(testUrls.sdk + '/memberships/nicolas%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: membershipsNicolas, headers: {} }), 400); }); // First client gets segments before splits. No segment cache loading (yet) }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas2%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 700); }); // Second client gets segments after 700ms + fetchMock.get(testUrls.sdk + '/memberships/nicolas2%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 700); }); // Second client gets segments after 700ms }); - fetchMock.get(testUrls.sdk + '/mySegments/nicolas3%40split.io', function () { - return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'mySegments': [] }, headers: {} }), 1000); }); // Third client mySegments will come after 1s + fetchMock.get(testUrls.sdk + '/memberships/nicolas3%40split.io', function () { + return new Promise(res => { setTimeout(() => res({ status: 200, body: { 'ms': {} }, headers: {} }), 1000); }); // Third client memberships will come after 1s }); fetchMock.postOnce(testUrls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(testUrls.events + '/testImpressions/count', 200); @@ -460,7 +460,7 @@ export default function (fetchMock, assert) { Promise.all([client3.destroy(), client2.destroy(), client.destroy()]).then(() => { t.equal(localStorage.getItem('some_user_item'), 'user_item', 'user items at localStorage must not be changed'); t.equal(localStorage.getItem('readyFromCache_4.SPLITIO.splits.till'), '1457552620999', 'splits.till must correspond to the till of the last successfully fetched Splits'); - t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_4.SPLITIO.splits.lastUpdated')), Date.now() - 1000 /* 1000 ms between last Split and MySegments fetch */), 'lastUpdated must correspond to the timestamp of the last successfully fetched Splits'); + t.true(nearlyEqual(parseInt(localStorage.getItem('readyFromCache_4.SPLITIO.splits.lastUpdated')), Date.now() - 1000 /* 1000 ms between last Split and memberships fetch */), 'lastUpdated must correspond to the timestamp of the last successfully fetched Splits'); t.end(); }); @@ -470,11 +470,11 @@ export default function (fetchMock, assert) { }); client3.on(client3.Event.SDK_READY_TIMED_OUT, () => { client3.ready().catch(() => { - t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'control', 'It should not evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should reject ready promise before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'control', 'It should not evaluate treatments with memberships data from cache.'); }); - t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing mySegments data with the cloud.'); - t.equal(client3.getTreatment('always_on'), 'control', 'It should evaluate treatments with mySegments data from cache.'); + t.true(Date.now() - startTime >= 850, 'It should emit SDK_READY_TIMED_OUT before syncing memberships data with the cloud.'); + t.equal(client3.getTreatment('always_on'), 'control', 'It should evaluate treatments with memberships data from cache.'); }); }); @@ -489,7 +489,7 @@ export default function (fetchMock, assert) { t.plan(7); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_5.SPLITIO.splits.till', 25); @@ -541,7 +541,7 @@ export default function (fetchMock, assert) { t.plan(5); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=p1__split,p2__split', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); const splitio = SplitFactory({ ...baseConfig, @@ -585,7 +585,7 @@ export default function (fetchMock, assert) { t.plan(7); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=25&names=p2__split&prefixes=p1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: 25, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&names=p2__split&prefixes=p1' }, flagSpecVersion: '1.2' } }); localStorage.setItem('some_user_item', 'user_item'); @@ -636,7 +636,7 @@ export default function (fetchMock, assert) { t.plan(6); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&prefixes=p1,p2', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); const expectedHash = getStorageHash({ ...baseConfig, sync: { __splitFiltersValidation: { queryString: '&prefixes=p1,p2' }, flagSpecVersion: '1.2' } }); localStorage.setItem('some_user_item', 'user_item'); @@ -702,7 +702,7 @@ export default function (fetchMock, assert) { t.plan(7); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: { splits: [splitDeclarations.p1__split, splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_8.SPLITIO.splits.till', 25); @@ -756,7 +756,7 @@ export default function (fetchMock, assert) { t.plan(6); fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1&names=no%20exist%20trim,no_exist,p3__split&prefixes=no%20exist%20trim,p2', { status: 200, body: { splits: [splitDeclarations.p2__split, splitDeclarations.p3__split], since: -1, till: 1457552620999 } }, { delay: 10 }); // short delay to let emit SDK_READY_FROM_CACHE - fetchMock.getOnce(testUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { mySegments: [] } }); + fetchMock.getOnce(testUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { ms: {} } }); localStorage.setItem('some_user_item', 'user_item'); localStorage.setItem('readyFromCache_9.SPLITIO.splits.till', 25); diff --git a/src/__tests__/browserSuites/ready-promise.spec.js b/src/__tests__/browserSuites/ready-promise.spec.js index 6d54d1432..ebcd5843c 100644 --- a/src/__tests__/browserSuites/ready-promise.spec.js +++ b/src/__tests__/browserSuites/ready-promise.spec.js @@ -13,7 +13,7 @@ const consoleSpy = { import { SplitFactory } from '../../'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; const baseConfig = { core: { @@ -61,7 +61,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both attempts fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -109,7 +109,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -159,7 +159,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -230,12 +230,12 @@ export default function readyPromiseAssertions(fetchMock, assert) { fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); // main client endpoint configured to fetch segments before request timeout - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=1457552620999', { splits: [], since: 1457552620999, till: 1457552620999 }); // shared client endpoint configured to fetch segments immediately, in order to emit SDK_READY as soon as splits arrives - fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo); + fetchMock.get(config.urls.sdk + '/memberships/nicolas%40split.io', membershipsFacundo); // shared client endpoint configured to emit SDK_READY_TIMED_OUT - fetchMock.get(config.urls.sdk + '/mySegments/emiliano%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.readyTimeout) + 20 }); + fetchMock.get(config.urls.sdk + '/memberships/emiliano%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.readyTimeout) + 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -264,7 +264,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { const timeoutClient = splitio.client('emiliano@split.io'); timeoutClient.ready().then(undefined, () => { // setting onRejected handler via `then` method - t.pass('### Shared client TIMED OUT - promise rejected since mySegments fetch took more time than readyTimeout'); + t.pass('### Shared client TIMED OUT - promise rejected since memberships fetch took more time than readyTimeout'); timeoutClient.ready().catch(() => { // setting onRejected handler via `catch` method t.pass('### Shared client TIMED OUT - promise keeps being rejected'); timeoutClient.on(timeoutClient.Event.SDK_READY, () => { @@ -311,7 +311,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -359,9 +359,9 @@ export default function readyPromiseAssertions(fetchMock, assert) { } }; - // Both /splitChanges and /mySegments take less than 'requestTimeoutBeforeReady' + // Both /splitChanges and /memberships take less than 'requestTimeoutBeforeReady' fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -409,7 +409,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -498,9 +498,9 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo); - fetchMock.get(config.urls.sdk + '/mySegments/emiliano%40split.io', mySegmentsFacundo); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/nicolas%40split.io', membershipsFacundo); + fetchMock.get(config.urls.sdk + '/memberships/emiliano%40split.io', membershipsFacundo); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -582,8 +582,8 @@ export default function readyPromiseAssertions(fetchMock, assert) { // /splitChanges takes longer than 'requestTimeoutBeforeReady' fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/facundo%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); - fetchMock.get(config.urls.sdk + '/mySegments/nicolas%40split.io', mySegmentsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/facundo%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/memberships/nicolas%40split.io', membershipsFacundo, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); diff --git a/src/__tests__/browserSuites/shared-instantiation.spec.js b/src/__tests__/browserSuites/shared-instantiation.spec.js index dddbe9fc6..9f9423ac9 100644 --- a/src/__tests__/browserSuites/shared-instantiation.spec.js +++ b/src/__tests__/browserSuites/shared-instantiation.spec.js @@ -14,9 +14,9 @@ const settings = settingsFactory({ * @param {boolean} sdkIgnoredTT whether the SDK ignores TT (i.e, clients without bound TT) or not (client with optional bound TT) */ export default function sharedInstantiationSuite(startWithTT, sdkIgnoresTT, fetchMock, assert) { - // mocking mySegments endpoints with delays for new clients - fetchMock.get(url(settings, '/mySegments/emiliano%2Fsplit.io'), { status: 200, body: { mySegments: [] } }, { delay: 100 }); - fetchMock.get(url(settings, '/mySegments/matias%25split.io'), { status: 200, body: { mySegments: [] } }, { delay: 200 }); + // mocking memberships endpoints with delays for new clients + fetchMock.get(url(settings, '/memberships/emiliano%2Fsplit.io'), { status: 200, body: { ms: {} } }, { delay: 100 }); + fetchMock.get(url(settings, '/memberships/matias%25split.io'), { status: 200, body: { ms: {} } }, { delay: 200 }); const factory = SplitFactory({ core: { diff --git a/src/__tests__/browserSuites/single-sync.spec.js b/src/__tests__/browserSuites/single-sync.spec.js index b7ae61757..a2d7c16a9 100644 --- a/src/__tests__/browserSuites/single-sync.spec.js +++ b/src/__tests__/browserSuites/single-sync.spec.js @@ -4,7 +4,7 @@ import { url } from '../testUtils'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsNicolasMock2 from '../mocks/mysegments.nicolas@split.io.json'; +import membershipsNicolasMock2 from '../mocks/memberships.nicolas@split.io.json'; const baseUrls = { sdk: 'https://sdk.single-sync/api', @@ -45,13 +45,13 @@ export default function singleSync(fetchMock, assert) { return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function () { - assert.pass('first mySegments fetch'); - return { status: 200, body: mySegmentsNicolasMock2 }; + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { + assert.pass('first memberships fetch'); + return { status: 200, body: membershipsNicolasMock2 }; }); - fetchMock.getOnce(url(settings, '/mySegments/nicolas%40split.io'), function () { - assert.fail('mySegments should not be called again'); - return { status: 200, body: mySegmentsNicolasMock2 }; + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { + assert.fail('memberships should not be called again'); + return { status: 200, body: membershipsNicolasMock2 }; }); let splitio, client = false; diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 8ae2910b9..0251dc0f2 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -35,8 +35,8 @@ export default async function telemetryBrowserSuite(fetchMock, t) { t.test(async (assert) => { fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', 500); fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', 500); - fetchMock.getOnce(baseUrls.sdk + '/mySegments/user-key', { status: 200, body: { 'mySegments': ['one_segment'] } }); + fetchMock.getOnce(baseUrls.sdk + '/memberships/user-key', 500); + fetchMock.getOnce(baseUrls.sdk + '/memberships/user-key', { status: 200, body: { 'ms': { k: [{ n: 'one_segment' }] } } }); // We need to handle all requests properly fetchMock.postOnce(baseUrls.events + '/testImpressions/bulk', 200); @@ -59,13 +59,13 @@ export default async function telemetryBrowserSuite(fetchMock, t) { const data = JSON.parse(opts.body); // Validate last successful sync - assert.deepEqual(Object.keys(data.lS), ['ms', 'sp', 'te'], 'Successful splitChanges, mySegments and metrics/config requests'); + assert.deepEqual(Object.keys(data.lS), ['ms', 'sp', 'te'], 'Successful splitChanges, memberships and metrics/config requests'); lastSync = data.lS; delete data.lS; // Validate http and method latencies const getLatencyCount = buckets => buckets ? buckets.reduce((accum, entry) => accum + entry, 0) : 0; assert.equal(getLatencyCount(data.hL.sp), 2, 'Two latency metrics for splitChanges GET request'); - assert.equal(getLatencyCount(data.hL.ms), 2, 'Two latency metrics for mySegments GET request'); + assert.equal(getLatencyCount(data.hL.ms), 2, 'Two latency metrics for memberships GET request'); assert.equal(getLatencyCount(data.hL.te), 1, 'One latency metric for telemetry config POST request'); assert.equal(getLatencyCount(data.mL.t), 2, 'Two latency metrics for getTreatment (one not ready usage'); assert.equal(getLatencyCount(data.mL.ts), 1, 'One latency metric for getTreatments'); @@ -187,7 +187,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { let factory; const splitFilters = [{ type: 'bySet', values: ['a', '_b', 'a', 'a', 'c', 'd', '_d'] }]; - fetchMock.get(baseUrls.sdk + '/mySegments/nicolas%40split.io', { status: 200, body: { 'mySegments': [] } }); + fetchMock.get(baseUrls.sdk + '/memberships/nicolas%40split.io', { status: 200, body: { 'ms': {} } }); fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=a,c,d', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.postOnce(baseUrls.telemetry + '/v1/metrics/config', (url, opts) => { const data = JSON.parse(opts.body); diff --git a/src/__tests__/browserSuites/use-beacon-api.debug.spec.js b/src/__tests__/browserSuites/use-beacon-api.debug.spec.js index 7e673afff..7de576e6c 100644 --- a/src/__tests__/browserSuites/use-beacon-api.debug.spec.js +++ b/src/__tests__/browserSuites/use-beacon-api.debug.spec.js @@ -2,7 +2,7 @@ import sinon from 'sinon'; import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; import { DEBUG } from '@splitsoftware/splitio-commons/src/utils/constants'; import { url } from '../testUtils'; import { triggerPagehideEvent, triggerVisibilitychange } from '../testUtils/browser'; @@ -68,7 +68,7 @@ function beaconApiNotSendTestDebug(fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); // Init and run Split client const splitio = SplitFactory(config); diff --git a/src/__tests__/browserSuites/use-beacon-api.spec.js b/src/__tests__/browserSuites/use-beacon-api.spec.js index ed08eb8e2..bde426077 100644 --- a/src/__tests__/browserSuites/use-beacon-api.spec.js +++ b/src/__tests__/browserSuites/use-beacon-api.spec.js @@ -2,7 +2,7 @@ import sinon from 'sinon'; import { SplitFactory } from '../../'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; import { url } from '../testUtils'; import { OPTIMIZED } from '@splitsoftware/splitio-commons/src/utils/constants'; import { triggerPagehideEvent, triggerVisibilitychange } from '../testUtils/browser'; @@ -80,7 +80,7 @@ function beaconApiNotSendTest(fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); // Init and run Split client const splitio = SplitFactory(config); diff --git a/src/__tests__/destroy/browser.spec.js b/src/__tests__/destroy/browser.spec.js index b7df518c7..88afc744d 100644 --- a/src/__tests__/destroy/browser.spec.js +++ b/src/__tests__/destroy/browser.spec.js @@ -8,7 +8,7 @@ import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitChanges.since.-1.till.1500492097547.json'; import splitChangesMock2 from '../mocks/splitChanges.since.1500492097547.json'; -import mySegmentsMock from '../mocks/mySegmentsEmpty.json'; +import membershipsMock from '../mocks/membershipsEmpty.json'; import impressionsMock from '../mocks/impressions.json'; const settings = settingsFactory({ @@ -20,10 +20,10 @@ const settings = settingsFactory({ fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); -fetchMock.getOnce(url(settings, '/mySegments/ut1'), { status: 200, body: mySegmentsMock }); -fetchMock.getOnce(url(settings, '/mySegments/ut2'), { status: 200, body: mySegmentsMock }); -fetchMock.getOnce(url(settings, '/mySegments/ut3'), { status: 200, body: mySegmentsMock }); -fetchMock.getOnce(url(settings, '/mySegments/ut4'), { status: 200, body: mySegmentsMock }); +fetchMock.getOnce(url(settings, '/memberships/ut1'), { status: 200, body: membershipsMock }); +fetchMock.getOnce(url(settings, '/memberships/ut2'), { status: 200, body: membershipsMock }); +fetchMock.getOnce(url(settings, '/memberships/ut3'), { status: 200, body: membershipsMock }); +fetchMock.getOnce(url(settings, '/memberships/ut4'), { status: 200, body: membershipsMock }); fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); // 0.1% sample rate tape('SDK destroy for BrowserJS', async function (assert) { diff --git a/src/__tests__/errorCatching/browser.spec.js b/src/__tests__/errorCatching/browser.spec.js index 25315666d..4ad0c8222 100644 --- a/src/__tests__/errorCatching/browser.spec.js +++ b/src/__tests__/errorCatching/browser.spec.js @@ -5,7 +5,7 @@ import includes from 'lodash/includes'; import fetchMock from '../testUtils/fetchMock'; import { url } from '../testUtils'; import splitChangesMock1 from '../mocks/splitChanges.since.-1.till.1500492097547.json'; -import mySegmentsMock from '../mocks/mySegmentsEmpty.json'; +import membershipsMock from '../mocks/membershipsEmpty.json'; import splitChangesMock2 from '../mocks/splitChanges.since.1500492097547.till.1500492297547.json'; import splitChangesMock3 from '../mocks/splitChanges.since.1500492297547.json'; import { SplitFactory } from '../../'; @@ -28,7 +28,7 @@ fetchMock.get(url(settings, '/splitChanges?s=1.2&since=25'), function () { }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492297547'), { status: 200, body: splitChangesMock3 }); -fetchMock.get(url(settings, '/mySegments/nico%40split.io'), { status: 200, body: mySegmentsMock }); +fetchMock.get(url(settings, '/memberships/nico%40split.io'), { status: 200, body: membershipsMock }); fetchMock.post('*', 200); const assertionsPlanned = 4; diff --git a/src/__tests__/gaIntegration/browser.spec.js b/src/__tests__/gaIntegration/browser.spec.js index 3eb6b3144..502d57c29 100644 --- a/src/__tests__/gaIntegration/browser.spec.js +++ b/src/__tests__/gaIntegration/browser.spec.js @@ -8,7 +8,7 @@ import bothIntegrationsSuite from './both-integrations.spec'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; const settings = settingsFactory({ core: { @@ -19,7 +19,7 @@ const settings = settingsFactory({ tape('## E2E CI Tests ##', function (assert) { fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); fetchMock.post(/\/v1\/metrics/, 200); // 0.1% sample rate /* Validate GA integration */ diff --git a/src/__tests__/mocks/memberships.emmanuel@split.io.json b/src/__tests__/mocks/memberships.emmanuel@split.io.json new file mode 100644 index 000000000..aec8b8705 --- /dev/null +++ b/src/__tests__/mocks/memberships.emmanuel@split.io.json @@ -0,0 +1,15 @@ +{ + "ms": { + "k": [ + { + "n": "developers" + }, + { + "n": "engineers" + }, + { + "n": "employees" + } + ] + } +} \ No newline at end of file diff --git a/src/__tests__/mocks/memberships.facundo@split.io.json b/src/__tests__/mocks/memberships.facundo@split.io.json new file mode 100644 index 000000000..d64b10ee3 --- /dev/null +++ b/src/__tests__/mocks/memberships.facundo@split.io.json @@ -0,0 +1,9 @@ +{ + "ms": { + "k": [ + { + "n": "splitters" + } + ] + } +} \ No newline at end of file diff --git a/src/__tests__/mocks/memberships.marcio@split.io.json b/src/__tests__/mocks/memberships.marcio@split.io.json new file mode 100644 index 000000000..476ddc3f4 --- /dev/null +++ b/src/__tests__/mocks/memberships.marcio@split.io.json @@ -0,0 +1,3 @@ +{ + "ms": {} +} diff --git a/src/__tests__/mocks/memberships.nicolas@split.io.json b/src/__tests__/mocks/memberships.nicolas@split.io.json new file mode 100644 index 000000000..aec8b8705 --- /dev/null +++ b/src/__tests__/mocks/memberships.nicolas@split.io.json @@ -0,0 +1,15 @@ +{ + "ms": { + "k": [ + { + "n": "developers" + }, + { + "n": "engineers" + }, + { + "n": "employees" + } + ] + } +} \ No newline at end of file diff --git a/src/__tests__/mocks/memberships.nicolas@split.io.mock2.json b/src/__tests__/mocks/memberships.nicolas@split.io.mock2.json new file mode 100644 index 000000000..9de7489d1 --- /dev/null +++ b/src/__tests__/mocks/memberships.nicolas@split.io.mock2.json @@ -0,0 +1,15 @@ +{ + "ms": { + "k": [ + { + "n": "developers" + }, + { + "n": "engineers" + }, + { + "n": "splitters" + } + ] + } +} \ No newline at end of file diff --git a/src/__tests__/mocks/membershipsEmpty.json b/src/__tests__/mocks/membershipsEmpty.json new file mode 100644 index 000000000..7473a4b01 --- /dev/null +++ b/src/__tests__/mocks/membershipsEmpty.json @@ -0,0 +1,5 @@ +{ + "ms": { + "k": [] + } +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json index eac4303a0..eebe360d5 100644 --- a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json +++ b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -1,4 +1,4 @@ { "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552653000,\\\"largeSegments\\\":[\\\"harnessians\\\",\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" } \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json deleted file mode 100644 index f6fa59825..000000000 --- a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552650000,\\\"largeSegments\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json new file mode 100644 index 000000000..5d5b3d9b7 --- /dev/null +++ b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552645000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552645000.json deleted file mode 100644 index 415bc2b09..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552645000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"id\":\"mc4i3NENoA:0:0\",\"clientId\":\"NDEzMTY5Mzg0MA==:MTM2ODE2NDMxNA==\",\"timestamp\":1457552645900,\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw==_MjE0MTkxOTU2Mg==_mySegments\",\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552645000,\\\"segmentList\\\":[\\\"employees\\\"],\\\"includesPayload\\\":true}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552646000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552646000.json deleted file mode 100644 index 18daa83bd..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.marcio@split.io.1457552646000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"id\":\"mc4i3NENoA:0:0\",\"clientId\":\"NDEzMTY5Mzg0MA==:MTM2ODE2NDMxNA==\",\"timestamp\":1457552646900,\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw==_MjE0MTkxOTU2Mg==_mySegments\",\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552646000,\\\"includesPayload\\\":true}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json deleted file mode 100644 index 951d8a31d..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552640000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"id\":\"mc4i3NENoA:0:0\",\"clientId\":\"NDEzMTY5Mzg0MA==:MTM2ODE2NDMxNA==\",\"timestamp\":1457552640900,\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw==_NTcwOTc3MDQx_mySegments\",\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552640000,\\\"includesPayload\\\":false}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552641000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552641000.json deleted file mode 100644 index 1c659961e..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE.nicolas@split.io.1457552641000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"id\":\"mc4i3NENoA:0:0\",\"clientId\":\"NDEzMTY5Mzg0MA==:MTM2ODE2NDMxNA==\",\"timestamp\":1457552641900,\"encoding\":\"json\",\"channel\":\"NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw==_NTcwOTc3MDQx_mySegments\",\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE\\\",\\\"changeNumber\\\":1457552641000,\\\"includesPayload\\\":false}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json new file mode 100644 index 000000000..c934e1f0b --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json new file mode 100644 index 000000000..487b8860d --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json new file mode 100644 index 000000000..c2960774a --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552652000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..c22d47e12 --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json new file mode 100644 index 000000000..5f1f09aab --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552640000,\\\"u\\\": 0,\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json new file mode 100644 index 000000000..7bb8514dd --- /dev/null +++ b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.V2.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.V2.BOUNDED.GZIP.1457552651000.json deleted file mode 100644 index 97c2a73c9..000000000 --- a/src/__tests__/mocks/message.V2.BOUNDED.GZIP.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE_V2\\\",\\\"changeNumber\\\":1457552651000,\\\"segmentName\\\":\\\"\\\",\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.V2.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.V2.BOUNDED.ZLIB.1457552651000.json deleted file mode 100644 index 44c008928..000000000 --- a/src/__tests__/mocks/message.V2.BOUNDED.ZLIB.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE_V2\\\",\\\"changeNumber\\\":1457552651000,\\\"segmentName\\\":\\\"\\\",\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.V2.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.V2.KEYLIST.GZIP.1457552652000.json deleted file mode 100644 index c44ee3ac3..000000000 --- a/src/__tests__/mocks/message.V2.KEYLIST.GZIP.1457552652000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE_V2\\\",\\\"changeNumber\\\":1457552652000,\\\"segmentName\\\":\\\"splitters\\\",\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json deleted file mode 100644 index aaf1a3f33..000000000 --- a/src/__tests__/mocks/message.V2.SEGMENT_REMOVAL.1457552653000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE_V2\\\",\\\"changeNumber\\\":1457552653000,\\\"segmentName\\\":\\\"splitters\\\",\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.V2.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.V2.UNBOUNDED.1457552650000.json deleted file mode 100644 index a7a2e793e..000000000 --- a/src/__tests__/mocks/message.V2.UNBOUNDED.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MY_SEGMENTS_UPDATE_V2\\\",\\\"changeNumber\\\":1457552650000,\\\"segmentName\\\":\\\"\\\",\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/mySegmentsEmpty.json b/src/__tests__/mocks/mySegmentsEmpty.json deleted file mode 100644 index 619bab21b..000000000 --- a/src/__tests__/mocks/mySegmentsEmpty.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "mySegments": [] -} diff --git a/src/__tests__/mocks/mysegments.emmanuel@split.io.json b/src/__tests__/mocks/mysegments.emmanuel@split.io.json deleted file mode 100644 index 6d53eb431..000000000 --- a/src/__tests__/mocks/mysegments.emmanuel@split.io.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mySegments": [ - { - "id": "482df151-e63f-11e9-9275-924a43dg782b", - "name": "developers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc783e", - "name": "engineers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc7840", - "name": "employees" - } - ] -} diff --git a/src/__tests__/mocks/mysegments.facundo@split.io.json b/src/__tests__/mocks/mysegments.facundo@split.io.json deleted file mode 100644 index de85cc2f9..000000000 --- a/src/__tests__/mocks/mysegments.facundo@split.io.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "mySegments": [ - { - "id": "482df150-e62f-11e5-9265-924a43db712b", - "name": "splitters" - } - ] -} diff --git a/src/__tests__/mocks/mysegments.marcio@split.io.json b/src/__tests__/mocks/mysegments.marcio@split.io.json deleted file mode 100644 index 619bab21b..000000000 --- a/src/__tests__/mocks/mysegments.marcio@split.io.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "mySegments": [] -} diff --git a/src/__tests__/mocks/mysegments.nicolas@split.io.json b/src/__tests__/mocks/mysegments.nicolas@split.io.json deleted file mode 100644 index 6d53eb431..000000000 --- a/src/__tests__/mocks/mysegments.nicolas@split.io.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mySegments": [ - { - "id": "482df151-e63f-11e9-9275-924a43dg782b", - "name": "developers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc783e", - "name": "engineers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc7840", - "name": "employees" - } - ] -} diff --git a/src/__tests__/mocks/mysegments.nicolas@split.io.mock2.json b/src/__tests__/mocks/mysegments.nicolas@split.io.mock2.json deleted file mode 100644 index 98a1538ae..000000000 --- a/src/__tests__/mocks/mysegments.nicolas@split.io.mock2.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "mySegments": [ - { - "id": "482df151-e63f-11e9-9275-924a43dg782b", - "name": "developers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc783e", - "name": "engineers" - }, - { - "id": "725df151-d43f-11e9-7561-498b43dc783f", - "name": "splitters" - } - ] -} \ No newline at end of file diff --git a/src/__tests__/nodeSuites/push-initialization-retries.spec.js b/src/__tests__/nodeSuites/push-initialization-retries.spec.js index ace87370e..b55621084 100644 --- a/src/__tests__/nodeSuites/push-initialization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-retries.spec.js @@ -168,7 +168,7 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { * Assert that if the main client is destroyed while authentication request is in progress and successes, the SDK doesn't open the SSE connection * * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and first auth attempt + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and first auth attempt * 0.05 secs: client destroyed * 0.1 secs: first auth attempt response (success) but not SSE connection opened since push was closed * 0.2 secs: test finished @@ -207,8 +207,8 @@ export function testSdkDestroyWhileAuthSuccess(fetchMock, assert) { * Asserts that if the client is destroyed while authentication request is in progress and fails, the SDK doesn't schedule an auth retry * * Sequence of calls: - * 0.0 secs: initial SyncAll (/splitChanges, /mySegments/*) and first auth attempt (fail due to bad token) - * 0.0 secs: polling (/splitChanges, /mySegments/*) + * 0.0 secs: initial SyncAll (/splitChanges, /memberships/*) and first auth attempt (fail due to bad token) + * 0.0 secs: polling (/splitChanges, /memberships/*) * 0.1 secs: second auth attempt request * 0.15 secs: client destroyed * 0.2 secs: second auth attempt response (fail due to network error) diff --git a/src/__tests__/offline/browser.spec.js b/src/__tests__/offline/browser.spec.js index 10ef846d5..bce2020eb 100644 --- a/src/__tests__/offline/browser.spec.js +++ b/src/__tests__/offline/browser.spec.js @@ -9,7 +9,7 @@ const settings = settingsFactory({ core: { key: 'facundo@split.io' } }); const spySplitChanges = sinon.spy(); const spySegmentChanges = sinon.spy(); -const spyMySegments = sinon.spy(); +const spyMemberships = sinon.spy(); const spyEventsBulk = sinon.spy(); const spyTestImpressionsBulk = sinon.spy(); const spyTestImpressionsCount = sinon.spy(); @@ -27,7 +27,7 @@ const replySpy = spy => { const configMocks = () => { fetchMock.mock(new RegExp(`${url(settings, '/splitChanges/')}.*`), () => replySpy(spySplitChanges)); fetchMock.mock(new RegExp(`${url(settings, '/segmentChanges/')}.*`), () => replySpy(spySegmentChanges)); - fetchMock.mock(new RegExp(`${url(settings, '/mySegments/')}.*`), () => replySpy(spyMySegments)); + fetchMock.mock(new RegExp(`${url(settings, '/memberships/')}.*`), () => replySpy(spyMemberships)); fetchMock.mock(url(settings, '/events/bulk'), () => replySpy(spyEventsBulk)); fetchMock.mock(url(settings, '/testImpressions/bulk'), () => replySpy(spyTestImpressionsBulk)); fetchMock.mock(url(settings, '/testImpressions/count'), () => replySpy(spyTestImpressionsCount)); @@ -336,7 +336,7 @@ tape('Browser offline mode', function (assert) { // We test the breakdown instead of just the misc because it's faster to spot where the issue is assert.notOk(spySplitChanges.called, 'On offline mode we should not call the splitChanges endpoint.'); assert.notOk(spySegmentChanges.called, 'On offline mode we should not call the segmentChanges endpoint.'); - assert.notOk(spyMySegments.called, 'On offline mode we should not call the mySegments endpoint.'); + assert.notOk(spyMemberships.called, 'On offline mode we should not call the Memberships endpoint.'); assert.notOk(spyEventsBulk.called, 'On offline mode we should not call the events endpoint.'); assert.notOk(spyTestImpressionsBulk.called, 'On offline mode we should not call the impressions endpoint.'); assert.notOk(spyTestImpressionsCount.called, 'On offline mode we should not call the impressions count endpoint.'); diff --git a/src/__tests__/offline/node.spec.js b/src/__tests__/offline/node.spec.js index 5d1d52e8c..4d0b8e562 100644 --- a/src/__tests__/offline/node.spec.js +++ b/src/__tests__/offline/node.spec.js @@ -11,7 +11,7 @@ const settings = settingsFactory({ core: { key: 'facundo@split.io' } }); const spySplitChanges = sinon.spy(); const spySegmentChanges = sinon.spy(); -const spyMySegments = sinon.spy(); +const spyMemberships = sinon.spy(); const spyEventsBulk = sinon.spy(); const spyTestImpressionsBulk = sinon.spy(); const spyTestImpressionsCount = sinon.spy(); @@ -29,7 +29,7 @@ const replySpy = spy => { const configMocks = () => { fetchMock.mock(new RegExp(`${url(settings, '/splitChanges/')}.*`), () => replySpy(spySplitChanges)); fetchMock.mock(new RegExp(`${url(settings, '/segmentChanges/')}.*`), () => replySpy(spySegmentChanges)); - fetchMock.mock(new RegExp(`${url(settings, '/mySegments/')}.*`), () => replySpy(spyMySegments)); + fetchMock.mock(new RegExp(`${url(settings, '/memberships/')}.*`), () => replySpy(spyMemberships)); fetchMock.mock(url(settings, '/events/bulk'), () => replySpy(spyEventsBulk)); fetchMock.mock(url(settings, '/testImpressions/bulk'), () => replySpy(spyTestImpressionsBulk)); fetchMock.mock(url(settings, '/testImpressions/count'), () => replySpy(spyTestImpressionsCount)); @@ -98,7 +98,7 @@ function networkAssertions(client, assert) { // We test the breakdown instead of just the misc because it's faster to spot where the issue is assert.notOk(spySplitChanges.called, 'On offline mode we should not call the splitChanges endpoint.'); assert.notOk(spySegmentChanges.called, 'On offline mode we should not call the segmentChanges endpoint.'); - assert.notOk(spyMySegments.called, 'On offline mode we should not call the mySegments endpoint.'); + assert.notOk(spyMemberships.called, 'On offline mode we should not call the memberships endpoint.'); assert.notOk(spyEventsBulk.called, 'On offline mode we should not call the events endpoint.'); assert.notOk(spyTestImpressionsBulk.called, 'On offline mode we should not call the impressions endpoint.'); assert.notOk(spyTestImpressionsCount.called, 'On offline mode we should not call the impressions count endpoint.'); diff --git a/src/__tests__/online/browser.spec.js b/src/__tests__/online/browser.spec.js index 74574666a..e3c6ebe86 100644 --- a/src/__tests__/online/browser.spec.js +++ b/src/__tests__/online/browser.spec.js @@ -25,10 +25,10 @@ import flagSets from '../browserSuites/flag-sets.spec'; import { settingsFactory } from '../../settings'; import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; -import mySegmentsFacundo from '../mocks/mysegments.facundo@split.io.json'; -import mySegmentsNicolas from '../mocks/mysegments.nicolas@split.io.json'; -import mySegmentsMarcio from '../mocks/mysegments.marcio@split.io.json'; -import mySegmentsEmmanuel from '../mocks/mysegments.emmanuel@split.io.json'; +import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; +import membershipsNicolas from '../mocks/memberships.nicolas@split.io.json'; +import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; +import membershipsEmmanuel from '../mocks/memberships.emmanuel@split.io.json'; const settings = settingsFactory({ core: { @@ -89,10 +89,10 @@ tape('## E2E CI Tests ##', function (assert) { fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); - fetchMock.get(url(settings, '/mySegments/facundo%40split.io'), { status: 200, body: mySegmentsFacundo }); - fetchMock.get(url(settings, '/mySegments/nicolas%40split.io'), { status: 200, body: mySegmentsNicolas }); - fetchMock.get(url(settings, '/mySegments/marcio%40split.io'), { status: 200, body: mySegmentsMarcio }); - fetchMock.get(url(settings, '/mySegments/emmanuel%40split.io'), { status: 200, body: mySegmentsEmmanuel }); + fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); + fetchMock.get(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolas }); + fetchMock.get(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); + fetchMock.get(url(settings, '/memberships/emmanuel%40split.io'), { status: 200, body: membershipsEmmanuel }); fetchMock.post(url(settings, '/testImpressions/bulk'), 200); fetchMock.post(url(settings, '/testImpressions/count'), 200); Math.random = () => 0.5; // SDKs without telemetry From 917e0634cdb29f0bfb408e106c5fa6c676e91110 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Sun, 1 Sep 2024 14:39:35 -0300 Subject: [PATCH 20/58] Notification refactors: t->type, MEMBERSHIP_MS_UPDATE, MEMBERSHIP_LS_UPDATE --- .../browserSuites/push-fallback.spec.js | 20 +++++------ .../push-synchronization-retries.spec.js | 24 ++++++------- .../push-synchronization.spec.js | 34 +++++++++---------- ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 +++ ..._UPDATE.UNBOUNDED.DELAY.1457552650000.json | 4 +++ ..._MS_UPDATE.BOUNDED.GZIP.1457552651000.json | 4 +++ ..._MS_UPDATE.BOUNDED.ZLIB.1457552651000.json | 4 +++ ..._MS_UPDATE.KEYLIST.GZIP.1457552652000.json | 4 +++ ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 +++ ...HIP_MS_UPDATE.UNBOUNDED.1457552640000.json | 4 +++ ...HIP_MS_UPDATE.UNBOUNDED.1457552650000.json | 4 +++ ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 --- ..._UPDATE.UNBOUNDED.DELAY.1457552650000.json | 4 --- ..._UPDATE_V3.BOUNDED.GZIP.1457552651000.json | 4 --- ..._UPDATE_V3.BOUNDED.ZLIB.1457552651000.json | 4 --- ..._UPDATE_V3.KEYLIST.GZIP.1457552652000.json | 4 --- ...DATE_V3.SEGMENT_REMOVAL.1457552653000.json | 4 --- ...NTS_UPDATE_V3.UNBOUNDED.1457552640000.json | 4 --- ...NTS_UPDATE_V3.UNBOUNDED.1457552650000.json | 4 --- 19 files changed, 71 insertions(+), 71 deletions(-) create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json delete mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json delete mode 100644 src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json delete mode 100644 src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json diff --git a/src/__tests__/browserSuites/push-fallback.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js index a2ab4a54c..87a1c3db6 100644 --- a/src/__tests__/browserSuites/push-fallback.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -20,7 +20,7 @@ import streamingPausedControlPriMessage2 from '../mocks/message.CONTROL.STREAMIN import streamingDisabledControlPriMessage from '../mocks/message.CONTROL.STREAMING_DISABLED.control_pri.1586987434950.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -66,11 +66,11 @@ const MILLIS_CREATE_CLIENT_DURING_PUSH = MILLIS_STREAMING_UP_OCCUPANCY + 50; const MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_UP_OCCUPANCY + 100; const MILLIS_STREAMING_PAUSED_CONTROL = MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH + 100; -const MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_POLLING = MILLIS_STREAMING_PAUSED_CONTROL + 100; +const MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_POLLING = MILLIS_STREAMING_PAUSED_CONTROL + 100; const MILLIS_STREAMING_RESUMED_CONTROL = MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate + 100; -const MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_RESUMED_CONTROL + 100; +const MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_RESUMED_CONTROL + 100; -const MILLIS_STREAMING_PAUSED_CONTROL_2 = MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_PUSH + 100; +const MILLIS_STREAMING_PAUSED_CONTROL_2 = MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH + 100; const MILLIS_STREAMING_RESET_WHILE_PUSH_DOWN = MILLIS_STREAMING_PAUSED_CONTROL_2 + 100; const MILLIS_STREAMING_RESET_WHILE_PUSH_UP = MILLIS_STREAMING_RESET_WHILE_PUSH_DOWN + settings.scheduler.featuresRefreshRate; const MILLIS_STREAMING_DISABLED_CONTROL = MILLIS_STREAMING_RESET_WHILE_PUSH_UP + 100; @@ -88,11 +88,11 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe * 0.55 secs: create a new client while streaming -> initial fetch (/memberships/marcio), auth, SSE connection and syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) * 0.6 secs: SPLIT_UPDATE event -> /splitChanges * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) - * 0.8 secs: MY_SEGMENTS_UPDATE_V3 event ignored + * 0.8 secs: MEMBERSHIP_MS_UPDATE event ignored * 0.9 secs: periodic fetch due to polling (/splitChanges) * 0.95 secs: periodic fetch due to polling (/memberships/nicolas, /memberships/marcio) * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) - * 1.1 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas, /memberships/marcio + * 1.1 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas, /memberships/marcio * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) * 1.3 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll and stop polling * 1.5 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll @@ -155,7 +155,7 @@ export function testFallback(fetchMock, assert) { setTimeout(() => { assert.equal(eventSourceInstance.readyState, EventSourceMock.OPEN, 'EventSource connection keeps opened after PUSH_SUBSYSTEM_DOWN (STREAMING_PAUSED event)'); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_POLLING - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MY_SEGMENTS_UPDATE event while polling, to check that we are ignoring it + }, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_POLLING - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIP_MS_UPDATE event while polling, to check that we are ignoring it setTimeout(() => { eventSourceInstance.emitMessage(streamingResumedControlPriMessage); @@ -167,7 +167,7 @@ export function testFallback(fetchMock, assert) { assert.equal(client.getTreatment('real_split'), 'on', 'evaluation with updated segment'); }); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_PUSH - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MY_SEGMENTS_UPDATE event + }, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIP_MS_UPDATE event setTimeout(() => { eventSourceInstance.emitMessage(streamingPausedControlPriMessage2); @@ -271,10 +271,10 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); - // fetch due to MY_SEGMENTS_UPDATE event + // fetch due to MEMBERSHIP_MS_UPDATE event fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_MY_SEGMENTS_UPDATE_EVENT_DURING_PUSH), 'sync due to MY_SEGMENTS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH), 'sync due to MEMBERSHIP_MS_UPDATE event'); return { status: 200, body: membershipsNicolasMock2 }; }); fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); diff --git a/src/__tests__/browserSuites/push-synchronization-retries.spec.js b/src/__tests__/browserSuites/push-synchronization-retries.spec.js index 7bb76a9df..65df72b41 100644 --- a/src/__tests__/browserSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/browserSuites/push-synchronization-retries.spec.js @@ -7,7 +7,7 @@ import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; @@ -64,10 +64,10 @@ const MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT = 2000; * * 0.4 secs: SPLIT_UPDATE event with old changeNumber -> SDK_UPDATE not triggered * - * 0.5 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/marcio@split.io OK, /memberships/nicolas@split.io: network error - * 0.6 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io retry: invalid JSON response - * 0.8 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io: server error - * 1.2 secs: Unbounded MY_SEGMENTS_UPDATE_V3 event -> /memberships/nicolas@split.io retry: success -> SDK_UPDATE triggered + * 0.5 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/marcio@split.io OK, /memberships/nicolas@split.io: network error + * 0.6 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io retry: invalid JSON response + * 0.8 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io: server error + * 1.2 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io retry: success -> SDK_UPDATE triggered * * 1.3 secs: SPLIT_KILL event -> /splitChanges: outdated response -> SDK_UPDATE triggered although fetches fail * 1.4 secs: SPLIT_KILL event -> /splitChanges retry: network error @@ -114,11 +114,11 @@ export function testSynchronizationRetries(fetchMock, assert) { assert.equal(client.getTreatment('splitters'), 'off', 'evaluation with initial MySegments list'); client.once(client.Event.SDK_UPDATE, () => { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'SDK_UPDATE due to MY_SEGMENTS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'SDK_UPDATE due to MEMBERSHIP_MS_UPDATE event'); assert.equal(client.getTreatment('splitters'), 'on', 'evaluation with updated MySegments list'); }); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MYSEGMENTS_UPDATE_V3_EVENT); // send a MY_SEGMENTS_UPDATE_V3 event with a new changeNumber after 0.4 seconds + }, MILLIS_MYSEGMENTS_UPDATE_V3_EVENT); // send a MEMBERSHIP_MS_UPDATE event with a new changeNumber after 0.4 seconds setTimeout(() => { client.once(client.Event.SDK_UPDATE, () => { @@ -163,16 +163,16 @@ export function testSynchronizationRetries(fetchMock, assert) { return { status: 200, body: splitChangesMock3 }; }); - // fetch due to first MY_SEGMENTS_UPDATE event + // fetch due to first MEMBERSHIP_MS_UPDATE event fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { throws: new TypeError('Network error') }); - // fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail + // fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response - // fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail + // fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 500, body: 'server error' }); - // second fetch retry for MY_SEGMENTS_UPDATE event, due to previous fail + // second fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'sync second retry for MY_SEGMENTS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'sync second retry for MEMBERSHIP_MS_UPDATE event'); return { status: 200, body: membershipsNicolasMock2 }; }); diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 88c946006..ad9400e1a 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -9,12 +9,12 @@ import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; -import unboundedMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json'; -import boundedZlibMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json'; -import keylistGzipMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json'; -import segmentRemovalMessage from '../mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json'; -import unboundedMyLargeSegmentsMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; -import myLargeSegmentRemovalMessage from '../mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json'; +import boundedZlibMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json'; +import keylistGzipMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json'; +import segmentRemovalMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMyLargeSegmentsMessage from '../mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; +import myLargeSegmentRemovalMessage from '../mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -76,15 +76,15 @@ const MILLIS_SEGMENT_REMOVAL_LS = 1800; * 0.5 secs: creates a new client -> new auth and SSE connection * 0.6 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) * 0.7 secs: creates more clients - * 0.8 secs: MY_SEGMENTS_UPDATE_V3 UnboundedFetchRequest event. - * 0.9 secs: MY_SEGMENTS_UPDATE_V3 BoundedFetchRequest event error --> UnboundedFetchRequest. - * 1.0 secs: MY_SEGMENTS_UPDATE_V3 KeyList event error --> UnboundedFetchRequest. - * 1.1 secs: MY_SEGMENTS_UPDATE_V3 BoundedFetchRequest event. - * 1.2 secs: MY_SEGMENTS_UPDATE_V3 KeyList event. - * 1.3 secs: MY_SEGMENTS_UPDATE_V3 SegmentRemoval event. - * 1.4 secs: MY_LARGE_SEGMENTS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) - * 1.641 secs: /memberships/* fetch due to unbounded MY_LARGE_SEGMENTS_UPDATE event -> SDK_UPDATE event - * 1.8 secs: MY_LARGE_SEGMENTS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 0.8 secs: MEMBERSHIP_MS_UPDATE UnboundedFetchRequest event. + * 0.9 secs: MEMBERSHIP_MS_UPDATE BoundedFetchRequest event error --> UnboundedFetchRequest. + * 1.0 secs: MEMBERSHIP_MS_UPDATE KeyList event error --> UnboundedFetchRequest. + * 1.1 secs: MEMBERSHIP_MS_UPDATE BoundedFetchRequest event. + * 1.2 secs: MEMBERSHIP_MS_UPDATE KeyList event. + * 1.3 secs: MEMBERSHIP_MS_UPDATE SegmentRemoval event. + * 1.4 secs: MEMBERSHIP_LS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) + * 1.641 secs: /memberships/* fetch due to unbounded MEMBERSHIP_LS_UPDATE event -> SDK_UPDATE event + * 1.8 secs: MEMBERSHIP_LS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { assert.plan(34); @@ -319,7 +319,7 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: membershipsMarcio }; }); - // 3 unbounded fetch for MY_SEGMENTS_UPDATE_V3 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE + // 3 unbounded fetch for MEMBERSHIP_MS_UPDATE + 1 unbounded fetch for MEMBERSHIP_LS_UPDATE fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 3 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: membershipsNicolasMock2 }; @@ -330,7 +330,7 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: membershipsMarcio }; }); - // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MY_SEGMENTS_UPDATE_V3 + 1 unbounded fetch for MY_LARGE_SEGMENTS_UPDATE + // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MEMBERSHIP_MS_UPDATE + 1 unbounded fetch for MEMBERSHIP_LS_UPDATE fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); fetchMock.get({ url: url(settings, '/memberships/key1'), repeat: 6 }, { status: 200, body: { ms: {} } }); fetchMock.get({ url: url(settings, '/memberships/key3'), repeat: 6 }, { status: 200, body: { ms: { k: [{ n: 'splitters' }] } } }); diff --git a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..28540e802 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_LS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json new file mode 100644 index 000000000..9b3493588 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_LS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json new file mode 100644 index 000000000..7f4e53b31 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json new file mode 100644 index 000000000..88dae3cb7 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json new file mode 100644 index 000000000..c9cb0b904 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552652000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..55def7a16 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json new file mode 100644 index 000000000..ef1a218c6 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552640000,\\\"u\\\": 0,\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json new file mode 100644 index 000000000..663d89c6b --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json deleted file mode 100644 index eebe360d5..000000000 --- a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.SEGMENT_REMOVAL.1457552653000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json b/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json deleted file mode 100644 index 5d5b3d9b7..000000000 --- a/src/__tests__/mocks/message.MY_LARGE_SEGMENTS_UPDATE.UNBOUNDED.DELAY.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_LARGE_SEGMENTS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json deleted file mode 100644 index c934e1f0b..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.GZIP.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json deleted file mode 100644 index 487b8860d..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.BOUNDED.ZLIB.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json deleted file mode 100644 index c2960774a..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.KEYLIST.GZIP.1457552652000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552652000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json deleted file mode 100644 index c22d47e12..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.SEGMENT_REMOVAL.1457552653000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json deleted file mode 100644 index 5f1f09aab..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552640000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552640000,\\\"u\\\": 0,\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json deleted file mode 100644 index 7bb8514dd..000000000 --- a/src/__tests__/mocks/message.MY_SEGMENTS_UPDATE_V3.UNBOUNDED.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"t\\\":\\\"MY_SEGMENTS_UPDATE_V3\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file From 3fbbfa6b2b9592d14a3eba977c93b37cef8071b6 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 2 Sep 2024 11:21:36 -0300 Subject: [PATCH 21/58] rc --- .github/workflows/ci-cd.yml | 4 ++-- package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..982a7a3a3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_unify_endpoint' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_unify_endpoint' }} strategy: matrix: environment: diff --git a/package-lock.json b/package-lock.json index f9283ab20..893173807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.27.1-rc.3", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.10", + "@splitsoftware/splitio-commons": "1.16.1-rc.11", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.10", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.10.tgz", - "integrity": "sha512-FK8zFFgrSgPWZVDYsOMQPXMycwUzjwaTQLq7ZrGbCW2sGF8UujiRmwsCQEmghMAU+eq9rLlIvVFUIA5Px1sbqw==", + "version": "1.16.1-rc.11", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.11.tgz", + "integrity": "sha512-w1Hv6y98PaIUCAy4DP+0l0GabagPwt+4u9Z6BsTtXlnWjkSXfgHQJnR2EjdhU5xrACdgR+x9rENm2ZSjioNebg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8416,9 +8416,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.10", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.10.tgz", - "integrity": "sha512-FK8zFFgrSgPWZVDYsOMQPXMycwUzjwaTQLq7ZrGbCW2sGF8UujiRmwsCQEmghMAU+eq9rLlIvVFUIA5Px1sbqw==", + "version": "1.16.1-rc.11", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.11.tgz", + "integrity": "sha512-w1Hv6y98PaIUCAy4DP+0l0GabagPwt+4u9Z6BsTtXlnWjkSXfgHQJnR2EjdhU5xrACdgR+x9rENm2ZSjioNebg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 7c864214c..6a5f4bc56 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.10", + "@splitsoftware/splitio-commons": "1.16.1-rc.11", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", From 087e77202be4b7ae6d73fc602bc60b5a10ea050d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 3 Sep 2024 17:51:10 -0300 Subject: [PATCH 22/58] Update tests with new auth payloads and notification types --- package-lock.json | 18 ++--- package.json | 4 +- .../browserSuites/push-fallback.spec.js | 24 +++---- .../push-initialization-retries.spec.js | 2 +- .../push-synchronization-retries.spec.js | 30 ++++---- .../push-synchronization.spec.js | 71 ++++++++++--------- src/__tests__/browserSuites/readiness.spec.js | 4 +- .../auth.pushEnabled.nicolas@split.io.json | 2 +- ...bled.nicolas@split.io.marcio@split.io.json | 2 +- ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 ++ ..._UPDATE.UNBOUNDED.DELAY.1457552650000.json | 4 ++ ..._MS_UPDATE.BOUNDED.GZIP.1457552651000.json | 4 ++ ..._MS_UPDATE.BOUNDED.ZLIB.1457552651000.json | 4 ++ ..._MS_UPDATE.KEYLIST.GZIP.1457552652000.json | 4 ++ ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 ++ ...IPS_MS_UPDATE.UNBOUNDED.1457552640000.json | 4 ++ ...IPS_MS_UPDATE.UNBOUNDED.1457552650000.json | 4 ++ ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 -- ..._UPDATE.UNBOUNDED.DELAY.1457552650000.json | 4 -- ..._MS_UPDATE.BOUNDED.GZIP.1457552651000.json | 4 -- ..._MS_UPDATE.BOUNDED.ZLIB.1457552651000.json | 4 -- ..._MS_UPDATE.KEYLIST.GZIP.1457552652000.json | 4 -- ..._UPDATE.SEGMENT_REMOVAL.1457552653000.json | 4 -- ...HIP_MS_UPDATE.UNBOUNDED.1457552640000.json | 4 -- ...HIP_MS_UPDATE.UNBOUNDED.1457552650000.json | 4 -- src/settings/defaults/version.js | 2 +- 26 files changed, 112 insertions(+), 111 deletions(-) create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.GZIP.1457552651000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json create mode 100644 src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552650000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json delete mode 100644 src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json diff --git a/package-lock.json b/package-lock.json index 893173807..ab58f360d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.3", + "version": "10.27.1-rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.3", + "version": "10.27.1-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.11", + "@splitsoftware/splitio-commons": "1.16.1-rc.12", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.11", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.11.tgz", - "integrity": "sha512-w1Hv6y98PaIUCAy4DP+0l0GabagPwt+4u9Z6BsTtXlnWjkSXfgHQJnR2EjdhU5xrACdgR+x9rENm2ZSjioNebg==", + "version": "1.16.1-rc.12", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.12.tgz", + "integrity": "sha512-OOkjuR1y48SGoZ5Z3TMdPyngAv4xQJ8cK7ydUSlMwkCFU4nT3u5kfpwoafr3v+7i7K6zneDfW8z0VeIXYY8wAw==", "dependencies": { "tslib": "^2.3.1" }, @@ -8416,9 +8416,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.16.1-rc.11", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.11.tgz", - "integrity": "sha512-w1Hv6y98PaIUCAy4DP+0l0GabagPwt+4u9Z6BsTtXlnWjkSXfgHQJnR2EjdhU5xrACdgR+x9rENm2ZSjioNebg==", + "version": "1.16.1-rc.12", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.16.1-rc.12.tgz", + "integrity": "sha512-OOkjuR1y48SGoZ5Z3TMdPyngAv4xQJ8cK7ydUSlMwkCFU4nT3u5kfpwoafr3v+7i7K6zneDfW8z0VeIXYY8wAw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 6a5f4bc56..9d21f96e9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.27.1-rc.3", + "version": "10.27.1-rc.4", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.16.1-rc.11", + "@splitsoftware/splitio-commons": "1.16.1-rc.12", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/push-fallback.spec.js b/src/__tests__/browserSuites/push-fallback.spec.js index 87a1c3db6..dc8df88b9 100644 --- a/src/__tests__/browserSuites/push-fallback.spec.js +++ b/src/__tests__/browserSuites/push-fallback.spec.js @@ -20,7 +20,7 @@ import streamingPausedControlPriMessage2 from '../mocks/message.CONTROL.STREAMIN import streamingDisabledControlPriMessage from '../mocks/message.CONTROL.STREAMING_DISABLED.control_pri.1586987434950.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -66,11 +66,11 @@ const MILLIS_CREATE_CLIENT_DURING_PUSH = MILLIS_STREAMING_UP_OCCUPANCY + 50; const MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_UP_OCCUPANCY + 100; const MILLIS_STREAMING_PAUSED_CONTROL = MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH + 100; -const MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_POLLING = MILLIS_STREAMING_PAUSED_CONTROL + 100; +const MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_POLLING = MILLIS_STREAMING_PAUSED_CONTROL + 100; const MILLIS_STREAMING_RESUMED_CONTROL = MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate + 100; -const MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_RESUMED_CONTROL + 100; +const MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_PUSH = MILLIS_STREAMING_RESUMED_CONTROL + 100; -const MILLIS_STREAMING_PAUSED_CONTROL_2 = MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH + 100; +const MILLIS_STREAMING_PAUSED_CONTROL_2 = MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_PUSH + 100; const MILLIS_STREAMING_RESET_WHILE_PUSH_DOWN = MILLIS_STREAMING_PAUSED_CONTROL_2 + 100; const MILLIS_STREAMING_RESET_WHILE_PUSH_UP = MILLIS_STREAMING_RESET_WHILE_PUSH_DOWN + settings.scheduler.featuresRefreshRate; const MILLIS_STREAMING_DISABLED_CONTROL = MILLIS_STREAMING_RESET_WHILE_PUSH_UP + 100; @@ -88,11 +88,11 @@ const MILLIS_DESTROY = MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.fe * 0.55 secs: create a new client while streaming -> initial fetch (/memberships/marcio), auth, SSE connection and syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) * 0.6 secs: SPLIT_UPDATE event -> /splitChanges * 0.7 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) - * 0.8 secs: MEMBERSHIP_MS_UPDATE event ignored + * 0.8 secs: MEMBERSHIPS_MS_UPDATE event ignored * 0.9 secs: periodic fetch due to polling (/splitChanges) * 0.95 secs: periodic fetch due to polling (/memberships/nicolas, /memberships/marcio) * 1.0 secs: Streaming up (CONTROL event) -> syncAll (/splitChanges, /memberships/nicolas, /memberships/marcio) - * 1.1 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas, /memberships/marcio + * 1.1 secs: Unbounded MEMBERSHIPS_MS_UPDATE event -> /memberships/nicolas, /memberships/marcio * 1.2 secs: Streaming down (CONTROL event) -> fetch due to fallback to polling (/splitChanges, /memberships/nicolas, /memberships/marcio) * 1.3 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll and stop polling * 1.5 secs: STREAMING_RESET control event -> auth, SSE connection, syncAll @@ -110,7 +110,7 @@ export function testFallback(fetchMock, assert) { // mock SSE open and message events setMockListener((eventSourceInstance) => { - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; assert.equals(eventSourceInstance.url, expectedSSEurl, 'EventSource URL is the expected'); setTimeout(() => { @@ -136,7 +136,7 @@ export function testFallback(fetchMock, assert) { secondClient = splitio.client(secondUserKey); setMockListener((eventSourceInstance) => { - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_MjE0MTkxOTU2Mg%3D%3D_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolasAndMarcio.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolasAndMarcio.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; assert.equals(eventSourceInstance.url, expectedSSEurl, 'new EventSource URL is the expected'); eventSourceInstance.emitOpen(); @@ -155,7 +155,7 @@ export function testFallback(fetchMock, assert) { setTimeout(() => { assert.equal(eventSourceInstance.readyState, EventSourceMock.OPEN, 'EventSource connection keeps opened after PUSH_SUBSYSTEM_DOWN (STREAMING_PAUSED event)'); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_POLLING - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIP_MS_UPDATE event while polling, to check that we are ignoring it + }, MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_POLLING - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIPS_MS_UPDATE event while polling, to check that we are ignoring it setTimeout(() => { eventSourceInstance.emitMessage(streamingResumedControlPriMessage); @@ -167,7 +167,7 @@ export function testFallback(fetchMock, assert) { assert.equal(client.getTreatment('real_split'), 'on', 'evaluation with updated segment'); }); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIP_MS_UPDATE event + }, MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_PUSH - MILLIS_CREATE_CLIENT_DURING_PUSH); // send a MEMBERSHIPS_MS_UPDATE event setTimeout(() => { eventSourceInstance.emitMessage(streamingPausedControlPriMessage2); @@ -271,10 +271,10 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: membershipsNicolasMock1 }); fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); - // fetch due to MEMBERSHIP_MS_UPDATE event + // fetch due to MEMBERSHIPS_MS_UPDATE event fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_MEMBERSHIP_MS_UPDATE_EVENT_DURING_PUSH), 'sync due to MEMBERSHIP_MS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_MEMBERSHIPS_MS_UPDATE_EVENT_DURING_PUSH), 'sync due to MEMBERSHIPS_MS_UPDATE event'); return { status: 200, body: membershipsNicolasMock2 }; }); fetchMock.getOnce(url(settings, '/memberships/marcio%40split.io'), { status: 200, body: membershipsMarcio }); diff --git a/src/__tests__/browserSuites/push-initialization-retries.spec.js b/src/__tests__/browserSuites/push-initialization-retries.spec.js index 49dc6295e..027ceceaa 100644 --- a/src/__tests__/browserSuites/push-initialization-retries.spec.js +++ b/src/__tests__/browserSuites/push-initialization-retries.spec.js @@ -114,7 +114,7 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { let start, splitio, client, ready = false; const expectedTimeToSSEsuccess = (settings.scheduler.pushRetryBackoffBase * Math.pow(2, 0) + settings.scheduler.pushRetryBackoffBase * Math.pow(2, 1)); - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; let sseattempts = 0; setMockListener(function (eventSourceInstance) { assert.equal(eventSourceInstance.url, expectedSSEurl, 'SSE url is correct'); diff --git a/src/__tests__/browserSuites/push-synchronization-retries.spec.js b/src/__tests__/browserSuites/push-synchronization-retries.spec.js index 65df72b41..a24236503 100644 --- a/src/__tests__/browserSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/browserSuites/push-synchronization-retries.spec.js @@ -7,7 +7,7 @@ import membershipsMarcio from '../mocks/memberships.marcio@split.io.json'; import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json'; import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; -import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json'; +import mySegmentsUpdateMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; @@ -48,8 +48,8 @@ const MILLIS_RETRY_FOR_FIRST_SPLIT_UPDATE_EVENT = 300; const MILLIS_SECOND_SPLIT_UPDATE_EVENT = 400; -const MILLIS_MYSEGMENTS_UPDATE_V3_EVENT = 500; -const MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT = 1200; +const MILLIS_MEMBERSHIPS_MS_UPDATE = 500; +const MILLIS_THIRD_RETRY_FOR_MEMBERSHIPS_MS_UPDATE = 1200; const MILLIS_SPLIT_KILL_EVENT = 1300; const MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT = 2000; @@ -64,10 +64,10 @@ const MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT = 2000; * * 0.4 secs: SPLIT_UPDATE event with old changeNumber -> SDK_UPDATE not triggered * - * 0.5 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/marcio@split.io OK, /memberships/nicolas@split.io: network error - * 0.6 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io retry: invalid JSON response - * 0.8 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io: server error - * 1.2 secs: Unbounded MEMBERSHIP_MS_UPDATE event -> /memberships/nicolas@split.io retry: success -> SDK_UPDATE triggered + * 0.5 secs: Unbounded MEMBERSHIPS_MS_UPDATE event -> /memberships/marcio@split.io OK, /memberships/nicolas@split.io: network error + * 0.6 secs: Unbounded MEMBERSHIPS_MS_UPDATE event -> /memberships/nicolas@split.io retry: invalid JSON response + * 0.8 secs: Unbounded MEMBERSHIPS_MS_UPDATE event -> /memberships/nicolas@split.io: server error + * 1.2 secs: Unbounded MEMBERSHIPS_MS_UPDATE event -> /memberships/nicolas@split.io retry: success -> SDK_UPDATE triggered * * 1.3 secs: SPLIT_KILL event -> /splitChanges: outdated response -> SDK_UPDATE triggered although fetches fail * 1.4 secs: SPLIT_KILL event -> /splitChanges retry: network error @@ -88,7 +88,7 @@ export function testSynchronizationRetries(fetchMock, assert) { setMockListener(function (eventSourceInstance) { start = Date.now(); - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; assert.equals(eventSourceInstance.url, expectedSSEurl, 'EventSource URL is the expected'); /* events on first SSE connection */ @@ -114,11 +114,11 @@ export function testSynchronizationRetries(fetchMock, assert) { assert.equal(client.getTreatment('splitters'), 'off', 'evaluation with initial MySegments list'); client.once(client.Event.SDK_UPDATE, () => { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'SDK_UPDATE due to MEMBERSHIP_MS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MEMBERSHIPS_MS_UPDATE), 'SDK_UPDATE due to MEMBERSHIPS_MS_UPDATE event'); assert.equal(client.getTreatment('splitters'), 'on', 'evaluation with updated MySegments list'); }); eventSourceInstance.emitMessage(mySegmentsUpdateMessage); - }, MILLIS_MYSEGMENTS_UPDATE_V3_EVENT); // send a MEMBERSHIP_MS_UPDATE event with a new changeNumber after 0.4 seconds + }, MILLIS_MEMBERSHIPS_MS_UPDATE); // send a MEMBERSHIPS_MS_UPDATE event with a new changeNumber after 0.4 seconds setTimeout(() => { client.once(client.Event.SDK_UPDATE, () => { @@ -163,16 +163,16 @@ export function testSynchronizationRetries(fetchMock, assert) { return { status: 200, body: splitChangesMock3 }; }); - // fetch due to first MEMBERSHIP_MS_UPDATE event + // fetch due to first MEMBERSHIPS_MS_UPDATE event fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { throws: new TypeError('Network error') }); - // fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail + // fetch retry for MEMBERSHIPS_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON response - // fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail + // fetch retry for MEMBERSHIPS_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 500, body: 'server error' }); - // second fetch retry for MEMBERSHIP_MS_UPDATE event, due to previous fail + // second fetch retry for MEMBERSHIPS_MS_UPDATE event, due to previous fail fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), function () { const lapse = Date.now() - start; - assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MYSEGMENT_UPDATE_EVENT), 'sync second retry for MEMBERSHIP_MS_UPDATE event'); + assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_MEMBERSHIPS_MS_UPDATE), 'sync second retry for MEMBERSHIPS_MS_UPDATE event'); return { status: 200, body: membershipsNicolasMock2 }; }); diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index ad9400e1a..783197f47 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -9,12 +9,12 @@ import splitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552649999.json import oldSplitUpdateMessage from '../mocks/message.SPLIT_UPDATE.1457552620999.json'; import splitKillMessage from '../mocks/message.SPLIT_KILL.1457552650000.json'; -import unboundedMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json'; -import boundedZlibMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json'; -import keylistGzipMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json'; -import segmentRemovalMessage from '../mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; -import unboundedMyLargeSegmentsMessage from '../mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; -import myLargeSegmentRemovalMessage from '../mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552650000.json'; +import boundedZlibMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json'; +import keylistGzipMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json'; +import segmentRemovalMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedMyLargeSegmentsMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; +import myLargeSegmentRemovalMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; @@ -57,14 +57,14 @@ const MILLIS_SPLIT_KILL_EVENT = 400; const MILLIS_NEW_CLIENT = 500; const MILLIS_SECOND_SSE_OPEN = 600; const MILLIS_MORE_CLIENTS = 700; -const MILLIS_UNBOUNDED_FETCH = 800; -const MILLIS_BOUNDED_FALLBACK = 900; -const MILLIS_KEYLIST_FALLBACK = 1000; -const MILLIS_BOUNDED = 1100; -const MILLIS_KEYLIST = 1200; -const MILLIS_SEGMENT_REMOVAL = 1300; -const MILLIS_UNBOUNDED_FETCH_LS = 1400; -const MILLIS_SEGMENT_REMOVAL_LS = 1800; +const MILLIS_MEMBERSHIPS_MS_UPDATE_UNBOUNDED_FETCH = 800; +const MILLIS_MEMBERSHIPS_MS_UPDATE_BOUNDED_FALLBACK = 900; +const MILLIS_MEMBERSHIPS_MS_UPDATE_KEYLIST_FALLBACK = 1000; +const MILLIS_MEMBERSHIPS_MS_UPDATE_BOUNDED = 1100; +const MILLIS_MEMBERSHIPS_MS_UPDATE_KEYLIST = 1200; +const MILLIS_MEMBERSHIPS_MS_UPDATE_SEGMENT_REMOVAL = 1300; +const MILLIS_MEMBERSHIPS_LS_UPDATE_UNBOUNDED_FETCH = 1400; +const MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL = 1800; /** * Sequence of calls: @@ -76,15 +76,16 @@ const MILLIS_SEGMENT_REMOVAL_LS = 1800; * 0.5 secs: creates a new client -> new auth and SSE connection * 0.6 secs: SSE connection opened -> syncAll (/splitChanges, /memberships/*) * 0.7 secs: creates more clients - * 0.8 secs: MEMBERSHIP_MS_UPDATE UnboundedFetchRequest event. - * 0.9 secs: MEMBERSHIP_MS_UPDATE BoundedFetchRequest event error --> UnboundedFetchRequest. - * 1.0 secs: MEMBERSHIP_MS_UPDATE KeyList event error --> UnboundedFetchRequest. - * 1.1 secs: MEMBERSHIP_MS_UPDATE BoundedFetchRequest event. - * 1.2 secs: MEMBERSHIP_MS_UPDATE KeyList event. - * 1.3 secs: MEMBERSHIP_MS_UPDATE SegmentRemoval event. - * 1.4 secs: MEMBERSHIP_LS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) - * 1.641 secs: /memberships/* fetch due to unbounded MEMBERSHIP_LS_UPDATE event -> SDK_UPDATE event - * 1.8 secs: MEMBERSHIP_LS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 0.8 secs: MEMBERSHIPS_MS_UPDATE UnboundedFetchRequest event. + * 0.9 secs: MEMBERSHIPS_MS_UPDATE BoundedFetchRequest event error --> UnboundedFetchRequest. + * 1.0 secs: MEMBERSHIPS_MS_UPDATE KeyList event error --> UnboundedFetchRequest. + * 1.1 secs: MEMBERSHIPS_MS_UPDATE BoundedFetchRequest event. + * 1.2 secs: MEMBERSHIPS_MS_UPDATE KeyList event. + * 1.3 secs: MEMBERSHIPS_MS_UPDATE SegmentRemoval event. +// WITH CN IN THE RESPONSE + * 1.4 secs: MEMBERSHIPS_LS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) + * 1.641 secs: /memberships/* fetch due to unbounded MEMBERSHIPS_LS_UPDATE event -> SDK_UPDATE event + * 1.8 secs: MEMBERSHIPS_LS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { assert.plan(34); @@ -94,7 +95,7 @@ export function testSynchronization(fetchMock, assert) { // mock SSE open and message events setMockListener((eventSourceInstance) => { - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolas.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; assert.equals(eventSourceInstance.url, expectedSSEurl, 'EventSource URL is the expected'); /* events on first SSE connection */ @@ -133,7 +134,7 @@ export function testSynchronization(fetchMock, assert) { otherClient = splitio.client(otherUserKey); setMockListener((eventSourceInstance) => { - const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_MjE0MTkxOTU2Mg%3D%3D_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_NTcwOTc3MDQx_mySegments,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_splits,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolasAndMarcio.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; + const expectedSSEurl = `${url(settings, '/sse')}?channels=NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_control,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_flags,NzM2MDI5Mzc0_NDEzMjQ1MzA0Nw%3D%3D_memberships,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_pri,%5B%3Foccupancy%3Dmetrics.publishers%5Dcontrol_sec&accessToken=${authPushEnabledNicolasAndMarcio.token}&v=1.1&heartbeats=true&SplitSDKVersion=${settings.version}&SplitSDKClientKey=h-1>`; assert.equals(eventSourceInstance.url, expectedSSEurl, 'new EventSource URL is the expected'); /* events on second SSE connection */ @@ -152,17 +153,17 @@ export function testSynchronization(fetchMock, assert) { setTimeout(() => { eventSourceInstance.emitMessage(unboundedMessage); - }, MILLIS_UNBOUNDED_FETCH - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_UNBOUNDED_FETCH - MILLIS_MORE_CLIENTS); setTimeout(() => { const malformedMessage = { ...boundedZlibMessage, data: boundedZlibMessage.data.replace('eJxiGAX4AMd', '').replace('1457552651000', '1457552650100') }; eventSourceInstance.emitMessage(malformedMessage); - }, MILLIS_BOUNDED_FALLBACK - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_BOUNDED_FALLBACK - MILLIS_MORE_CLIENTS); setTimeout(() => { const malformedMessage = { ...keylistGzipMessage, data: keylistGzipMessage.data.replace('H4sIAAAAAAA', '').replace('1457552652000', '1457552650200') }; eventSourceInstance.emitMessage(malformedMessage); - }, MILLIS_KEYLIST_FALLBACK - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_KEYLIST_FALLBACK - MILLIS_MORE_CLIENTS); setTimeout(() => { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'off', 'on', 'off'], 'evaluation before bounded fetch'); @@ -170,7 +171,7 @@ export function testSynchronization(fetchMock, assert) { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'off', 'on', 'on'], 'evaluation after bounded fetch'); }); eventSourceInstance.emitMessage(boundedZlibMessage); - }, MILLIS_BOUNDED - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_BOUNDED - MILLIS_MORE_CLIENTS); setTimeout(() => { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'off', 'on', 'on'], 'evaluation before keylist message'); @@ -182,7 +183,7 @@ export function testSynchronization(fetchMock, assert) { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'on', 'off', 'on'], 'evaluation after keylist message (removed key)'); }); eventSourceInstance.emitMessage(keylistGzipMessage); - }, MILLIS_KEYLIST - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_KEYLIST - MILLIS_MORE_CLIENTS); setTimeout(() => { assert.deepEqual(sharedClients.map(c => c.getTreatment('splitters')), ['off', 'on', 'off', 'on'], 'evaluation before segment removal'); @@ -191,7 +192,7 @@ export function testSynchronization(fetchMock, assert) { }); eventSourceInstance.emitMessage(segmentRemovalMessage); - }, MILLIS_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_MS_UPDATE_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); setTimeout(() => { assert.equal(client.getTreatment('in_large_segment'), 'no', 'evaluation before myLargeSegment fetch'); @@ -205,7 +206,7 @@ export function testSynchronization(fetchMock, assert) { }); eventSourceInstance.emitMessage(unboundedMyLargeSegmentsMessage); - }, MILLIS_UNBOUNDED_FETCH_LS - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_LS_UPDATE_UNBOUNDED_FETCH - MILLIS_MORE_CLIENTS); setTimeout(() => { assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation before large segment removal'); @@ -230,7 +231,7 @@ export function testSynchronization(fetchMock, assert) { }); eventSourceInstance.emitMessage(myLargeSegmentRemovalMessage); - }, MILLIS_SEGMENT_REMOVAL_LS - MILLIS_MORE_CLIENTS); + }, MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); }); }, MILLIS_MORE_CLIENTS - MILLIS_NEW_CLIENT); @@ -319,7 +320,7 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: membershipsMarcio }; }); - // 3 unbounded fetch for MEMBERSHIP_MS_UPDATE + 1 unbounded fetch for MEMBERSHIP_LS_UPDATE + // 3 unbounded fetch for MEMBERSHIPS_MS_UPDATE + 1 unbounded fetch for MEMBERSHIPS_LS_UPDATE fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 3 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: membershipsNicolasMock2 }; @@ -330,7 +331,7 @@ export function testSynchronization(fetchMock, assert) { return { status: 200, body: membershipsMarcio }; }); - // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MEMBERSHIP_MS_UPDATE + 1 unbounded fetch for MEMBERSHIP_LS_UPDATE + // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MEMBERSHIPS_MS_UPDATE + 1 unbounded fetch for MEMBERSHIPS_LS_UPDATE fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); fetchMock.get({ url: url(settings, '/memberships/key1'), repeat: 6 }, { status: 200, body: { ms: {} } }); fetchMock.get({ url: url(settings, '/memberships/key3'), repeat: 6 }, { status: 200, body: { ms: { k: [{ n: 'splitters' }] } } }); diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 9ed15d8a0..8bc7dada8 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -199,7 +199,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships as soon as it received a new Split with segments.'); }, 0); - setTimeout(() => { // Nasty ugly crap to avoid listening to the update coming from mySegment calls. + setTimeout(() => { // Nasty ugly code to avoid listening to the update coming from membership calls. client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with no segments (removed the matcher we fetched on the previous one), it should stop the producer and not trigger more requests. @@ -283,7 +283,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 2 * CLIENTS_COUNT - 1, 'It should have tried to synchronize memberships as soon as it received a new Split with segments.'); }, 0); - setTimeout(() => { // Nasty ugly crap to avoid listening to the update coming from mySegment calls. + setTimeout(() => { // Nasty ugly code to avoid listening to the update coming from membership calls. client.once(client.Event.SDK_UPDATE, () => { setTimeout(() => { // This update left us in an state with no segments (removed the matcher we fetched on the previous one), it should stop the producer and not trigger more requests. diff --git a/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.json b/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.json index 3930e1d09..d7b68e966 100644 --- a/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.json +++ b/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.json @@ -1,5 +1,5 @@ { "pushEnabled": true, - "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjVZOU05US45QnJtR0EiLCJ0eXAiOiJKV1QifQ.eyJ4LWFibHktY2FwYWJpbGl0eSI6IntcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X05UY3dPVGMzTURReF9teVNlZ21lbnRzXCI6W1wic3Vic2NyaWJlXCJdLFwiTnpNMk1ESTVNemMwX05ERXpNalExTXpBME53PT1fc3BsaXRzXCI6W1wic3Vic2NyaWJlXCJdLFwiY29udHJvbF9wcmlcIjpbXCJzdWJzY3JpYmVcIixcImNoYW5uZWwtbWV0YWRhdGE6cHVibGlzaGVyc1wiXSxcImNvbnRyb2xfc2VjXCI6W1wic3Vic2NyaWJlXCIsXCJjaGFubmVsLW1ldGFkYXRhOnB1Ymxpc2hlcnNcIl19IiwieC1hYmx5LWNsaWVudElkIjoiY2xpZW50SWQiLCJleHAiOjE1ODY5MTU3NjksImlhdCI6MTU4NjkxMjE2OX0.iq6k65WcCx8s-yqDj4FpIOUEP6-G3VdB-NLhR0fXQUw", + "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjVZOU05US5MZzMtZWciLCJ0eXAiOiJKV1QifQ.eyJ4LWFibHktY2FwYWJpbGl0eSI6IntcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X2NvbnRyb2xcIjpbXCJzdWJzY3JpYmVcIl0sXCJOek0yTURJNU16YzBfTkRFek1qUTFNekEwTnc9PV9mbGFnc1wiOltcInN1YnNjcmliZVwiXSxcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X21lbWJlcnNoaXBzXCI6W1wic3Vic2NyaWJlXCJdLFwiY29udHJvbF9wcmlcIjpbXCJzdWJzY3JpYmVcIixcImNoYW5uZWwtbWV0YWRhdGE6cHVibGlzaGVyc1wiXSxcImNvbnRyb2xfc2VjXCI6W1wic3Vic2NyaWJlXCIsXCJjaGFubmVsLW1ldGFkYXRhOnB1Ymxpc2hlcnNcIl19IiwieC1hYmx5LWNsaWVudElkIjoiY2xpZW50SWQiLCJleHAiOjE3MjUzODM2NDEsImlhdCI6MTcyNTM4MDA0MX0.Qqyixo2ZG-2tAkxjad7O-iphK3DVK5_xICypbIDh3IM", "connDelay": 0 } \ No newline at end of file diff --git a/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json b/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json index 8ed677bbe..e266b5928 100644 --- a/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json +++ b/src/__tests__/mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json @@ -1,5 +1,5 @@ { "pushEnabled": true, - "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjVZOU05US45QnJtR0EiLCJ0eXAiOiJKV1QifQ.eyJ4LWFibHktY2FwYWJpbGl0eSI6IntcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X01qRTBNVGt4T1RVMk1nPT1fbXlTZWdtZW50c1wiOltcInN1YnNjcmliZVwiXSxcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X05UY3dPVGMzTURReF9teVNlZ21lbnRzXCI6W1wic3Vic2NyaWJlXCJdLFwiTnpNMk1ESTVNemMwX05ERXpNalExTXpBME53PT1fc3BsaXRzXCI6W1wic3Vic2NyaWJlXCJdLFwiY29udHJvbF9wcmlcIjpbXCJzdWJzY3JpYmVcIixcImNoYW5uZWwtbWV0YWRhdGE6cHVibGlzaGVyc1wiXSxcImNvbnRyb2xfc2VjXCI6W1wic3Vic2NyaWJlXCIsXCJjaGFubmVsLW1ldGFkYXRhOnB1Ymxpc2hlcnNcIl19IiwieC1hYmx5LWNsaWVudElkIjoiY2xpZW50SWQiLCJleHAiOjE1ODY5MTYyMDAsImlhdCI6MTU4NjkxMjYwMH0.iq6k65WcCx8s-yqDj4FpIOUEP6-G3VdB-NLhR0fXQUw", + "token": "eyJhbGciOiJIUzI1NiIsImtpZCI6IjVZOU05US5MZzMtZWciLCJ0eXAiOiJKV1QifQ.eyJ4LWFibHktY2FwYWJpbGl0eSI6IntcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X2NvbnRyb2xcIjpbXCJzdWJzY3JpYmVcIl0sXCJOek0yTURJNU16YzBfTkRFek1qUTFNekEwTnc9PV9mbGFnc1wiOltcInN1YnNjcmliZVwiXSxcIk56TTJNREk1TXpjMF9OREV6TWpRMU16QTBOdz09X21lbWJlcnNoaXBzXCI6W1wic3Vic2NyaWJlXCJdLFwiY29udHJvbF9wcmlcIjpbXCJzdWJzY3JpYmVcIixcImNoYW5uZWwtbWV0YWRhdGE6cHVibGlzaGVyc1wiXSxcImNvbnRyb2xfc2VjXCI6W1wic3Vic2NyaWJlXCIsXCJjaGFubmVsLW1ldGFkYXRhOnB1Ymxpc2hlcnNcIl19IiwieC1hYmx5LWNsaWVudElkIjoiY2xpZW50SWQiLCJleHAiOjE3MjUzODk4MjgsImlhdCI6MTcyNTM4NjIyOH0.KaEa6CjNM489dLgHxDbL8RP1DUFCMtkGLI6W3JZcTTs", "connDelay": 0 } \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..baa24fe3f --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_LS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json new file mode 100644 index 000000000..99c839cb0 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_LS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.GZIP.1457552651000.json new file mode 100644 index 000000000..59da6ea6f --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.GZIP.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json new file mode 100644 index 000000000..fe4ff5a38 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json new file mode 100644 index 000000000..320522553 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552652000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json new file mode 100644 index 000000000..23e582775 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json new file mode 100644 index 000000000..dcce251be --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552640000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552640000,\\\"u\\\": 0,\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552650000.json new file mode 100644 index 000000000..a69df9dd9 --- /dev/null +++ b/src/__tests__/mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1457552650000.json @@ -0,0 +1,4 @@ +{ + "type": "message", + "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIPS_MS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" +} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json deleted file mode 100644 index 28540e802..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_LS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\"}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json deleted file mode 100644 index 9b3493588..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_LS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"i\\\":300,\\\"h\\\":1,\\\"s\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json deleted file mode 100644 index 7f4e53b31..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.GZIP.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 1,\\\"u\\\": 1,\\\"d\\\":\\\"H4sIAAAAAAAA/2JABxzYeIxQLguYFIBLN8Bl4EABjc+EzOnAsA4QAAD//8YBvWeAAAAA\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json deleted file mode 100644 index 88dae3cb7..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552651000,\\\"n\\\":[],\\\"c\\\": 2,\\\"u\\\": 1,\\\"d\\\":\\\"eJxiGAX4AMdAO2AU4AeMA+2AAQACA+0AuoORGMvDBDANtAPoDBQG2gGDGQz16pRloB0wCkbBKBgFo4As0EBYyZCqoojwDwEACAAA//+W/QFR\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json deleted file mode 100644 index c9cb0b904..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.KEYLIST.GZIP.1457552652000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552652000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 1,\\\"u\\\": 2,\\\"d\\\":\\\"H4sIAAAAAAAA/wTAsRHDUAgD0F2ofwEIkPAqPhdZIW0uu/v97GPXHU004ULuMGrYR6XUbIjlXULPPse+dt1yhJibBODjrTmj3GJ4emduuDDP/w0AAP//18WLsl0AAAA=\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json deleted file mode 100644 index 55def7a16..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552653000,\\\"n\\\":[\\\"splitters\\\"],\\\"c\\\": 0,\\\"u\\\": 3,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json deleted file mode 100644 index ef1a218c6..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552640000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552640000,\\\"u\\\": 0,\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json b/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json deleted file mode 100644 index 663d89c6b..000000000 --- a/src/__tests__/mocks/message.MEMBERSHIP_MS_UPDATE.UNBOUNDED.1457552650000.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "type": "message", - "data": "{\"data\":\"{\\\"type\\\":\\\"MEMBERSHIP_MS_UPDATE\\\",\\\"cn\\\":1457552650000,\\\"n\\\":[],\\\"c\\\": 0,\\\"u\\\": 0,\\\"d\\\":\\\"\\\",\\\"h\\\":0}\"}" -} \ No newline at end of file diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 22f2f5139..e6877bf0d 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.27.1-rc.3'; +export const packageVersion = '10.27.1-rc.4'; From cdf411f48de39bb9692a97b82b7bd1594c9420cc Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 3 Sep 2024 20:50:33 -0300 Subject: [PATCH 23/58] Test updates --- .github/workflows/ci-cd.yml | 4 +-- .../push-synchronization-retries.spec.js | 2 +- .../push-synchronization.spec.js | 36 +++++++++++-------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 982a7a3a3..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_unify_endpoint' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_unify_endpoint' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: diff --git a/src/__tests__/browserSuites/push-synchronization-retries.spec.js b/src/__tests__/browserSuites/push-synchronization-retries.spec.js index a24236503..db0374aa7 100644 --- a/src/__tests__/browserSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/browserSuites/push-synchronization-retries.spec.js @@ -76,7 +76,7 @@ const MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT = 2000; * (we destroy the client here, to assert that all scheduled tasks are clean) */ export function testSynchronizationRetries(fetchMock, assert) { - // Force the backoff base of UpdateWorkers, from 10 secs to 100 ms, to reduce test time + // Force the backoff base of UpdateWorkers, from 1 sec to 100 ms, to reduce test time Backoff.__TEST__BASE_MILLIS = 100; assert.plan(17); diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 783197f47..25e7e93d7 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -13,12 +13,13 @@ import unboundedMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.UNBOUNDED.1 import boundedZlibMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.BOUNDED.ZLIB.1457552651000.json'; import keylistGzipMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.KEYLIST.GZIP.1457552652000.json'; import segmentRemovalMessage from '../mocks/message.MEMBERSHIPS_MS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; -import unboundedMyLargeSegmentsMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; -import myLargeSegmentRemovalMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; +import unboundedLSMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.UNBOUNDED.DELAY.1457552650000.json'; +import segmentRemovalLSMessage from '../mocks/message.MEMBERSHIPS_LS_UPDATE.SEGMENT_REMOVAL.1457552653000.json'; import authPushEnabledNicolas from '../mocks/auth.pushEnabled.nicolas@split.io.json'; import authPushEnabledNicolasAndMarcio from '../mocks/auth.pushEnabled.nicolas@split.io.marcio@split.io.json'; +import { Backoff } from '@splitsoftware/splitio-commons/src/utils/Backoff'; import { nearlyEqual, url, hasNoCacheHeader } from '../testUtils'; // Replace original EventSource with mock @@ -64,7 +65,8 @@ const MILLIS_MEMBERSHIPS_MS_UPDATE_BOUNDED = 1100; const MILLIS_MEMBERSHIPS_MS_UPDATE_KEYLIST = 1200; const MILLIS_MEMBERSHIPS_MS_UPDATE_SEGMENT_REMOVAL = 1300; const MILLIS_MEMBERSHIPS_LS_UPDATE_UNBOUNDED_FETCH = 1400; -const MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL = 1800; +const MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL = 1900; +const EXPECTED_DELAY_AND_BACKOFF = 241 + 100; /** * Sequence of calls: @@ -82,12 +84,14 @@ const MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL = 1800; * 1.1 secs: MEMBERSHIPS_MS_UPDATE BoundedFetchRequest event. * 1.2 secs: MEMBERSHIPS_MS_UPDATE KeyList event. * 1.3 secs: MEMBERSHIPS_MS_UPDATE SegmentRemoval event. -// WITH CN IN THE RESPONSE * 1.4 secs: MEMBERSHIPS_LS_UPDATE UnboundedFetchRequest event, with 241 ms delay for 'nicolas@split.io' (hash('nicolas@split.io') % 300) - * 1.641 secs: /memberships/* fetch due to unbounded MEMBERSHIPS_LS_UPDATE event -> SDK_UPDATE event - * 1.8 secs: MEMBERSHIPS_LS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event + * 1.641 secs: /memberships/* fetch due to unbounded MEMBERSHIPS_LS_UPDATE event, with an old changeNumber + * 1.741 secs: /memberships/* fetch due to unbounded MEMBERSHIPS_LS_UPDATE event, with the target changeNumber -> SDK_UPDATE event + * 1.9 secs: MEMBERSHIPS_LS_UPDATE SegmentRemoval event -> SPLIT_UPDATE event */ export function testSynchronization(fetchMock, assert) { + // Force the backoff base of UpdateWorkers to reduce test time + Backoff.__TEST__BASE_MILLIS = 100; assert.plan(34); fetchMock.reset(); @@ -198,14 +202,13 @@ export function testSynchronization(fetchMock, assert) { assert.equal(client.getTreatment('in_large_segment'), 'no', 'evaluation before myLargeSegment fetch'); const timestampUnboundEvent = Date.now(); - const EXPECTED_DELAY = 241; client.once(client.Event.SDK_UPDATE, () => { - assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY), 'SDK_UPDATE after fetching memberships with a delay'); + assert.true(nearlyEqual(Date.now() - timestampUnboundEvent, EXPECTED_DELAY_AND_BACKOFF), 'SDK_UPDATE after fetching memberships with a delay'); assert.equal(client.getTreatment('in_large_segment'), 'yes', 'evaluation after myLargeSegment fetch'); }); - eventSourceInstance.emitMessage(unboundedMyLargeSegmentsMessage); + eventSourceInstance.emitMessage(unboundedLSMessage); }, MILLIS_MEMBERSHIPS_LS_UPDATE_UNBOUNDED_FETCH - MILLIS_MORE_CLIENTS); setTimeout(() => { @@ -225,12 +228,14 @@ export function testSynchronization(fetchMock, assert) { client.destroy().then(() => { assert.equal(client.getTreatment('whitelist'), 'control', 'evaluation returns control for main client if it is destroyed'); assert.equal(eventSourceInstance.readyState, EventSourceMock.CLOSED, 'streaming is closed after destroy'); + + Backoff.__TEST__BASE_MILLIS = undefined; assert.end(); }); }); }); - eventSourceInstance.emitMessage(myLargeSegmentRemovalMessage); + eventSourceInstance.emitMessage(segmentRemovalLSMessage); }, MILLIS_MEMBERSHIPS_LS_UPDATE_SEGMENT_REMOVAL - MILLIS_MORE_CLIENTS); }); }, MILLIS_MORE_CLIENTS - MILLIS_NEW_CLIENT); @@ -321,15 +326,16 @@ export function testSynchronization(fetchMock, assert) { }); // 3 unbounded fetch for MEMBERSHIPS_MS_UPDATE + 1 unbounded fetch for MEMBERSHIPS_LS_UPDATE - fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 3 }, function (url, opts) { - if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); - return { status: 200, body: membershipsNicolasMock2 }; - }); - fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: { ...membershipsNicolasMock2, ls: { k: [{ n: 'employees' }, { n: 'splitters' }] } } }); fetchMock.get({ url: url(settings, '/memberships/marcio%40split.io'), repeat: 4 }, function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); return { status: 200, body: membershipsMarcio }; }); + fetchMock.get({ url: url(settings, '/memberships/nicolas%40split.io'), repeat: 3 }, function (url, opts) { + if (!hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); + return { status: 200, body: membershipsNicolasMock2 }; + }); + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: { ms: { k: [{ n: 'developers' }, { n: 'engineers' }] }, ls: { k: [], cn: 1457552640000 } } }); // not target changeNumber + fetchMock.getOnce(url(settings, '/memberships/nicolas%40split.io'), { status: 200, body: { ms: { k: [{ n: 'developers' }, { n: 'engineers' }] }, ls: { k: [{ n: 'employees' }, { n: 'splitters' }], cn: 1457552650000 } } }); // target changeNumber // initial fetch of memberships for other clients + sync all after third SSE opened + 3 unbounded fetch for MEMBERSHIPS_MS_UPDATE + 1 unbounded fetch for MEMBERSHIPS_LS_UPDATE fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), { status: 200, body: { splits: [], since: 1457552650000, till: 1457552650000 } }); From 654e77248cf7e72b244706ac85d7e35d021bd13c Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 16 Sep 2024 17:54:00 -0300 Subject: [PATCH 24/58] Update mock --- src/__tests__/mocks/splitchanges.since.-1.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/__tests__/mocks/splitchanges.since.-1.json b/src/__tests__/mocks/splitchanges.since.-1.json index 82ceb16d7..ee21cf9cc 100644 --- a/src/__tests__/mocks/splitchanges.since.-1.json +++ b/src/__tests__/mocks/splitchanges.since.-1.json @@ -22,8 +22,8 @@ }, "matcherType": "IN_LARGE_SEGMENT", "negate": false, - "userDefinedSegmentMatcherData": { - "segmentName": "harnessians" + "userDefinedLargeSegmentMatcherData": { + "largeSegmentName": "harnessians" }, "whitelistMatcherData": null, "unaryNumericMatcherData": null, @@ -50,8 +50,8 @@ }, "matcherType": "IN_LARGE_SEGMENT", "negate": false, - "userDefinedSegmentMatcherData": { - "segmentName": "splitters" + "userDefinedLargeSegmentMatcherData": { + "largeSegmentName": "splitters" }, "whitelistMatcherData": null, "unaryNumericMatcherData": null, From 1f3094fe17cb84e7883c4b2e5f04d48510797a2c Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 16 Sep 2024 18:14:05 -0300 Subject: [PATCH 25/58] rc --- CHANGES.txt | 5 +++++ package-lock.json | 18 +++++++++--------- package.json | 4 ++-- src/settings/defaults/version.js | 2 +- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index d609813a6..1453141e9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,3 +1,8 @@ +10.29.0 (September XX, 2024) + - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: + - Added support for targeting rules based on large segments for browsers. + - Updated some transitive dependencies for vulnerability fixes. + 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: - Added `sync.requestOptions.getHeaderOverrides` configuration option to enhance SDK HTTP request Headers for Authorization Frameworks. diff --git a/package-lock.json b/package-lock.json index c31c65505..480c9966e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.0", + "version": "10.28.1-rc.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.0", + "version": "10.28.1-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.0.tgz", - "integrity": "sha512-rvP+0LGUN92bcTytiqyVxq9UzBG5kTkIYjU7b7AU2awBUYgM0bqT3xhQ9/MJ/2fsBbqC6QIsxoKDOz9pMgbAQw==", + "version": "1.17.1-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", + "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", "dependencies": { "tslib": "^2.3.1" }, @@ -8416,9 +8416,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.0.tgz", - "integrity": "sha512-rvP+0LGUN92bcTytiqyVxq9UzBG5kTkIYjU7b7AU2awBUYgM0bqT3xhQ9/MJ/2fsBbqC6QIsxoKDOz9pMgbAQw==", + "version": "1.17.1-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", + "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index ed966a4f2..70e986c5e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.0", + "version": "10.28.1-rc.0", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.0", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 271ef6cd7..ce1bf7740 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.0'; +export const packageVersion = '10.28.1-rc.0'; From a5f8835c8cbf5bf24e1aaf1bb91234347beb7930 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 16 Sep 2024 18:15:02 -0300 Subject: [PATCH 26/58] ci-cd update for rc --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..982a7a3a3 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_unify_endpoint' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_unify_endpoint' }} strategy: matrix: environment: From f920053b8e932b40392103a47db58db6cb33374f Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 16 Sep 2024 19:18:20 -0300 Subject: [PATCH 27/58] rollback ci-cd --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 982a7a3a3..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/SDKS-8407_unify_endpoint' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/SDKS-8407_unify_endpoint' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: From 5211a8a8c1d16d5274f1e0144f1fb1cd1ca03f98 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 18 Sep 2024 12:39:21 -0300 Subject: [PATCH 28/58] Use flag spec version 1.1 for server-side --- package-lock.json | 4 ++-- package.json | 2 +- src/settings/defaults/version.js | 2 +- src/settings/node.js | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 480c9966e..a5ffa148b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.0", + "version": "10.28.1-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.0", + "version": "10.28.1-rc.1", "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "1.17.1-rc.0", diff --git a/package.json b/package.json index 70e986c5e..95344a2b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.0", + "version": "10.28.1-rc.1", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index ce1bf7740..036701e45 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.1-rc.0'; +export const packageVersion = '10.28.1-rc.1'; diff --git a/src/settings/node.js b/src/settings/node.js index e91c5a76b..f7664b3f6 100644 --- a/src/settings/node.js +++ b/src/settings/node.js @@ -6,12 +6,15 @@ import { defaults } from './defaults/node'; import { validateStorage } from './storage/node'; import { validateRuntime } from './runtime/node'; +const FLAG_SPEC_VERSION = '1.1'; + const params = { defaults, runtime: validateRuntime, storage: validateStorage, logger: validateLogger, localhost: () => LocalhostFromFile(), + flagSpec: () => FLAG_SPEC_VERSION // In Node.js the SDK ignores `config.integrations`, so a validator for integrations is not required }; From 62723ec2336d90e9b48cb68ea99c3b639bfc8b30 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 18 Sep 2024 13:20:56 -0300 Subject: [PATCH 29/58] Update server-side tests with flag spec 1.1 --- src/__tests__/destroy/node.spec.js | 4 +-- src/__tests__/errorCatching/node.spec.js | 6 ++-- .../nodeSuites/evaluations-semver.spec.js | 4 +-- .../nodeSuites/expected-treatments.spec.js | 2 +- .../nodeSuites/fetch-specific-splits.spec.js | 10 +++--- src/__tests__/nodeSuites/flag-sets.spec.js | 24 ++++++------- .../nodeSuites/impressions.debug.spec.js | 4 +-- .../nodeSuites/impressions.none.spec.js | 4 +-- src/__tests__/nodeSuites/impressions.spec.js | 4 +-- .../ip-addresses-setting.debug.spec.js | 4 +-- .../nodeSuites/ip-addresses-setting.spec.js | 4 +-- src/__tests__/nodeSuites/manager.spec.js | 2 +- .../nodeSuites/push-fallback.spec.js | 28 +++++++-------- .../nodeSuites/push-flag-sets.spec.js | 14 ++++---- .../push-initialization-nopush.spec.js | 14 ++++---- .../push-initialization-retries.spec.js | 36 +++++++++---------- .../nodeSuites/push-refresh-token.spec.js | 14 ++++---- .../push-synchronization-retries.spec.js | 18 +++++----- .../nodeSuites/push-synchronization.spec.js | 20 +++++------ src/__tests__/nodeSuites/readiness.spec.js | 4 +-- .../nodeSuites/ready-promise.spec.js | 32 ++++++++--------- src/__tests__/nodeSuites/telemetry.spec.js | 4 +-- src/__tests__/online/node.spec.js | 4 +-- 23 files changed, 130 insertions(+), 130 deletions(-) diff --git a/src/__tests__/destroy/node.spec.js b/src/__tests__/destroy/node.spec.js index 13fe4dc7c..7f9f9b541 100644 --- a/src/__tests__/destroy/node.spec.js +++ b/src/__tests__/destroy/node.spec.js @@ -17,8 +17,8 @@ import splitChangesMock1 from '../mocks/splitChanges.since.-1.till.1500492097547 import splitChangesMock2 from '../mocks/splitChanges.since.1500492097547.json'; import impressionsMock from '../mocks/impressions.json'; -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }); fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); tape('SDK destroy for NodeJS', async function (assert) { diff --git a/src/__tests__/errorCatching/node.spec.js b/src/__tests__/errorCatching/node.spec.js index dc2a3db70..b7838685a 100644 --- a/src/__tests__/errorCatching/node.spec.js +++ b/src/__tests__/errorCatching/node.spec.js @@ -21,9 +21,9 @@ const settings = settingsFactory({ streamingEnabled: false }); -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }, responseDelay); -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492097547'), { status: 200, body: splitChangesMock2 }, responseDelay); -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1500492297547'), { status: 200, body: splitChangesMock3 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492097547'), { status: 200, body: splitChangesMock2 }, responseDelay); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1500492297547'), { status: 200, body: splitChangesMock3 }, responseDelay); fetchMock.postOnce(url(settings, '/v1/metrics/config'), 200); // SDK_READY fetchMock.postOnce(url(settings, '/v1/metrics/usage'), 200); // SDK destroyed diff --git a/src/__tests__/nodeSuites/evaluations-semver.spec.js b/src/__tests__/nodeSuites/evaluations-semver.spec.js index 5f75d481f..5885a2b16 100644 --- a/src/__tests__/nodeSuites/evaluations-semver.spec.js +++ b/src/__tests__/nodeSuites/evaluations-semver.spec.js @@ -24,8 +24,8 @@ const config = { export default async function (fetchMock, assert) { - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=1675259356568', { status: 200, body: { splits: [], since: 1675259356568, till: 1675259356568 } }); const splitio = SplitFactory(config); const client = splitio.client(); diff --git a/src/__tests__/nodeSuites/expected-treatments.spec.js b/src/__tests__/nodeSuites/expected-treatments.spec.js index 918a533c8..552db56b3 100644 --- a/src/__tests__/nodeSuites/expected-treatments.spec.js +++ b/src/__tests__/nodeSuites/expected-treatments.spec.js @@ -6,7 +6,7 @@ import { url } from '../testUtils'; import splitChangesMockReal from '../mocks/splitchanges.real.json'; export default async function (config, settings, fetchMock, assert) { - fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); const splitio = SplitFactory({ ...config, diff --git a/src/__tests__/nodeSuites/fetch-specific-splits.spec.js b/src/__tests__/nodeSuites/fetch-specific-splits.spec.js index 0f67253c3..35d96d26d 100644 --- a/src/__tests__/nodeSuites/fetch-specific-splits.spec.js +++ b/src/__tests__/nodeSuites/fetch-specific-splits.spec.js @@ -23,9 +23,9 @@ export function fetchSpecificSplits(fetchMock, assert) { const queryString = queryStrings[i] || ''; let factory; - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); - fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, function () { + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(urls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, function () { factory.client().destroy().then(() => { assert.pass(`splitFilters #${i}`); }); @@ -64,8 +64,8 @@ export function fetchSpecificSplitsForFlagSets(fetchMock, assert) { let factory; const queryString = '&sets=4_valid,set_2,set_3,set_ww,set_x'; - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1457552620999' + queryString, async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1' + queryString, { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 }}); + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1457552620999' + queryString, async function () { t.pass('flag set query correctly formed'); factory.client().destroy().then(() => { t.end(); diff --git a/src/__tests__/nodeSuites/flag-sets.spec.js b/src/__tests__/nodeSuites/flag-sets.spec.js index fafbdb8cb..e8dd725e0 100644 --- a/src/__tests__/nodeSuites/flag-sets.spec.js +++ b/src/__tests__/nodeSuites/flag-sets.spec.js @@ -26,12 +26,12 @@ export default function flagSets(fetchMock, t) { let factory, manager, client = []; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1, 'only one feature flag should be added'); @@ -43,7 +43,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344&sets=set_1,set_2', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 1); @@ -54,7 +54,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344&sets=set_1,set_2', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344&sets=set_1,set_2', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 0, 'the feature flag should be removed'); @@ -79,12 +79,12 @@ export default function flagSets(fetchMock, t) { let factory, manager, client = []; // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { return { status: 200, body: splitChange2}; }); // Receive split change with 1 split belonging to set_1 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2, 'every feature flag should be added'); @@ -98,7 +98,7 @@ export default function flagSets(fetchMock, t) { }); // Receive split change with 1 split belonging to set_3 only - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602797638344', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602797638344', function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -111,7 +111,7 @@ export default function flagSets(fetchMock, t) { return { status: 200, body: splitChange0}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602798638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602798638344', async function () { // stored feature flags before update const storedFlags = manager.splits(); assert.true(storedFlags.length === 2); @@ -142,11 +142,11 @@ export default function flagSets(fetchMock, t) { mockSegmentChanges(fetchMock, new RegExp(baseUrls.sdk + '/segmentChanges/*'), []); fetchMock.post('*', 200); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344&sets=set_1', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344&sets=set_1', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_1'), {workm: 'on'}, 'only the flag in set_1 can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_2'), {}, 'only the flag in set_1 can be evaluated'); @@ -180,11 +180,11 @@ export default function flagSets(fetchMock, t) { fetchMock.post('*', 200); // Receive split change with 1 split belonging to set_1 & set_2 and one belonging to set_3 - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { return { status: 200, body: splitChange2}; }); - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1602796638344', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1602796638344', async function () { // stored feature flags before update assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_1'), {workm: 'on'}, 'all flags can be evaluated'); assert.deepEqual(client.getTreatmentsByFlagSet(key, 'set_2'), {workm: 'on'}, 'all flags can be evaluated'); diff --git a/src/__tests__/nodeSuites/impressions.debug.spec.js b/src/__tests__/nodeSuites/impressions.debug.spec.js index cfab6e7c0..9d09415c0 100644 --- a/src/__tests__/nodeSuites/impressions.debug.spec.js +++ b/src/__tests__/nodeSuites/impressions.debug.spec.js @@ -40,8 +40,8 @@ const config = { export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/impressions.none.spec.js b/src/__tests__/nodeSuites/impressions.none.spec.js index d664b6dbd..4c726bca4 100644 --- a/src/__tests__/nodeSuites/impressions.none.spec.js +++ b/src/__tests__/nodeSuites/impressions.none.spec.js @@ -39,8 +39,8 @@ const config = { export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/impressions.spec.js b/src/__tests__/nodeSuites/impressions.spec.js index 4f3b364dd..b5fb102a7 100644 --- a/src/__tests__/nodeSuites/impressions.spec.js +++ b/src/__tests__/nodeSuites/impressions.spec.js @@ -37,8 +37,8 @@ let truncatedTimeFrame; export default async function (key, fetchMock, assert) { // Mocking this specific route to make sure we only get the items we want to test from the handlers. - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); const splitio = SplitFactory(config); diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js index 2103f78c3..674873ad4 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.debug.spec.js @@ -77,8 +77,8 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { })(); // Mock GET endpoints to run client normally - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); // Mock and assert POST endpoints diff --git a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js index 49e29e505..2fbf92f12 100644 --- a/src/__tests__/nodeSuites/ip-addresses-setting.spec.js +++ b/src/__tests__/nodeSuites/ip-addresses-setting.spec.js @@ -121,8 +121,8 @@ export default function ipAddressesSettingAssertions(fetchMock, assert) { })(); // Mock GET endpoints to run client normally - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); // Mock and assert POST endpoints diff --git a/src/__tests__/nodeSuites/manager.spec.js b/src/__tests__/nodeSuites/manager.spec.js index 378ad018d..00a707dc9 100644 --- a/src/__tests__/nodeSuites/manager.spec.js +++ b/src/__tests__/nodeSuites/manager.spec.js @@ -4,7 +4,7 @@ import map from 'lodash/map'; import { url } from '../testUtils'; export default async function (settings, fetchMock, assert) { - fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=-1'), overwriteRoutes: true }, { status: 200, body: splitChangesMockReal }); const mockSplits = splitChangesMockReal; diff --git a/src/__tests__/nodeSuites/push-fallback.spec.js b/src/__tests__/nodeSuites/push-fallback.spec.js index 863e475f3..7789236a1 100644 --- a/src/__tests__/nodeSuites/push-fallback.spec.js +++ b/src/__tests__/nodeSuites/push-fallback.spec.js @@ -190,26 +190,26 @@ export function testFallback(fetchMock, assert) { }); - fetchMock.get({ url: url(settings, '/v2/auth?s=1.2'), repeat: 3 /* initial + 2 STREAMING_RESET */ }, function (url, opts) { + fetchMock.get({ url: url(settings, '/v2/auth?s=1.1'), repeat: 3 /* initial + 2 STREAMING_RESET */ }, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=-1'), { status: 200, body: { since: -1, till: 1457552620999, name: 'employees', added: [key], removed: [] } }); // extra retry due to double request (greedy fetch until since === till) fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // fetches due to first fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DOWN_OCCUPANCY + settings.scheduler.featuresRefreshRate), 'fetch due to first fallback to polling'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; @@ -217,22 +217,22 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552620999, name: 'employees', added: [], removed: [] } }); // split and segment sync due to streaming up (OCCUPANCY event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552620999'), { status: 200, body: { since: 1457552620999, till: 1457552621999, name: 'employees', added: ['other_key'], removed: [] } }); // extra retry due to double request (greedy fetch until since === till) fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_UPDATE_EVENT_DURING_PUSH), 'sync due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock2 }; }); // fetches due to second fallback to polling - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_PAUSED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to second fallback to polling'); return { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }; @@ -240,7 +240,7 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // split and segment sync due to streaming up (CONTROL event) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552621999'), { status: 200, body: { since: 1457552621999, till: 1457552621999, name: 'employees', added: [], removed: [] } }); // fetch due to SEGMENT_UPDATE event @@ -249,19 +249,19 @@ export function testFallback(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); // Fetches due to third fallback to polling (second STREAMING_PAUSED event) and two syncAll ( SSE opened twice due to two STREAMING_RESET events) - fetchMock.get({ url: url(settings, '/splitChanges?s=1.2&since=1457552649999'), repeat: 3 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.get({ url: url(settings, '/splitChanges?s=1.1&since=1457552649999'), repeat: 3 }, { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.get({ url: url(settings, '/segmentChanges/employees?since=1457552650000'), repeat: 3 }, { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); // fetches due to fourth fallback to polling due to STREAMING_DISABLED event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: { splits: [], since: 1457552649999, till: 1457552649999 } }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate), 'fetch due to fourth fallback to polling'); return { status: 200, body: splitChangesMock3 }; }); fetchMock.getOnce(url(settings, '/segmentChanges/employees?since=1457552650000'), { status: 200, body: { since: 1457552650000, till: 1457552650000, name: 'employees', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552669999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552669999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_STREAMING_DISABLED_CONTROL + settings.scheduler.featuresRefreshRate * 2), 'fetch due to third fallback to polling'); return { status: 200, body: { splits: [], since: 1457552669999, till: 1457552669999 } }; diff --git a/src/__tests__/nodeSuites/push-flag-sets.spec.js b/src/__tests__/nodeSuites/push-flag-sets.spec.js index 8cb7c0472..d8beb05ac 100644 --- a/src/__tests__/nodeSuites/push-flag-sets.spec.js +++ b/src/__tests__/nodeSuites/push-flag-sets.spec.js @@ -39,21 +39,21 @@ export function testFlagSets(fetchMock, t) { mockSegmentChanges(fetchMock, new RegExp(baseUrls.sdk + '/segmentChanges/*'), ['some-key']); fetchMock.post('*', 200); - fetchMock.get(baseUrls.auth + '/v2/auth?s=1.2', function (url, opts) { + fetchMock.get(baseUrls.auth + '/v2/auth?s=1.1', function (url, opts) { if (!opts.headers['Authorization']) t.fail('`/v2/auth` request must include `Authorization` header'); t.pass('auth success'); return { status: 200, body: authPushEnabled }; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1', function () { return { status: 200, body: { splits: [], since: -1, till: 0}}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=-1&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=-1&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: -1, till: 0 }}; }); - fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.2&since=0&sets=set_1,set_2', function () { + fetchMock.get(baseUrls.sdk + '/splitChanges?s=1.1&since=0&sets=set_1,set_2', function () { return { status: 200, body: { splits: [], since: 0, till: 1 }}; }); @@ -194,7 +194,7 @@ export function testFlagSets(fetchMock, t) { setMockListener((eventSourceInstance) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=2&sets=set_1,set_2', async function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=2&sets=set_1,set_2', async function () { assert.pass('4 - A fetch is triggered due to the SPLIT_KILL'); await client.destroy(); assert.end(); @@ -232,7 +232,7 @@ export function testFlagSets(fetchMock, t) { t.test(async (assert) => { - fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.2&since=1&sets=set_1,set_2', function () { + fetchMock.getOnce(baseUrls.sdk + '/splitChanges?s=1.1&since=1&sets=set_1,set_2', function () { assert.pass('5 - A fetch is triggered due to the SPLIT_KILL'); return { status: 200, body: { splits: [], since: 1, till: 5 }}; }); diff --git a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js index d1baa10df..b79db1f1f 100644 --- a/src/__tests__/nodeSuites/push-initialization-nopush.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-nopush.spec.js @@ -42,7 +42,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { const lapse = Date.now() - start; // using a higher error margin for Travis, due to a lower performance than local execution assert.true(nearlyEqual(lapse, 0), 'initial sync'); @@ -50,7 +50,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { }); if (fallbackToPolling) { - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0, 100), 'polling (first fetch)'); @@ -58,7 +58,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { }); } - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { assert.true(ready, 'client ready'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate, 100), 'polling (second fetch)'); @@ -80,7 +80,7 @@ function testInitializationFail(fetchMock, assert, fallbackToPolling) { export function testAuthWithPushDisabled(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce('https://auth.push-initialization-nopush/api/v2/auth?s=1.2', function (url, opts) { + fetchMock.getOnce('https://auth.push-initialization-nopush/api/v2/auth?s=1.1', function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 200, body: authPushDisabled }; @@ -93,7 +93,7 @@ export function testAuthWithPushDisabled(fetchMock, assert) { export function testAuthWith401(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 401, body: authInvalidCredentials }; @@ -106,7 +106,7 @@ export function testAuthWith401(fetchMock, assert) { export function testAuthWith400(fetchMock, assert) { assert.plan(6); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth'); return { status: 400, body: authNoUserSpecified }; @@ -131,7 +131,7 @@ export function testSSEWithNonRetryableError(fetchMock, assert) { assert.plan(7); // Auth successes - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth successes'); return { status: 200, body: authPushEnabled }; diff --git a/src/__tests__/nodeSuites/push-initialization-retries.spec.js b/src/__tests__/nodeSuites/push-initialization-retries.spec.js index b55621084..88cc30af8 100644 --- a/src/__tests__/nodeSuites/push-initialization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-initialization-retries.spec.js @@ -45,13 +45,13 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { let start, splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('first auth attempt'); return { status: 200, body: authPushBadToken }; }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { throws: new TypeError('Network error') }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); const lapse = Date.now() - start; const expected = (settings.scheduler.pushRetryBackoffBase * Math.pow(2, 0) + settings.scheduler.pushRetryBackoffBase * Math.pow(2, 1)); @@ -60,23 +60,23 @@ export function testPushRetriesDueToAuthErrors(fetchMock, assert) { }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate * 2), 'keep polling since auth success buth with push disabled'); client.destroy().then(() => { @@ -122,30 +122,30 @@ export function testPushRetriesDueToSseErrors(fetchMock, assert) { sseattempts++; }); - fetchMock.get({ url: url(settings, '/v2/auth?s=1.2'), repeat: 3 /* 3 push attempts */ }, function (url, opts) { + fetchMock.get({ url: url(settings, '/v2/auth?s=1.1'), repeat: 3 /* 3 push attempts */ }, function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); return { status: 200, body: splitChangesMock1 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { assert.true(ready, 'client ready before first polling fetch'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'fallback to polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, settings.scheduler.featuresRefreshRate), 'polling'); return { status: 200, body: splitChangesMock2 }; }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, expectedTimeToSSEsuccess), 'sync due to success SSE connection'); client.destroy().then(() => { @@ -181,10 +181,10 @@ export function testSdkDestroyWhileAuthSuccess(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { status: 200, body: authPushEnabled }, { delay: 100 }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { status: 200, body: authPushEnabled }, { delay: 100 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); setTimeout(() => { client.destroy().then(() => { @@ -219,12 +219,12 @@ export function testSdkDestroyWhileAuthRetries(fetchMock, assert) { let splitio, client, ready = false; - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { status: 200, body: authPushBadToken }); - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), { throws: new TypeError('Network error') }, { delay: 100 }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { status: 200, body: authPushBadToken }); + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), { throws: new TypeError('Network error') }, { delay: 100 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges/')}.*`), { status: 200, body: { since: 10, till: 10, name: 'segmentName', added: [], removed: [] } }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp('.*'), function (url) { assert.fail('unexpected GET request with url: ' + url); diff --git a/src/__tests__/nodeSuites/push-refresh-token.spec.js b/src/__tests__/nodeSuites/push-refresh-token.spec.js index ed030806f..b3246a2c4 100644 --- a/src/__tests__/nodeSuites/push-refresh-token.spec.js +++ b/src/__tests__/nodeSuites/push-refresh-token.spec.js @@ -77,20 +77,20 @@ export function testRefreshToken(fetchMock, assert) { }); // initial split sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); // first auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // split sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); // re-auth due to refresh token, with connDelay of 0.5 seconds - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN), 'reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -98,14 +98,14 @@ export function testRefreshToken(fetchMock, assert) { }); // split sync after SSE reopened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN + MILLIS_CONNDELAY), 'sync after SSE connection is reopened'); return { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }; }); // second re-auth due to refresh token, this time responding with pushEnabled false - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'second reauthentication for token refresh'); if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); @@ -113,7 +113,7 @@ export function testRefreshToken(fetchMock, assert) { }); // split sync after SSE closed due to push disabled - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_REFRESH_TOKEN * 2), 'sync after SSE connection is reopened a second time'); setTimeout(() => { diff --git a/src/__tests__/nodeSuites/push-synchronization-retries.spec.js b/src/__tests__/nodeSuites/push-synchronization-retries.spec.js index 147e18f3b..e1154e9d6 100644 --- a/src/__tests__/nodeSuites/push-synchronization-retries.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization-retries.spec.js @@ -126,14 +126,14 @@ export function testSynchronizationRetries(fetchMock, assert) { }); // initial auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); fetchMock.getOnce(url(settings, '/segmentChanges/splitters?since=-1'), { status: 200, body: { since: -1, till: 1457552620999, name: 'splitters', added: [key], removed: [] } } ); @@ -143,7 +143,7 @@ export function testSynchronizationRetries(fetchMock, assert) { ); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); return { status: 200, body: splitChangesMock2 }; @@ -153,9 +153,9 @@ export function testSynchronizationRetries(fetchMock, assert) { ); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { throws: new TypeError('Network error') }); // fetch retry for SPLIT_UPDATE event, due to previous fail - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_RETRY_FOR_FIRST_SPLIT_UPDATE_EVENT), 'fetch retry due to SPLIT_UPDATE event'); return { status: 200, body: splitChangesMock3 }; @@ -182,18 +182,18 @@ export function testSynchronizationRetries(fetchMock, assert) { fetchMock.getOnce(url(settings, '/segmentChanges/splitters?since=1457552640000'), { status: 200, body: { since: 1457552640000, till: 1457552640000, name: 'splitters', added: [], removed: [] } }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { assert.equal(client.getTreatment(key, 'whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SPLIT_KILL_EVENT), 'sync due to SPLIT_KILL event'); return { status: 200, body: { since: 1457552649999, till: 1457552649999, splits: [] } }; // returning old state }); // first fetch retry for SPLIT_KILL event, due to previous unexpected response (response till minor than SPLIT_KILL changeNumber) - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { status: 200, body: '{ "since": 1457552620999, "til' }); // invalid JSON // second fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), { throws: new TypeError('Network error') }); + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), { throws: new TypeError('Network error') }); // third fetch retry for SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function () { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function () { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_THIRD_RETRY_FOR_SPLIT_KILL_EVENT), 'third fetch retry due to SPLIT_KILL event'); diff --git a/src/__tests__/nodeSuites/push-synchronization.spec.js b/src/__tests__/nodeSuites/push-synchronization.spec.js index 67ee0c18c..4ee3a20de 100644 --- a/src/__tests__/nodeSuites/push-synchronization.spec.js +++ b/src/__tests__/nodeSuites/push-synchronization.spec.js @@ -215,14 +215,14 @@ export function testSynchronization(fetchMock, assert) { }); // initial auth - fetchMock.getOnce(url(settings, '/v2/auth?s=1.2'), function (url, opts) { + fetchMock.getOnce(url(settings, '/v2/auth?s=1.1'), function (url, opts) { if (!opts.headers['Authorization']) assert.fail('`/v2/auth` request must include `Authorization` header'); assert.pass('auth success'); return { status: 200, body: authPushEnabled }; }); // initial split and segment sync - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=-1'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=-1'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, 0), 'initial sync'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -239,7 +239,7 @@ export function testSynchronization(fetchMock, assert) { }); // split and segment sync after SSE opened - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { const lapse = Date.now() - start; assert.true(nearlyEqual(lapse, MILLIS_SSE_OPEN), 'sync after SSE connection is opened'); if (hasNoCacheHeader(opts)) assert.fail('request must not include `Cache-Control` header'); @@ -251,7 +251,7 @@ export function testSynchronization(fetchMock, assert) { }); // fetch due to SPLIT_UPDATE event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552620999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552620999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock3 }; }); @@ -268,14 +268,14 @@ export function testSynchronization(fetchMock, assert) { }); // fetch due to SPLIT_KILL event - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552649999'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552649999'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); assert.equal(client.getTreatment(key, 'whitelist'), 'not_allowed', 'evaluation with split killed immediately, before fetch is done'); return { status: 200, body: splitChangesMock4 }; }); // fetch due to SPLIT_UPDATE event, with an update that involves a new segment - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1457552650000'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1457552650000'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock5 }; }); @@ -286,25 +286,25 @@ export function testSynchronization(fetchMock, assert) { }); // fetch feature flags due to IFFU SPLIT_UPDATE event with wrong compress code - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694505'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694505'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock6 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with previous change number = 0 - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694506'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694506'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock7 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with previous change number !== current change number - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694526'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694526'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock8 }; }); // fetch feature flags due to IFFU SPLIT_UPDATE event with ARCHIVED feature flag - fetchMock.getOnce(url(settings, '/splitChanges?s=1.2&since=1684265694546'), function (url, opts) { + fetchMock.getOnce(url(settings, '/splitChanges?s=1.1&since=1684265694546'), function (url, opts) { if (!hasNoCacheHeader(opts)) assert.fail('request must include `Cache-Control` header'); return { status: 200, body: splitChangesMock9 }; }); diff --git a/src/__tests__/nodeSuites/readiness.spec.js b/src/__tests__/nodeSuites/readiness.spec.js index e11026faa..519571ea3 100644 --- a/src/__tests__/nodeSuites/readiness.spec.js +++ b/src/__tests__/nodeSuites/readiness.spec.js @@ -23,8 +23,8 @@ export default function (fetchMock, assert) { events: 'https://events.baseurl/readinessSuite1' }; - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=-1', { status: 200, body: splitChangesMock1 }); - fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.2&since=1457552620999', { status: 200, body: splitChangesMock2 }); + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=-1', { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(testUrls.sdk + '/splitChanges?s=1.1&since=1457552620999', { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(testUrls.sdk + '/segmentChanges/*'), 403); fetchMock.postOnce(testUrls.events + '/events/bulk', 200); diff --git a/src/__tests__/nodeSuites/ready-promise.spec.js b/src/__tests__/nodeSuites/ready-promise.spec.js index 59693d330..e5811b302 100644 --- a/src/__tests__/nodeSuites/ready-promise.spec.js +++ b/src/__tests__/nodeSuites/ready-promise.spec.js @@ -56,8 +56,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -103,8 +103,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -153,8 +153,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -222,9 +222,9 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { config.scheduler.featuresRefreshRate) - config.startup.readyTimeout) + refreshTimeMillis; // /splitChanges takes longer than 'requestTimeoutBeforeReady' in both initial attempts - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: refreshTimeMillis }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -281,7 +281,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -331,7 +331,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes less than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -378,8 +378,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -467,8 +467,8 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' only for the first attempt - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); - fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.getOnce(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) - 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); @@ -538,7 +538,7 @@ export default function readyPromiseAssertions(key, fetchMock, assert) { }; // /splitChanges takes longer than 'requestTimeoutBeforeReady' - fetchMock.get(config.urls.sdk + '/splitChanges?s=1.2&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); + fetchMock.get(config.urls.sdk + '/splitChanges?s=1.1&since=-1', splitChangesMock1, { delay: fromSecondsToMillis(config.startup.requestTimeoutBeforeReady) + 20 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(config.urls.events + '/testImpressions/bulk', 200); fetchMock.postOnce(config.urls.events + '/testImpressions/count', 200); diff --git a/src/__tests__/nodeSuites/telemetry.spec.js b/src/__tests__/nodeSuites/telemetry.spec.js index 32a3f5d7e..a6a6bb66f 100644 --- a/src/__tests__/nodeSuites/telemetry.spec.js +++ b/src/__tests__/nodeSuites/telemetry.spec.js @@ -22,8 +22,8 @@ const config = { export default async function telemetryNodejsSuite(key, fetchMock, assert) { - fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=-1'), 500); // record http exception - fetchMock.getOnce(url(config, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); + fetchMock.getOnce(url(config, '/splitChanges?s=1.1&since=-1'), 500); // record http exception + fetchMock.getOnce(url(config, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); mockSegmentChanges(fetchMock, new RegExp(config.urls.sdk + '/segmentChanges/*'), ['some_key']); fetchMock.postOnce(url(config, '/testImpressions/bulk'), 200); diff --git a/src/__tests__/online/node.spec.js b/src/__tests__/online/node.spec.js index 46bd9fca9..94ca9d830 100644 --- a/src/__tests__/online/node.spec.js +++ b/src/__tests__/online/node.spec.js @@ -38,8 +38,8 @@ const config = { const settings = settingsFactory(config); const key = 'facundo@split.io'; -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); -fetchMock.get(url(settings, '/splitChanges?s=1.2&since=1457552620999'), { status: 200, body: splitChangesMock2 }); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=-1'), { status: 200, body: splitChangesMock1 }); +fetchMock.get(url(settings, '/splitChanges?s=1.1&since=1457552620999'), { status: 200, body: splitChangesMock2 }); fetchMock.get(new RegExp(`${url(settings, '/segmentChanges')}/*`), { status: 200, body: { 'name': 'segment', From 195b1b1928f4f841beea5194861e70b192ca2c1d Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 Sep 2024 13:43:03 -0300 Subject: [PATCH 30/58] Add factory destroy method --- package-lock.json | 18 +++--- package.json | 4 +- src/__tests__/browserSuites/readiness.spec.js | 58 +++---------------- src/__tests__/nodeSuites/readiness.spec.js | 2 +- src/settings/defaults/version.js | 2 +- types/splitio.d.ts | 6 ++ 6 files changed, 28 insertions(+), 62 deletions(-) diff --git a/package-lock.json b/package-lock.json index 737623e94..4fce49522 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.2", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.1", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", - "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", + "version": "1.17.1-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", + "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8528,9 +8528,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.0.tgz", - "integrity": "sha512-WzF8b9zuPfyCqqp8ioeImFJCzSNjuziKQasg4HvPIPjHsFgiUlK/IPp0/1QuDbptEy1qsMJOdXV0wvLG0z1sZw==", + "version": "1.17.1-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", + "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 95344a2b8..ed707f03c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.1", + "version": "10.28.1-rc.2", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.0", + "@splitsoftware/splitio-commons": "1.17.1-rc.1", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 8bc7dada8..245a0dd1a 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -209,12 +209,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 10000); }, 0); }); @@ -293,12 +288,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 4 * CLIENTS_COUNT - 1, 'It should have not tried to synchronize segments again after the last update that left us in a no segment state.'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 10000); }, 0); }); @@ -373,12 +363,7 @@ export default function (fetchMock, assert) { t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT - 1, 'It should keep the producer synchronizing periodically..'); t.equal(readyCount, CLIENTS_COUNT, 'all clients must be ready'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 3000); }, 0); }); @@ -442,12 +427,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 6 * CLIENTS_COUNT, 'It should keep the producer synchronizing periodically..'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); - + splitio.destroy().then(() => { t.end(); }); }, 3000); }, 0); }); @@ -494,11 +474,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and keep syncing afterwards.'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 2500); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -541,11 +517,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 4500); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -592,11 +564,7 @@ export default function (fetchMock, assert) { t.ok(delay >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt but stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -639,11 +607,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 3 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and kept syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { @@ -689,11 +653,7 @@ export default function (fetchMock, assert) { setTimeout(() => { t.equal(getMembershipsHits(), 1 * CLIENTS_COUNT, 'memberships should had been hit once per client on the first attempt and stopped syncing afterwards'); - Promise.all([ - client2.destroy(), - client3.destroy(), - client.destroy() - ]).then(() => { t.end(); }); + splitio.destroy().then(() => { t.end(); }); }, 3000); }); client.once(client.Event.SDK_READY_TIMED_OUT, () => { diff --git a/src/__tests__/nodeSuites/readiness.spec.js b/src/__tests__/nodeSuites/readiness.spec.js index 519571ea3..33e377eb3 100644 --- a/src/__tests__/nodeSuites/readiness.spec.js +++ b/src/__tests__/nodeSuites/readiness.spec.js @@ -49,7 +49,7 @@ export default function (fetchMock, assert) { try { await client.ready(); } catch (e) { - await client.destroy(); + await splitio.destroy(); t.end(); } }); diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 036701e45..1e30feddf 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.1-rc.1'; +export const packageVersion = '10.28.1-rc.2'; diff --git a/types/splitio.d.ts b/types/splitio.d.ts index bb88476bc..e5fc78c28 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -491,6 +491,12 @@ interface IBasicSDK { * @property Logger */ Logger: ILoggerAPI + /** + * Destroys all the clients created by this factory. + * @function destroy + * @returns {Promise} + */ + destroy(): Promise } /****** Exposed namespace ******/ /** From 24137dc625255dcbe12c23280e280b77c6e2c9a9 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 Sep 2024 13:48:16 -0300 Subject: [PATCH 31/58] fix test --- src/__tests__/browserSuites/readiness.spec.js | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/__tests__/browserSuites/readiness.spec.js b/src/__tests__/browserSuites/readiness.spec.js index 245a0dd1a..f81fafccd 100644 --- a/src/__tests__/browserSuites/readiness.spec.js +++ b/src/__tests__/browserSuites/readiness.spec.js @@ -402,8 +402,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, as there are segments in the first splits payload.'); @@ -466,8 +466,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale.'); @@ -509,8 +509,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start < 50, 'It should be ready quickly, since it had no segments and update has no segments either.'); @@ -556,8 +556,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { const delay = Date.now() - start; @@ -599,8 +599,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start >= membershipsEndpointDelay, 'It should not be ready without waiting for memberships, when we start from cache it might be stale and we had segments even though the update has nothing.'); @@ -645,8 +645,8 @@ export default function (fetchMock, assert) { }); const CLIENTS_COUNT = 3; // Just so it's easier to read the assertions. const client = splitio.client(); - const client2 = splitio.client('nicolas2@split.io'); - const client3 = splitio.client('nicolas3@split.io'); + splitio.client('nicolas2@split.io'); + splitio.client('nicolas3@split.io'); client.once(client.Event.SDK_READY, () => { t.ok(Date.now() - start < 50, 'It should be ready without waiting for memberships, since when it downloads changes it will have no more use for them.'); From 24eb00002095f5e5024ab61ee6c9f419cb777999 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 Sep 2024 14:07:11 -0300 Subject: [PATCH 32/58] Update ts tests and changelog entry --- CHANGES.txt | 1 + ts-tests/index.ts | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 1453141e9..0fb91f911 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 10.29.0 (September XX, 2024) + - Added `factory.destroy()` method, which invokes the `destroy` method on all SDK clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: - Added support for targeting rules based on large segments for browsers. - Updated some transitive dependencies for vulnerability fixes. diff --git a/ts-tests/index.ts b/ts-tests/index.ts index a37c52808..7bdc4c834 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -240,10 +240,11 @@ const b: number = client.listenerCount(splitEvent); let nodeEventEmitter: NodeJS.EventEmitter = client; // Ready, destroy and flush -const readyPromise: Promise = client.ready(); -const destroyPromise: Promise = client.destroy(); -// @ts-ignore -const flushPromise: Promise = client.flush(); +let promise: Promise = client.ready(); +promise = client.destroy(); +promise = SDK.destroy(); +// @TODO not public yet +// promise = client.flush(); // We can call getTreatment with or without a key. treatment = client.getTreatment(splitKey, 'mySplit'); @@ -332,10 +333,11 @@ const b1: number = asyncClient.listenerCount(splitEvent); nodeEventEmitter = asyncClient; // Ready, destroy and flush (same as for sync client, just for interface checking) -const readyPromise1: Promise = asyncClient.ready(); -asyncClient.destroy(); -// @ts-ignore -asyncClient.flush(); +promise = asyncClient.ready(); +promise = asyncClient.destroy(); +promise = AsyncSDK.destroy(); +// @TODO not public yet +// promise = asyncClient.flush(); // We can call getTreatment but always with a key. asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit'); @@ -391,7 +393,7 @@ splitView = manager.split('mySplit'); splitViews = manager.splits(); // Manager implements ready promise. -const managerReadyPromise: Promise = manager.ready(); +promise = manager.ready(); // Manager implements methods from NodeJS.Events. Testing a few. manager = manager.on(splitEvent, () => { }); @@ -415,7 +417,7 @@ splitViewAsync = asyncManager.split('mySplit'); splitViewsAsync = asyncManager.splits(); // asyncManager implements ready promise. -const asyncManagerReadyPromise: Promise = asyncManager.ready(); +promise = asyncManager.ready(); // asyncManager implements methods from NodeJS.Events. Testing a few. asyncManager = asyncManager.on(splitEvent, () => { }); From 001e88242dbb61dd94f8911fa65ad7d8df37aa14 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 Sep 2024 17:40:59 -0300 Subject: [PATCH 33/58] rc --- .github/workflows/ci-cd.yml | 4 ++-- src/__tests__/browserSuites/push-synchronization.spec.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..b9512c239 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/add_factory_destroy_method' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/add_factory_destroy_method' }} strategy: matrix: environment: diff --git a/src/__tests__/browserSuites/push-synchronization.spec.js b/src/__tests__/browserSuites/push-synchronization.spec.js index 25e7e93d7..4086050fd 100644 --- a/src/__tests__/browserSuites/push-synchronization.spec.js +++ b/src/__tests__/browserSuites/push-synchronization.spec.js @@ -47,7 +47,6 @@ const config = { }, urls: baseUrls, streamingEnabled: true, - debug: true }; const settings = settingsFactory(config); From 8ba583010fbd1e122a39df50eaa5ce461ec02080 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 20 Sep 2024 17:41:20 -0300 Subject: [PATCH 34/58] rollback ci-cd --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index b9512c239..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/add_factory_destroy_method' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/add_factory_destroy_method' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: From d58d8e392a8e6a51808763e5bc129b1f95f0c4ff Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 1 Oct 2024 21:12:54 -0300 Subject: [PATCH 35/58] Bugfixing - Removed an overloaded method in the interface --- CHANGES.txt | 1 + ts-tests/index.ts | 3 +-- types/splitio.d.ts | 14 +++----------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 0fb91f911..f5569d556 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -3,6 +3,7 @@ - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: - Added support for targeting rules based on large segments for browsers. - Updated some transitive dependencies for vulnerability fixes. + - Bugfixing - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted a key and trafficType parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys or traffic types. 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 7bdc4c834..c7f84d29d 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -195,8 +195,6 @@ SDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager client = SDK.client(); -client = SDK.client('a customer key'); -client = SDK.client('a customer key', 'a traffic type'); manager = SDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. asyncClient = AsyncSDK.client(); @@ -204,6 +202,7 @@ asyncManager = AsyncSDK.manager(); // Browser client for attributes binding browserClient = BrowserSDK.client(); browserClient = BrowserSDK.client('a customer key'); +browserClient = BrowserSDK.client('a customer key', 'a traffic type'); // Logger SDK.Logger.enable(); diff --git a/types/splitio.d.ts b/types/splitio.d.ts index e5fc78c28..27a1dcade 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -1380,14 +1380,6 @@ declare namespace SplitIO { * @returns {IClient} The client instance. */ client(): IClient, - /** - * Returns a shared client of the SDK. For usage on the browser. - * @function client - * @param {SplitKey} key The key for the new client instance. - * @param {string=} trafficType The traffic type of the provided key. - * @returns {IClient} The client instance. - */ - client(key: SplitKey, trafficType?: string): IClient, /** * Returns a manager instance of the SDK to explore available information. * @function manager @@ -1398,9 +1390,9 @@ declare namespace SplitIO { /** * This represents the interface for the SDK instance with synchronous storage. * @interface IBrowserSDK - * @extends ISDK + * @extends IBasicSDK */ - interface IBrowserSDK extends ISDK { + interface IBrowserSDK extends IBasicSDK { /** * Returns the default client instance of the SDK. * @function client @@ -1408,7 +1400,7 @@ declare namespace SplitIO { */ client(): IBrowserClient, /** - * Returns a shared client of the SDK. For usage on the browser. + * Returns a shared client of the SDK. * @function client * @param {SplitKey} key The key for the new client instance. * @param {string=} trafficType The traffic type of the provided key. From 0a082b20110cb321418d85eedb979884058f86e0 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 4 Oct 2024 18:45:54 -0300 Subject: [PATCH 36/58] Rename dist folders: /lib -> /cjs, /es -> /esm --- .gitignore | 4 ++-- CHANGES.txt | 4 +++- client/package.json | 4 ++-- lib/factory/package.json | 4 ++++ lib/platform/getEventSource/package.json | 4 ++++ lib/platform/getFetch/package.json | 4 ++++ lib/platform/package.json | 4 ++++ lib/settings/package.json | 4 ++++ package.json | 14 +++++++------- scripts/build_cjs_replace_imports.sh | 4 ++-- scripts/build_esm_replace_imports.sh | 4 ++-- scripts/copy.packages.json.js | 4 ++-- server/package.json | 4 ++-- webpack.common.js | 2 +- 14 files changed, 43 insertions(+), 21 deletions(-) create mode 100644 lib/factory/package.json create mode 100644 lib/platform/getEventSource/package.json create mode 100644 lib/platform/getFetch/package.json create mode 100644 lib/platform/package.json create mode 100644 lib/settings/package.json diff --git a/.gitignore b/.gitignore index 376800e23..f26a161f7 100644 --- a/.gitignore +++ b/.gitignore @@ -19,8 +19,8 @@ dump.rdb /stats ## transpiled code -/lib -/es +/cjs +/esm /umd ## TS tests compilated files diff --git a/CHANGES.txt b/CHANGES.txt index 1453141e9..22397f752 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,9 @@ -10.29.0 (September XX, 2024) +11.0.0 (October XX, 2024) - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: - Added support for targeting rules based on large segments for browsers. - Updated some transitive dependencies for vulnerability fixes. + - BREAKING CHANGES: + - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: diff --git a/client/package.json b/client/package.json index d1f660668..f99b69ceb 100644 --- a/client/package.json +++ b/client/package.json @@ -1,5 +1,5 @@ { - "main": "../lib/factory/browser.js", - "module": "../es/factory/browser.js", + "main": "../cjs/factory/browser.js", + "module": "../esm/factory/browser.js", "types": "../types/client/index.d.ts" } diff --git a/lib/factory/package.json b/lib/factory/package.json new file mode 100644 index 000000000..a19625907 --- /dev/null +++ b/lib/factory/package.json @@ -0,0 +1,4 @@ +{ + "main": "./node.js", + "browser": "./browser.js" +} diff --git a/lib/platform/getEventSource/package.json b/lib/platform/getEventSource/package.json new file mode 100644 index 000000000..a19625907 --- /dev/null +++ b/lib/platform/getEventSource/package.json @@ -0,0 +1,4 @@ +{ + "main": "./node.js", + "browser": "./browser.js" +} diff --git a/lib/platform/getFetch/package.json b/lib/platform/getFetch/package.json new file mode 100644 index 000000000..a19625907 --- /dev/null +++ b/lib/platform/getFetch/package.json @@ -0,0 +1,4 @@ +{ + "main": "./node.js", + "browser": "./browser.js" +} diff --git a/lib/platform/package.json b/lib/platform/package.json new file mode 100644 index 000000000..a19625907 --- /dev/null +++ b/lib/platform/package.json @@ -0,0 +1,4 @@ +{ + "main": "./node.js", + "browser": "./browser.js" +} diff --git a/lib/settings/package.json b/lib/settings/package.json new file mode 100644 index 000000000..a19625907 --- /dev/null +++ b/lib/settings/package.json @@ -0,0 +1,4 @@ +{ + "main": "./node.js", + "browser": "./browser.js" +} diff --git a/package.json b/package.json index 95344a2b8..0e1ba9135 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "CONTRIBUTORS-GUIDE.md", "LICENSE", "CHANGES.txt", - "lib", + "cjs", "types", - "es", + "esm", "src", "scripts/ga-to-split-autorequire.js", "client", @@ -32,8 +32,8 @@ "sdk", "javascript" ], - "main": "lib/index.js", - "module": "es/index.js", + "main": "cjs/index.js", + "module": "esm/index.js", "types": "types", "engines": { "npm": ">=3", @@ -84,10 +84,10 @@ "webpack-merge": "^5.8.0" }, "scripts": { - "build-esm": "rimraf es && tsc -outDir es", - "postbuild-esm": "cross-env NODE_ENV=es node scripts/copy.packages.json.js && ./scripts/build_esm_replace_imports.sh", + "build-esm": "rimraf esm && tsc -outDir esm", + "postbuild-esm": "cross-env NODE_ENV=esm node scripts/copy.packages.json.js && ./scripts/build_esm_replace_imports.sh", "build-umd:stats": "webpack --progress --env production --json > ./stats/stat_results.json", - "build-cjs": "rimraf lib && tsc -outDir lib -m CommonJS", + "build-cjs": "rimraf cjs && tsc -outDir cjs -m CommonJS", "postbuild-cjs": "cross-env NODE_ENV=cjs node scripts/copy.packages.json.js && ./scripts/build_cjs_replace_imports.sh", "build-umd": "rimraf umd && webpack --config webpack.dev.js --env branch=$BUILD_BRANCH && webpack --config webpack.prod.js --env branch=$BUILD_BRANCH && ./scripts/clean_umd_build.sh", "build:npm": "npm run build-cjs && npm run build-esm", diff --git a/scripts/build_cjs_replace_imports.sh b/scripts/build_cjs_replace_imports.sh index 85490429f..fd29a4a7e 100755 --- a/scripts/build_cjs_replace_imports.sh +++ b/scripts/build_cjs_replace_imports.sh @@ -1,7 +1,7 @@ #!/bin/bash -# replace splitio-commons imports to use ES modules -replace '@splitsoftware/splitio-commons/src' '@splitsoftware/splitio-commons/cjs' ./lib -r +# replace splitio-commons imports to use CommonJS +replace '@splitsoftware/splitio-commons/src' '@splitsoftware/splitio-commons/cjs' ./cjs -r if [ $? -eq 0 ] then diff --git a/scripts/build_esm_replace_imports.sh b/scripts/build_esm_replace_imports.sh index 81cfb81b0..16155e206 100755 --- a/scripts/build_esm_replace_imports.sh +++ b/scripts/build_esm_replace_imports.sh @@ -1,7 +1,7 @@ #!/bin/bash -# replace splitio-commons imports to use ES modules -replace '@splitsoftware/splitio-commons/src' '@splitsoftware/splitio-commons/esm' ./es -r +# replace splitio-commons imports to use EcmaScript Modules +replace '@splitsoftware/splitio-commons/src' '@splitsoftware/splitio-commons/esm' ./esm -r if [ $? -eq 0 ] then diff --git a/scripts/copy.packages.json.js b/scripts/copy.packages.json.js index 3ce08513b..68683ee6c 100644 --- a/scripts/copy.packages.json.js +++ b/scripts/copy.packages.json.js @@ -3,8 +3,8 @@ const copyfiles = require('copyfiles'); const input = './src/**/package.json'; -const outputCjsDir = './lib'; -const outputEsmDir = './es'; +const outputCjsDir = './cjs'; +const outputEsmDir = './esm'; copyfiles([input, process.env.NODE_ENV === 'cjs' ? outputCjsDir : outputEsmDir], { up: 1, diff --git a/server/package.json b/server/package.json index be8f299ed..21aeb6f1f 100644 --- a/server/package.json +++ b/server/package.json @@ -1,5 +1,5 @@ { - "main": "../lib/factory/node.js", - "module": "../es/factory/node.js", + "main": "../cjs/factory/node.js", + "module": "../esm/factory/node.js", "types": "../types/server/index.d.ts" } diff --git a/webpack.common.js b/webpack.common.js index e7a389788..8fb8dc34b 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,6 +1,6 @@ module.exports = { entry: { - split: ['./es/umd.js'] + split: ['./esm/umd.js'] }, output: { From 4cfec031a698676012ac074c1f33a173fafce89b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 4 Oct 2024 18:54:01 -0300 Subject: [PATCH 37/58] Drop support for NodeJS v6 --- CHANGES.txt | 1 + package.json | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 22397f752..d6c991560 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -4,6 +4,7 @@ - Updated some transitive dependencies for vulnerability fixes. - BREAKING CHANGES: - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. + - Drop support for NodeJS v6. The SDK now requires NodeJS v14 or above. 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: diff --git a/package.json b/package.json index 0e1ba9135..99415e656 100644 --- a/package.json +++ b/package.json @@ -36,8 +36,7 @@ "module": "esm/index.js", "types": "types", "engines": { - "npm": ">=3", - "node": ">=6" + "node": ">=14.0.0" }, "dependencies": { "@splitsoftware/splitio-commons": "1.17.1-rc.0", From 9eefd1bf415e0ef35512e9aea806c849cac27f76 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 8 Oct 2024 17:50:58 -0300 Subject: [PATCH 38/58] Upgrade JS-commons. Updated type definitions & tests --- karma/e2e.gaIntegration.karma.conf.js | 20 - package-lock.json | 100 ++-- package.json | 8 +- scripts/ga-to-split-autorequire.js | 1 - src/__tests__/browserSuites/telemetry.spec.js | 2 +- .../browserSuites/user-consent.spec.js | 10 +- .../gaIntegration/both-integrations.spec.js | 138 ------ src/__tests__/gaIntegration/browser.spec.js | 31 -- .../gaIntegration/ga-to-split.spec.js | 461 ------------------ src/__tests__/gaIntegration/gaTestUtils.js | 94 ---- .../gaIntegration/split-to-ga.spec.js | 438 ----------------- src/__tests__/online/browser.spec.js | 8 +- src/__tests__/testUtils/index.js | 2 +- src/factory/browser.js | 5 +- src/settings/__tests__/browser.spec.js | 30 -- src/settings/browser.js | 4 +- src/settings/defaults/version.js | 2 +- src/sync/offline/splitsParserFromFile.js | 2 +- ts-tests/index.ts | 88 +--- types/client/index.d.ts | 2 +- types/index.d.ts | 6 +- types/server/index.d.ts | 4 +- types/splitio.d.ts | 445 +++++------------ 23 files changed, 226 insertions(+), 1675 deletions(-) delete mode 100644 karma/e2e.gaIntegration.karma.conf.js delete mode 100644 scripts/ga-to-split-autorequire.js delete mode 100644 src/__tests__/gaIntegration/both-integrations.spec.js delete mode 100644 src/__tests__/gaIntegration/browser.spec.js delete mode 100644 src/__tests__/gaIntegration/ga-to-split.spec.js delete mode 100644 src/__tests__/gaIntegration/gaTestUtils.js delete mode 100644 src/__tests__/gaIntegration/split-to-ga.spec.js diff --git a/karma/e2e.gaIntegration.karma.conf.js b/karma/e2e.gaIntegration.karma.conf.js deleted file mode 100644 index f6b03110f..000000000 --- a/karma/e2e.gaIntegration.karma.conf.js +++ /dev/null @@ -1,20 +0,0 @@ -const assign = require('lodash/assign'); - -module.exports = function(config) { - 'use strict'; - - config.set(assign({}, require('./config'), { - // list of files / patterns to load in the browser - files: [ - '__tests__/gaIntegration/browser.spec.js' - ], - // prepare code for the browser using webpack - preprocessors: { - '__tests__/gaIntegration/browser.spec.js': ['webpack'] - }, - - // level of logging - // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG - logLevel: config.LOG_WARN - })); -}; diff --git a/package-lock.json b/package-lock.json index 4fce49522..4071ba591 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "11.0.0-rc.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "11.0.0-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.1", - "@types/google.analytics": "0.0.40", + "@splitsoftware/splitio-commons": "2.0.0-rc.0", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", @@ -53,8 +52,7 @@ "webpack-merge": "^5.8.0" }, "engines": { - "node": ">=6", - "npm": ">=3" + "node": ">=14.0.0" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -872,9 +870,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", - "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.0.tgz", + "integrity": "sha512-iNuGugPMXQ/+k+uSDyhsvwkaGdzQrRaxRtP1sv58STKQFwww1smPxRA1gKfawoQm04quEHtLMKYm25t6VL0fJw==", "dependencies": { "tslib": "^2.3.1" }, @@ -932,11 +930,6 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "node_modules/@types/google.analytics": { - "version": "0.0.40", - "resolved": "https://registry.npmjs.org/@types/google.analytics/-/google.analytics-0.0.40.tgz", - "integrity": "sha512-R3HpnLkqmKxhUAf8kIVvDVGJqPtaaZlW4yowNwjOZUTmYUQEgHh8Nh5wkSXKMroNAuQM8gbXJHmNbbgA8tdb7Q==" - }, "node_modules/@types/ioredis": { "version": "4.28.10", "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.28.10.tgz", @@ -2612,9 +2605,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz", + "integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2633,9 +2626,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4473,9 +4466,9 @@ "dev": true }, "node_modules/karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "dependencies": { "@colors/colors": "1.5.0", @@ -4497,7 +4490,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -4951,9 +4944,9 @@ "dev": true }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "dependencies": { "isarray": "0.0.1" @@ -6435,16 +6428,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -8528,9 +8521,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", - "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", + "version": "2.0.0-rc.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.0.tgz", + "integrity": "sha512-iNuGugPMXQ/+k+uSDyhsvwkaGdzQrRaxRtP1sv58STKQFwww1smPxRA1gKfawoQm04quEHtLMKYm25t6VL0fJw==", "requires": { "tslib": "^2.3.1" } @@ -8580,11 +8573,6 @@ "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, - "@types/google.analytics": { - "version": "0.0.40", - "resolved": "https://registry.npmjs.org/@types/google.analytics/-/google.analytics-0.0.40.tgz", - "integrity": "sha512-R3HpnLkqmKxhUAf8kIVvDVGJqPtaaZlW4yowNwjOZUTmYUQEgHh8Nh5wkSXKMroNAuQM8gbXJHmNbbgA8tdb7Q==" - }, "@types/ioredis": { "version": "4.28.10", "resolved": "https://registry.npmjs.org/@types/ioredis/-/ioredis-4.28.10.tgz", @@ -9954,9 +9942,9 @@ } }, "engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.1.tgz", + "integrity": "sha512-NEpDCw9hrvBW+hVEOK4T7v0jFJ++KgtPl4jKFwsZVfG1XhS0dCrSb3VMb9gPAd7VAdW52VT1EnaNiU2vM8C0og==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -9981,9 +9969,9 @@ } }, "engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true }, "enhanced-resolve": { @@ -11305,9 +11293,9 @@ "dev": true }, "karma": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.1.tgz", - "integrity": "sha512-Cj57NKOskK7wtFWSlMvZf459iX+kpYIPXmkNUzP2WAFcA7nhr/ALn5R7sw3w+1udFDcpMx/tuB8d5amgm3ijaA==", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", "dev": true, "requires": { "@colors/colors": "1.5.0", @@ -11329,7 +11317,7 @@ "qjobs": "^1.2.0", "range-parser": "^1.2.1", "rimraf": "^3.0.2", - "socket.io": "^4.4.1", + "socket.io": "^4.7.2", "source-map": "^0.6.1", "tmp": "^0.2.1", "ua-parser-js": "^0.7.30", @@ -11715,9 +11703,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "requires": { "isarray": "0.0.1" @@ -12848,16 +12836,16 @@ } }, "socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" } diff --git a/package.json b/package.json index 72ac785c0..12856a9ac 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "11.0.0-rc.0", "description": "Split SDK", "files": [ "README.md", @@ -11,7 +11,6 @@ "types", "esm", "src", - "scripts/ga-to-split-autorequire.js", "client", "server" ], @@ -39,8 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.1", - "@types/google.analytics": "0.0.40", + "@splitsoftware/splitio-commons": "2.0.0-rc.0", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", @@ -90,7 +88,6 @@ "postbuild-cjs": "cross-env NODE_ENV=cjs node scripts/copy.packages.json.js && ./scripts/build_cjs_replace_imports.sh", "build-umd": "rimraf umd && webpack --config webpack.dev.js --env branch=$BUILD_BRANCH && webpack --config webpack.prod.js --env branch=$BUILD_BRANCH && ./scripts/clean_umd_build.sh", "build:npm": "npm run build-cjs && npm run build-esm", - "build:ga-to-split-autorequire": "terser ./node_modules/@splitsoftware/splitio-commons/src/integrations/ga/autoRequire.js --mangle --output ./scripts/ga-to-split-autorequire.js && cp ./scripts/ga-to-split-autorequire.js umd/ga-to-split-autorequire.js", "build": "npm run build-cjs && npm run build-esm && npm run build-umd", "check": "npm run check:lint && npm run check:version", "check:lint": "eslint src", @@ -103,7 +100,6 @@ "test-browser-e2e-destroy": "cross-env NODE_ENV=test karma start karma/e2e.destroy.karma.conf.js", "test-browser-e2e-errorCatching": "cross-env NODE_ENV=test karma start karma/e2e.errorCatching.karma.conf.js", "test-browser-e2e-push": "cross-env NODE_ENV=test karma start karma/e2e.push.karma.conf.js", - "test-browser-e2e-gaIntegration": "cross-env NODE_ENV=test karma start karma/e2e.gaIntegration.karma.conf.js", "test-node": "npm run test-node-unit && npm run test-node-e2e", "test-node-unit": "cross-env NODE_ENV=test tape -r ./ts-node.register \"src/*/**/__tests__/**/!(browser).spec.js\" | tap-min", "test-node-e2e": "npm run test-node-e2e-online && npm run test-node-e2e-offline && npm run test-node-e2e-destroy && npm run test-node-e2e-errorCatching && npm run test-node-e2e-push && npm run test-node-e2e-redis", diff --git a/scripts/ga-to-split-autorequire.js b/scripts/ga-to-split-autorequire.js deleted file mode 100644 index 7f8b88597..000000000 --- a/scripts/ga-to-split-autorequire.js +++ /dev/null @@ -1 +0,0 @@ -(function(n,t,e){n[e]=n[e]||t;n[t]=n[t]||function(){n[t].q.push(arguments)};n[t].q=n[t].q||[];var r={};function i(n){return typeof n==="object"&&typeof n.name==="string"&&n.name}function o(e){if(e&&e[0]==="create"){var o=i(e[1])||i(e[2])||i(e[3])||(typeof e[3]==="string"?e[3]:undefined);if(!r[o]){r[o]=true;n[t]((o?o+".":"")+"require","splitTracker")}}}n[t].q.forEach(o);var u=n[t].q.push;n[t].q.push=function(n){var t=u.apply(this,arguments);o(n);return t}})(window,"ga","GoogleAnalyticsObject"); \ No newline at end of file diff --git a/src/__tests__/browserSuites/telemetry.spec.js b/src/__tests__/browserSuites/telemetry.spec.js index 0251dc0f2..5ed7c331d 100644 --- a/src/__tests__/browserSuites/telemetry.spec.js +++ b/src/__tests__/browserSuites/telemetry.spec.js @@ -111,7 +111,7 @@ export default async function telemetryBrowserSuite(fetchMock, t) { oM: 0, st: 'memory', aF: 1, rF: 0, sE: false, rR: { sp: 99999, ms: 60, im: 300, ev: 60, te: 1 } /* override featuresRefreshRate */, uO: { s: true, e: true, a: false, st: false, t: true } /* override sdk, events and telemetry URLs */, - iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], i: [], uC: 2 /* Default GRANTED */, + iQ: 30000, eQ: 500, iM: 0, iL: false, hP: false, nR: 1 /* 1 non ready usage */, t: [], uC: 2 /* Default GRANTED */, fsT: 0, fsI: 0 }, 'metrics/config JSON payload should be the expected'); diff --git a/src/__tests__/browserSuites/user-consent.spec.js b/src/__tests__/browserSuites/user-consent.spec.js index 024fcb44d..ed1caba2c 100644 --- a/src/__tests__/browserSuites/user-consent.spec.js +++ b/src/__tests__/browserSuites/user-consent.spec.js @@ -72,7 +72,7 @@ function mockSubmittersRequests(fetchMock, assert, impressionFeature, eventTypeI export default function userConsent(fetchMock, t) { - // Validate trackers, submitters and browser listener behaviour on different consent status transitions + // Validate trackers, submitters and browser listener behavior on different consent status transitions t.test(async (assert) => { const sendBeaconSpy = sinon.spy(window.navigator, 'sendBeacon'); let expectedTrackedImpressions = 0; @@ -97,7 +97,7 @@ export default function userConsent(fetchMock, t) { ], ['on', 'on', 'on', 'on', 'on', 'on', 'on', 'on'], 'evaluating on SDK ready'); if (isTracking) expectedTrackedImpressions += 8; - // Trigger pagehide event to validate browser listener behaviour + // Trigger pagehide event to validate browser listener behavior // Beacon API is used only if user consent is GRANTED triggerPagehideEvent(); if (factory.UserConsent.getStatus() === factory.UserConsent.Status.GRANTED) { @@ -137,9 +137,9 @@ export default function userConsent(fetchMock, t) { assert.equal(trackedImpressions.length, expectedTrackedImpressions, 'Tracked impressions are the expected'); sendBeaconSpy.restore(); assert.end(); - }, 'Validate trackers, submitters and browser listener behaviour on different consent status transitions'); + }, 'Validate trackers, submitters and browser listener behavior on different consent status transitions'); - // Validate submitter's behaviour with full queues and with events first push window + // Validate submitter's behavior with full queues and with events first push window t.test(async (assert) => { const config = { ...baseConfig, @@ -182,6 +182,6 @@ export default function userConsent(fetchMock, t) { await client.destroy(); assert.end(); - }, 'Validate submitter\'s behaviour with full queues and with events first push window'); + }, 'Validate submitter\'s behavior with full queues and with events first push window'); } diff --git a/src/__tests__/gaIntegration/both-integrations.spec.js b/src/__tests__/gaIntegration/both-integrations.spec.js deleted file mode 100644 index 17b4ae736..000000000 --- a/src/__tests__/gaIntegration/both-integrations.spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import { SplitFactory } from '../../'; -import { settingsFactory } from '../../settings'; -import { gaSpy, gaTag } from './gaTestUtils'; -import includes from 'lodash/includes'; -import { DEBUG } from '@splitsoftware/splitio-commons/src/utils/constants'; -import { url } from '../testUtils'; - -function countImpressions(parsedImpressionsBulkPayload) { - return parsedImpressionsBulkPayload - .reduce((accumulator, currentValue) => { return accumulator + currentValue.i.length; }, 0); -} - -const config = { - core: { - key: 'facundo@split.io', - trafficType: 'user', - }, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - }, { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - }], - streamingEnabled: false, - sync: { - impressionsMode: DEBUG, - } -}; -const settings = settingsFactory(config); - -export default function (fetchMock, assert) { - - let client; - - // test default behavior of both integrations - assert.test(t => { - const customHits = [{ hitType: 'pageview' }, { hitType: 'event' }]; - - /* [eventType] */ - const splitTrackParams = [['some_event'], ['other_event'], ['another_event']]; - /* [splitName] */ - const splitGetTreatmentParams = [['hierarchical_splits_test']]; - - // Generator to synchronize the call of t.end() when both impressions and events endpoints were invoked. - const finish = (function* () { - yield; - const totalHits = customHits.length + splitTrackParams.length + splitGetTreatmentParams.length; - - t.equal(window.gaSpy.getHits().length, totalHits, 'Total hits'); - setTimeout(() => { - client.destroy(); - t.end(); - }, 0); - })(); - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - // we can assert payload and ga hits, once ga is ready and after `SplitToGa.queue`, that is timeout wrapped, make to the queue stack. - window.ga(() => { - setTimeout(() => { - try { - const resp = JSON.parse(opts.body); - const numberOfSentImpressions = countImpressions(resp); - const sentImpressionHits = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-impression'); - - t.equal(numberOfSentImpressions, splitGetTreatmentParams.length, 'Number of impressions'); - t.equal(sentImpressionHits.length, splitGetTreatmentParams.length, `Number of sent impression hits must be equal to the number of impressions (${splitGetTreatmentParams.length})`); - - finish.next(); - } catch (err) { - console.error(err); - } - }); - }); - return 200; - }); - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - window.ga(() => { - setTimeout(() => { - try { - const sentEvents = JSON.parse(opts.body); - const sentEventsFromSplitToGa = sentEvents.filter(event => { - return event.properties && event.properties.eventCategory && includes(event.properties.eventCategory, 'split'); - }); - - t.equal(sentEvents.length, splitTrackParams.length + customHits.length, 'Number of sent events is equal to custom events plus hits tracked as events'); - t.equal(sentEventsFromSplitToGa.length, 0, 'GA hits comming from Split-to-GA integration must not be tracked again as Split events'); - - const sentHitsNoSplitData = window.gaSpy.getHits().filter(hit => !hit.eventCategory || !includes(hit.eventCategory, 'split')); - const sentHitsSplitEvents = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-event'); - - t.equal(sentHitsNoSplitData.length, customHits.length, 'Number of custom hits'); - t.equal(sentHitsSplitEvents.length, splitTrackParams.length, 'Number of Split event hits'); - finish.next(); - } catch (err) { - console.error(err); - } - }); - }); - return 200; - }); - - gaTag(); - - // siteSpeedSampleRate set to 0 to never send a site speed timing hit - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - window.ga('require', 'splitTracker'); - customHits.forEach(hit => { - window.ga('send', hit); - }); - - const factory = SplitFactory({ - ...config, - startup: { - eventsFirstPushWindow: 0, - }, - scheduler: { - impressionsRefreshRate: 1, - // @TODO eventsPushRate is too high, but using eventsQueueSize don't let us assert `filterSplitToGaHits` - eventsPushRate: 10, - // eventsQueueSize: splitTrackParams.length + customHits.length, - }, - }); - client = factory.client(); - - client.ready().then(() => { - splitTrackParams.forEach(trackParams => { - client.track.apply(client, trackParams); - }); - splitGetTreatmentParams.forEach(getTreatmentParams => { - client.getTreatment.apply(client, getTreatmentParams); - }); - }); - }); - -} diff --git a/src/__tests__/gaIntegration/browser.spec.js b/src/__tests__/gaIntegration/browser.spec.js deleted file mode 100644 index 502d57c29..000000000 --- a/src/__tests__/gaIntegration/browser.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import tape from 'tape-catch'; -import fetchMock from '../testUtils/fetchMock'; -import { url } from '../testUtils'; -import gaToSplitSuite from './ga-to-split.spec'; -import splitToGaSuite from './split-to-ga.spec'; -import bothIntegrationsSuite from './both-integrations.spec'; - -import { settingsFactory } from '../../settings'; - -import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import membershipsFacundo from '../mocks/memberships.facundo@split.io.json'; - -const settings = settingsFactory({ - core: { - key: 'facundo@split.io' - } -}); - -tape('## E2E CI Tests ##', function (assert) { - - fetchMock.get(url(settings, '/splitChanges?s=1.2&since=-1'), { status: 200, body: splitChangesMock1 }); - fetchMock.get(url(settings, '/memberships/facundo%40split.io'), { status: 200, body: membershipsFacundo }); - fetchMock.post(/\/v1\/metrics/, 200); // 0.1% sample rate - - /* Validate GA integration */ - assert.test('E2E / GA-to-Split', gaToSplitSuite.bind(null, fetchMock)); - assert.test('E2E / Split-to-GA', splitToGaSuite.bind(null, fetchMock)); - assert.test('E2E / Both GA integrations', bothIntegrationsSuite.bind(null, fetchMock)); - - assert.end(); -}); diff --git a/src/__tests__/gaIntegration/ga-to-split.spec.js b/src/__tests__/gaIntegration/ga-to-split.spec.js deleted file mode 100644 index cc8e8764f..000000000 --- a/src/__tests__/gaIntegration/ga-to-split.spec.js +++ /dev/null @@ -1,461 +0,0 @@ -import sinon from 'sinon'; -import { SplitFactory } from '../../'; -import { settingsFactory } from '../../settings'; -import { gaSpy, gaTag, addGaTag, removeGaTag } from './gaTestUtils'; -import { url } from '../testUtils'; - -const config = { - core: { - key: 'facundo@split.io', - trafficType: 'user', - }, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - }], - startup: { - eventsFirstPushWindow: 0.2, - }, - streamingEnabled: false -}; -const settings = settingsFactory(config); - -export default function (fetchMock, assert) { - - let client; - - // test default behavior on default tracker - assert.test(t => { - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHits = window.gaSpy.getHits(); - - t.equal(resp.length, sentHits.length, `Number of sent hits must be equal to sent events (${resp.length})`); - t.equal(resp[0].key, settings.core.key, 'Event key is same that SDK config key'); - t.equal(resp[0].trafficTypeName, settings.core.trafficType, 'Event trafficTypeName is same that SDK config key'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - // siteSpeedSampleRate set to 0 to never send a site speed timing hit - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - window.ga('require', 'splitTracker'); - window.ga('send', 'pageview'); - - const factory = SplitFactory(config); - client = factory.client(); - - }); - - // test default behavior on named tracker, tracking N events, and GA in a different global variable - assert.test(t => { - const numberOfCustomEvents = 5; - let client; - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHits = window.gaSpy.getHits('myTracker'); - - t.equal(resp.length, sentHits.length, `Number of sent hits must be equal to sent events (${resp.length})`); - t.equal(resp[0].key, settings.core.key, 'Event key is same that SDK config key'); - t.equal(resp[0].trafficTypeName, settings.core.trafficType, 'Event trafficTypeName is same that SDK config key'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag('other_location_for_ga'); - - window.other_location_for_ga('create', 'UA-00000001-1', 'example1.com', 'myTracker', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker']); - - const factory = SplitFactory(config); - client = factory.client(); - - window.other_location_for_ga('myTracker.require', 'splitTracker'); - // this second 'require' is not applied (does not overwrite previous command) - window.other_location_for_ga('myTracker.require', 'splitTracker', { mapper: function () { throw 'error'; } }); - - for (let i = 0; i < numberOfCustomEvents; i++) - window.other_location_for_ga('myTracker.send', 'pageview'); - - }); - - // test error: no TT in SDK config - assert.test(t => { - const numberOfCustomEvents = 5; - - gaTag(); - - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - const logSpy = sinon.spy(console, 'log'); - - const factory = SplitFactory({ - ...config, - core: { key: config.core.key }, - debug: true, - }); - - window.ga('require', 'splitTracker'); - for (let i = 0; i < numberOfCustomEvents; i++) - window.ga('send', 'pageview'); - - // We must wait until ga is ready to get SplitTracker required and invoked, and to assert the test - window.ga(() => { - t.ok(logSpy.calledWith('[WARN] splitio => ga-to-split: No valid identities were provided. Please check that you are passing a valid list of identities or providing a traffic type at the SDK configuration.')); - t.equal(window.gaSpy.getHits().length, numberOfCustomEvents, `Number of sent hits must be equal to ${numberOfCustomEvents}`); - - logSpy.restore(); - t.end(); - }); - - factory.client().destroy(); - - }); - - // test default behavior, providing a list of identities as SDK options - assert.test(t => { - const numberOfCustomEvents = 3; - const identities = [{ key: 'user1', trafficType: 'user' }, { key: 'user2', trafficType: 'user' }]; - let client; - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHits = window.gaSpy.getHits('myTracker3'); - - t.equal(sentHits.length, numberOfCustomEvents, `Number of sent hits must be equal to sent custom events (${numberOfCustomEvents})`); - t.equal(resp.length, numberOfCustomEvents * identities.length, 'The number of sent events must be equal to the number of sent hits multiply by the number of identities'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - window.ga('create', 'UA-00000003-1', 'example3.com', 'myTracker3', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker3']); - - const factory = SplitFactory({ - ...config, - core: { key: config.core.key }, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - identities: identities, - }], - }); - client = factory.client(); - - window.ga('myTracker3.require', 'splitTracker'); - for (let i = 0; i < numberOfCustomEvents; i++) - window.ga('myTracker3.send', 'pageview'); - - }); - - - // test default behavior in multiple trackers, providing a list of identities in plugin options for one tracker and in sdk options for another - assert.test(t => { - const identitiesPluginOpts = [{ key: 'user1', trafficType: 'user' }, { key: 'user2', trafficType: 'user' }]; - const identitiesSdkOpts = [{ key: 'user3', trafficType: 'user' }]; - const gaSendIterations = 3; - const expectedNumberOfSplitEvents = gaSendIterations * (identitiesPluginOpts.length + identitiesSdkOpts.length); - - let client; - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - t.equal(resp.length, expectedNumberOfSplitEvents, 'The number of sent Split events must be equal to the number of sent hits multiply by the number of identities'); - - const sentHitsTracker4 = window.gaSpy.getHits('myTracker4'); - const sentHitsTracker5 = window.gaSpy.getHits('myTracker5'); - - t.equal(sentHitsTracker4.length, gaSendIterations, `Number of sent hits must be equal to the times 'send' command was invoked (${gaSendIterations})`); - t.equal(sentHitsTracker5.length, gaSendIterations, `Number of sent hits must be equal to the times 'send' command was invoked (${gaSendIterations})`); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - window.ga('create', 'UA-00000004-1', 'example4.com', 'myTracker4', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000005-1', 'example5.com', 'myTracker5', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker4', 'myTracker5']); - - const factory = SplitFactory({ - ...config, - core: { key: config.core.key }, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - identities: identitiesSdkOpts, - }], - }); - client = factory.client(); - - window.ga('myTracker4.require', 'splitTracker', { identities: identitiesPluginOpts }); - window.ga('myTracker5.require', 'splitTracker'); - - for (let i = 0; i < gaSendIterations; i++) { - window.ga('myTracker4.send', 'pageview'); - window.ga('myTracker5.send', 'event', 'mycategory', 'myaction'); - } - - }); - - // test custom filter and mapper in multiple trackers, passed as plugin options for one tracker and as sdk options for another - assert.test(t => { - const gaSendIterations = 3; - const prefixPluginOpts = 'plugin'; - const prefixSdkOpts = 'sdk'; - - let client; - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - t.equal(resp.length, gaSendIterations * 2, 'The number of sent Split events must be equal to the number of no filtered sent hits'); - t.equal(resp.filter(event => event.eventTypeId === prefixSdkOpts + '.mapperSdkOpts').length, gaSendIterations, 'Custom Split events'); - t.equal(resp.filter(event => event.eventTypeId === prefixPluginOpts + '.mapperPluginOpts').length, gaSendIterations, 'Custom Split events'); - - const sentHitsTracker4 = window.gaSpy.getHits('myTracker4'); - const sentHitsTracker5 = window.gaSpy.getHits('myTracker5'); - - t.equal(sentHitsTracker4.length, gaSendIterations * 2, 'Number of sent hits must be equal to the times `send` command was invoked'); - t.equal(sentHitsTracker5.length, gaSendIterations * 2, 'Number of sent hits must be equal to the times `send` command was invoked'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - window.ga('create', 'UA-00000004-1', 'example4.com', 'myTracker4', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000005-1', 'example5.com', 'myTracker5', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker4', 'myTracker5']); - - const factory = SplitFactory({ - ...config, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - filter: model => model.get('hitType') === 'pageview', // accepts only pageviews - mapper: () => ({ eventTypeId: 'mapperSdkOpts' }), // return a fixed event instance - prefix: prefixSdkOpts, - }], - }); - client = factory.client(); - - window.ga('myTracker4.require', 'splitTracker', { - filter: model => model.get('hitType') === 'event', // accepts only events - mapper: (model, defaultEvent) => ({ ...defaultEvent, eventTypeId: 'mapperPluginOpts' }), // updates the eventTypeId of default event - prefix: prefixPluginOpts, - }); - window.ga('myTracker5.require', 'splitTracker'); - - for (let i = 0; i < gaSendIterations; i++) { - window.ga('myTracker4.send', 'pageview'); - window.ga('myTracker5.send', 'pageview'); - window.ga('myTracker4.send', 'event', 'mycategory', 'myaction'); - window.ga('myTracker5.send', 'event', 'mycategory', 'myaction'); - } - - }); - - // exception in custom mapper or invalid mapper result must not block sending hits - assert.test(t => { - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - t.equal(resp.length, 1, 'only a custom event is sent. no events associated to ga hit'); - return 200; - }); - - gaTag(); - - // siteSpeedSampleRate set to 0 to never send a site speed timing hit - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000001-1', 'example1.com', 'myTracker', { siteSpeedSampleRate: 0 }); - - gaSpy(['t0', 'myTracker']); - - window.ga('require', 'splitTracker', { mapper: function () { throw 'error'; } }); - // this second 'require' is not applied (it does not overwrite previous command) - window.ga('require', 'splitTracker'); - - window.ga('myTracker.require', 'splitTracker', { mapper: function () { return { value: 'invalid value' }; } }); - - const logSpy = sinon.spy(console, 'log'); - - window.ga('send', 'pageview'); - window.ga('myTracker.send', 'pageview'); - - const factory = SplitFactory(config); - factory.Logger.enable(); // Enable debug logs. Equivalent to `config.debug` true - client = factory.client(); - client.track('some_event'); - - setTimeout(() => { - const sentHitsT0 = window.gaSpy.getHits('t0'); - const sentHitsMyTracker = window.gaSpy.getHits('myTracker'); - t.equal(sentHitsT0.length, 1, 'Hits must be sent even if a custom mapper throw an exception'); - t.equal(sentHitsMyTracker.length, 1, 'Hits must be sent even if a custom mapper return an invalid event instance'); - t.ok(logSpy.calledWith('[ERROR] splitio => ga-to-split:mapper: value must be a finite number.')); - client.destroy(); - logSpy.restore(); - t.end(); - }); - - }); - - // test default behavior on default tracker: Split ready before GA init, and keep sending hits after Split destroyed - assert.test(t => { - const hits = [{ hitType: 'pageview' }, { hitType: 'event' }]; - const hitsAfterDestroyed = [{ hitType: 'screenview' }]; - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHits = window.gaSpy.getHits(); - - t.equal(resp.length, sentHits.length, `Number of sent hits must be equal to sent events (${hits.length})`); - t.equal(resp.length, hits.length, `Number of sent hits must be equal to sent events (${hits.length})`); - - setTimeout(() => { - client.destroy().then(() => { - hitsAfterDestroyed.forEach(hit => window.ga('send', hit)); - setTimeout(() => { - t.equal(sentHits.length, hits.length + hitsAfterDestroyed.length, 'sending hits must not be bloqued if Split SDK is destroyed'); - t.end(); - }); - }); - }); - return 200; - }); - - removeGaTag(); - - const factory = SplitFactory({ - ...config, - startup: { - eventsFirstPushWindow: 1000, - }, - scheduler: { - eventsQueueSize: hits.length, - } - }); - client = factory.client(); - - client.ready().then(() => { - addGaTag(); - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - gaSpy(); - - window.ga('require', 'splitTracker'); - hits.forEach(hit => window.ga('send', hit)); - - }); - }); - - // test `hits` flag - assert.test(t => { - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHits = window.gaSpy.getHits(); - - t.equal(resp.filter(event => event.eventTypeId === 'ga.pageview').length, 0, 'No events associated to GA hits must be sent'); - t.equal(resp.filter(event => event.eventTypeId === 'some_event').length, 1, 'Tracked events must be sent to Split'); - t.equal(sentHits.length, 1, 'Hits must be sent to GA'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - // siteSpeedSampleRate set to 0 to never send a site speed timing hit - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - window.ga('require', 'splitTracker', { hits: false }); - window.ga('send', 'pageview'); - - const factory = SplitFactory(config); - client = factory.client(); - client.track('some_event'); - - }); - - // test 'autoRequire' script placed right after GA script tag. - // We get same result if it is placed right before, and also applies for Universal Analytics configured with GTM and gtag.js tags. - // If it is executed asynchronously, trackers creation might be missed. - assert.test(t => { - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - const resp = JSON.parse(opts.body); - const sentHitsTracker1 = window.gaSpy.getHits('tracker1'); - const sentHitsTracker2 = window.gaSpy.getHits('tracker2'); - - t.equal(resp.length, sentHitsTracker1.length + sentHitsTracker2.length, 'All hits of all trackers are captured as Split events'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - return 200; - }); - - gaTag(); - - // Run autoRequire iife: - // require('@splitsoftware/splitio-commons/src/integrations/ga/autoRequire'); - require('../../../scripts/ga-to-split-autorequire'); - - window.ga('create', 'UA-00000000-1', { name: 'tracker1', cookieDomain: 'auto', siteSpeedSampleRate: 0 }); - - gaSpy(['tracker1']); - - window.ga('tracker1.send', 'event', 'mycategory', 'myaction1'); // Captured - - const factory = SplitFactory({ - ...config, - integrations: [{ - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - autoRequire: true - }], - }); - - window.ga('tracker1.send', 'event', 'mycategory', 'myaction2'); // Captured - window.ga('create', 'UA-00000001-1', 'auto', 'tracker2', { siteSpeedSampleRate: 0 }); // New tracker - gaSpy(['tracker2'], false); - window.ga('tracker2.send', 'event', 'mycategory', 'myaction3'); // Captured - - client = factory.client(); - - }); - -} diff --git a/src/__tests__/gaIntegration/gaTestUtils.js b/src/__tests__/gaIntegration/gaTestUtils.js deleted file mode 100644 index e0aac43e3..000000000 --- a/src/__tests__/gaIntegration/gaTestUtils.js +++ /dev/null @@ -1,94 +0,0 @@ -export const DEFAULT_TRACKER = 't0'; - -const HIT_FIELDS = ['hitType', 'nonInteraction']; -const EVENT_FIELDS = ['eventCategory', 'eventAction', 'eventLabel', 'eventValue']; -const FIELDS = [...HIT_FIELDS, ...EVENT_FIELDS]; // List of hit fields to spy, which are the ones set by the default SplitToGa mapper. - -let hits = {}; - -/** - * Spy ga hits per tracker. - * - * @param {string[]} trackerNames names of the trackers to spy. If not provided, it spies the default tracker. i.e., `gaSpy()` is equivalent to `gaSpy(['t0'])`. - * @param {boolean} resetSpy true to reset the list of captured hits. - * - * @see {@link https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference} - */ -export function gaSpy(trackerNames = [DEFAULT_TRACKER], resetSpy = true) { - - if (resetSpy) hits = {}; - - // access ga via its gaAlias, accounting for the possibility that the global command queue - // has been renamed or not yet defined (analytics.js mutates window[gaAlias] reference) - const gaAlias = window['GoogleAnalyticsObject'] || 'ga'; - - if (typeof window[gaAlias] === 'function') { - window[gaAlias](function () { - // We try-catch the following code, since errors are catched by `ga` and thus cannot be traced for debugging. - try { - trackerNames.forEach(trackerName => { - const trackerToSniff = window[gaAlias].getByName(trackerName); - hits[trackerName] = []; - const originalSendHitTask = trackerToSniff.get('sendHitTask'); - trackerToSniff.set('sendHitTask', function (model) { - originalSendHitTask(model); - const hit = {}; - FIELDS.forEach(fieldName => { - hit[fieldName] = model.get(fieldName); - }); - hits[trackerName].push(hit); - }); - }); - } catch (err) { - console.log(err); - } - }); - } else { - console.error('GA command queue was not found'); - } - - window.gaSpy = { - // getHits may return `undefined` if `ga` is not ready or `trackerName` is not in the list of `trackerNames` - getHits: function (trackerName = DEFAULT_TRACKER) { - const trackerHits = hits[trackerName]; - return trackerHits; - } - }; - - return window.gaSpy; -} - -/** - * Add Google Analytics tag, removing previous one if exists. - * - * @see {@link https://developers.google.com/analytics/devguides/collection/analyticsjs#the_google_analytics_tag} - */ -export function gaTag(gaAlias = 'ga') { - removeGaTag(gaAlias); - addGaTag(gaAlias); -} - -/** - * Add Google Analytics tag. - */ -export function addGaTag(gaAlias = 'ga') { - (function (i, s, o, g, r, a, m) { - i['GoogleAnalyticsObject'] = r; - i[r] = i[r] || function () { - (i[r].q = i[r].q || []).push(arguments); - }, - i[r].l = 1 * new Date(); - a = s.createElement(o), - m = s.getElementsByTagName(o)[0]; - a.async = 1; - a.src = g; - m.parentNode.insertBefore(a, m); - })(window, document, 'script', 'https://www.google-analytics.com/analytics.js', gaAlias); -} - -/** - * Remove Google Analytics command queue. - */ -export function removeGaTag(gaAlias = 'ga') { - window[window['GoogleAnalyticsObject'] || gaAlias] = undefined; -} diff --git a/src/__tests__/gaIntegration/split-to-ga.spec.js b/src/__tests__/gaIntegration/split-to-ga.spec.js deleted file mode 100644 index 1285d6f01..000000000 --- a/src/__tests__/gaIntegration/split-to-ga.spec.js +++ /dev/null @@ -1,438 +0,0 @@ -import sinon from 'sinon'; -import { SplitFactory } from '../../'; -import { settingsFactory } from '../../settings'; -import { gaSpy, gaTag, removeGaTag, addGaTag } from './gaTestUtils'; -import { SPLIT_IMPRESSION, SPLIT_EVENT, DEBUG } from '@splitsoftware/splitio-commons/src/utils/constants'; -import { url } from '../testUtils'; - -function countImpressions(parsedImpressionsBulkPayload) { - return parsedImpressionsBulkPayload - .reduce((accumulator, currentValue) => { return accumulator + currentValue.i.length; }, 0); -} - -const config = { - core: { - authorizationKey: '', - key: 'facundo@split.io', - trafficType: 'user', - }, - integrations: [{ - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - }], - scheduler: { - impressionsRefreshRate: 0.2, - eventsQueueSize: 1, - }, - streamingEnabled: false, - sync: { - impressionsMode: DEBUG, - } -}; - -const settings = settingsFactory(config); - -export default function (fetchMock, assert) { - - // test default behavior - assert.test(t => { - - let client; - - // Generator to synchronize the call of t.end() when both impressions and events endpoints were invoked. - const finish = (function* () { - yield; - t.equal(window.gaSpy.getHits().length, 3, 'Total hits are 3: pageview, split event and impression'); - setTimeout(() => { - client.destroy(); - t.end(); - }); - })(); - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - // we can assert payload and ga hits, once ga is ready and after `SplitToGa.queue`, that is timeout wrapped, make to the queue stack. - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentImpressionHits = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-impression'); - - t.equal(sentImpressions, 1, 'Number of impressions'); - t.equal(sentImpressions, sentImpressionHits.length, `Number of sent impression hits must be equal to the number of impressions (${sentImpressions})`); - - finish.next(); - }); - }); - return 200; - }); - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentEvents = resp.length; - const sentEventHits = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-event'); - - t.equal(sentEvents, 1, 'Number of events'); - t.equal(sentEvents, sentEventHits.length, `Number of sent event hits must be equal to sent events: (${sentEvents})`); - - finish.next(); - }); - }, 10); - return 200; - }); - - gaTag(); - - // siteSpeedSampleRate set to 0 to never send a site speed timing hit - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - window.ga('send', 'pageview'); - - const factory = SplitFactory(config); - client = factory.client(); - client.ready().then(() => { - client.track('some_event'); - client.getTreatment('hierarchical_splits_test'); - }); - - }); - - // test default behavior in multiple trackers, with multiple impressions, and GA in a different global variable - assert.test(t => { - - let client; - const numOfEvaluations = 4; - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - setTimeout(() => { - window.other_location_for_ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentHitsTracker1 = window.gaSpy.getHits('myTracker1'); - const sentHitsTracker2 = window.gaSpy.getHits('myTracker2'); - - t.equal(sentImpressions, numOfEvaluations, 'Number of impressions equals the number of evaluations'); - t.equal(sentImpressions, sentHitsTracker1.length, 'Number of sent hits must be equal to the number of impressions'); - t.equal(sentImpressions, sentHitsTracker2.length, 'Number of sent hits must be equal to the number of impressions'); - - setTimeout(() => { - client.destroy(); - t.end(); - }); - }); - }); - return 200; - }); - - gaTag('other_location_for_ga'); - - window.other_location_for_ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - window.other_location_for_ga('create', 'UA-00000001-1', 'example1.com', 'myTracker1', { siteSpeedSampleRate: 0 }); - window.other_location_for_ga('create', 'UA-00000002-1', 'example2.com', 'myTracker2', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker1', 'myTracker2']); - - const factory = SplitFactory({ - ...config, - core: { - ...config.core, - authorizationKey: '', - }, - integrations: [{ - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker1'], - }, { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker2'], - }], - }); - client = factory.client(); - client.ready().then(() => { - for (let i = 0; i < numOfEvaluations; i++) - client.getTreatment('split_with_config'); - }); - - }); - - // test several SplitToGa integration items, with custom filter and mapper - assert.test(t => { - - let client; - const numOfEvaluations = 4; - const numOfEvents = 3; - - // Generator to synchronize the call of t.end() when both impressions and events endpoints were invoked. - const finish = (function* () { - yield; - setTimeout(() => { - client.destroy(); - t.end(); - }); - })(); - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentImpressionHitsTracker3 = window.gaSpy.getHits('myTracker3').filter(hit => hit.eventCategory === 'split-impression'); - const sentImpressionHitsTracker4 = window.gaSpy.getHits('myTracker4').filter(hit => hit.eventCategory === 'split-impression'); - - t.equal(sentImpressionHitsTracker3.length, sentImpressions, 'For tracker3, no impressions are filtered'); - t.equal(sentImpressionHitsTracker4.length, 0, 'For tracker4, all impressions are filtered'); - - finish.next(); - }); - }); - return 200; - }); - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentEvents = resp.length; - const sentEventHitsTracker3 = window.gaSpy.getHits('myTracker3').filter(hit => hit.eventCategory === 'mycategory'); - const sentEventHitsTracker4 = window.gaSpy.getHits('myTracker4').filter(hit => hit.eventCategory === 'mycategory'); - - t.equal(sentEventHitsTracker3.length, 0, 'For tracker3, all events are filtered'); - t.equal(sentEventHitsTracker4.length, sentEvents, 'For tracker4, no events are filtered'); - - finish.next(); - }); - }, 10); - return 200; - }); - - gaTag(); - - window.ga('create', 'UA-00000003-1', 'example3.com', 'myTracker3', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000004-1', 'example4.com', 'myTracker4', { siteSpeedSampleRate: 0 }); - - gaSpy(['myTracker3', 'myTracker4']); - - const onlyImpressionsFilter = ({ type }) => type === SPLIT_IMPRESSION; - const onlyEventsMapper = function ({ payload, type }) { - return type === SPLIT_EVENT ? - { hitType: 'event', eventCategory: 'mycategory', eventAction: payload.eventTypeId } : - undefined; - }; - const factory = SplitFactory({ - ...config, - core: { - ...config.core, - authorizationKey: '', - }, - scheduler: { - impressionsRefreshRate: 0.2, - eventsQueueSize: numOfEvents, - }, - integrations: [{ - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker3'], - filter: onlyImpressionsFilter, - }, { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker4'], - mapper: onlyEventsMapper, - }], - }); - client = factory.client(); - client.ready().then(() => { - for (let i = 0; i < numOfEvaluations; i++) { - client.getTreatment('split_with_config'); - } - for (let i = 0; i < numOfEvents; i++) { - client.track('eventType'); - } - }); - - }); - - // exception in custom mapper or invalid mapper result must not send a hit - assert.test(t => { - - const logSpy = sinon.spy(console, 'log'); - const error = 'some error'; - let client; - const numOfEvaluations = 1; - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentHitsDefault = window.gaSpy.getHits(); - const sentHitsTracker1 = window.gaSpy.getHits('myTracker1'); - const sentHitsTracker2 = window.gaSpy.getHits('myTracker2'); - - t.equal(sentImpressions, numOfEvaluations, 'Number of impressions equals the number of evaluations'); - t.equal(sentHitsDefault.length, 0, 'No hits sent if custom mapper throws error'); - t.equal(sentHitsTracker1.length, 0, 'No hits sent if custom mapper returns invalid result'); - t.equal(sentHitsTracker2.length, numOfEvaluations, 'Number of sent hits must be equal to the number of impressions'); - - setTimeout(() => { - t.ok(logSpy.calledWith(`[WARN] splitio => split-to-ga: queue method threw: ${error}. No hit was sent.`)); - t.ok(logSpy.calledWith('[WARN] splitio => split-to-ga: your custom mapper returned an invalid FieldsObject instance. It must be an object with at least a `hitType` field.')); - client.destroy(); - logSpy.restore(); - t.end(); - }); - }); - }); - return 200; - }); - - gaTag(); - - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000001-1', 'example1.com', 'myTracker1', { siteSpeedSampleRate: 0 }); - window.ga('create', 'UA-00000002-1', 'example2.com', 'myTracker2', { siteSpeedSampleRate: 0 }); - - gaSpy(['t0', 'myTracker1', 'myTracker2']); - - const factory = SplitFactory({ - ...config, - debug: true, - integrations: [{ - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - mapper: function () { throw error; }, - }, { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker1'], - mapper: function () { return {}; }, - }, { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - trackerNames: ['myTracker2'], - mapper: function () { return { hitType: 'event', eventCategory: 'my-split-impression', eventAction: 'some-action' }; }, - }], - }); - client = factory.client(); - client.ready().then(() => { - for (let i = 0; i < numOfEvaluations; i++) - client.getTreatment('split_with_config'); - }); - - }); - - // Split created before GA initialized - assert.test(t => { - - const logSpy = sinon.spy(console, 'log'); - let client; - const numOfEvaluations = 1; - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentHitsDefault = window.gaSpy.getHits(); - - t.equal(sentImpressions, numOfEvaluations, 'Number of impressions equals the number of evaluations'); - t.equal(sentHitsDefault.length, numOfEvaluations, 'Hits sent if ga initialized before Split evaluation (client.getTreatment***)'); - - setTimeout(() => { - client.destroy().then(() => { - logSpy.restore(); - t.end(); - }); - }); - }); - }); - return 200; - }); - - removeGaTag(); - - const factory = SplitFactory({ - ...config, - debug: true, - }); - t.ok(logSpy.calledWith('[WARN] splitio => split-to-ga: `ga` command queue not found. No hits will be sent until it is available.'), 'warning GA not found'); - - client = factory.client(); - client.ready().then(() => { - for (let i = 0; i < numOfEvaluations; i++) - client.getTreatment('split_with_config'); - }); - - addGaTag(); - - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - - gaSpy(); - - }); - - // test `events` and `impressions` flags - assert.test(t => { - - let client; - - // Generator to synchronize the call of t.end() when both impressions and events endpoints were invoked. - const finish = (function* () { - yield; - t.equal(window.gaSpy.getHits().length, 1, 'Total hits are 1: pageview'); - setTimeout(() => { - client.destroy(); - t.end(); - }); - })(); - - fetchMock.postOnce(url(settings, '/testImpressions/bulk'), (url, opts) => { - // we can assert payload and ga hits, once ga is ready and after `SplitToGa.queue`, that is timeout wrapped, make to the queue stack. - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentImpressions = countImpressions(resp); - const sentImpressionHits = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-impression'); - - t.equal(sentImpressions, 1, 'Number of impressions'); - t.equal(sentImpressionHits.length, 0, 'No hits associated to Split impressions must be sent'); - - finish.next(); - }); - }); - return 200; - }); - - fetchMock.postOnce(url(settings, '/events/bulk'), (url, opts) => { - setTimeout(() => { - window.ga(() => { - const resp = JSON.parse(opts.body); - const sentEvents = resp.length; - const sentEventHits = window.gaSpy.getHits().filter(hit => hit.eventCategory === 'split-event'); - - t.equal(sentEvents, 1, 'Number of events'); - t.equal(sentEventHits.length, 0, 'No hits associated to Split events must be sent'); - - finish.next(); - }); - }); - return 200; - }); - - gaTag(); - window.ga('create', 'UA-00000000-1', 'auto', { siteSpeedSampleRate: 0 }); - gaSpy(); - window.ga('send', 'pageview'); - - const factory = SplitFactory({ - ...config, - integrations: [{ - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - events: false, - impressions: false, - }] - }); - client = factory.client(); - client.ready().then(() => { - client.track('some_event'); - client.getTreatment('hierarchical_splits_test'); - }); - - }); -} diff --git a/src/__tests__/online/browser.spec.js b/src/__tests__/online/browser.spec.js index e3c6ebe86..05fd60de2 100644 --- a/src/__tests__/online/browser.spec.js +++ b/src/__tests__/online/browser.spec.js @@ -10,7 +10,7 @@ import telemetrySuite from '../browserSuites/telemetry.spec'; import impressionsListenerSuite from '../browserSuites/impressions-listener.spec'; import readinessSuite from '../browserSuites/readiness.spec'; import readyFromCache from '../browserSuites/ready-from-cache.spec'; -import { withoutBindingTT, bindingTT } from '../browserSuites/events.spec'; +import { withoutBindingTT } from '../browserSuites/events.spec'; import sharedInstantiationSuite from '../browserSuites/shared-instantiation.spec'; import managerSuite from '../browserSuites/manager.spec'; import ignoreIpAddressesSettingSuite from '../browserSuites/ignore-ip-addresses-setting.spec'; @@ -112,10 +112,8 @@ tape('## E2E CI Tests ##', function (assert) { assert.test('E2E / Telemetry', telemetrySuite.bind(null, fetchMock)); /* Check events */ assert.test('E2E / Events', withoutBindingTT.bind(null, fetchMock)); - assert.test('E2E / Events with TT bound', bindingTT.bind(null, fetchMock)); /* Check shared clients */ - assert.test('E2E / Shared instances', sharedInstantiationSuite.bind(null, false, false, fetchMock)); - assert.test('E2E / Shared instances with Traffic Type on factory settings', sharedInstantiationSuite.bind(null, true, false, fetchMock)); + assert.test('E2E / Shared instances', sharedInstantiationSuite.bind(null, false, true, fetchMock)); /* Validate user consent */ assert.test('E2E / User consent', userConsent.bind(null, fetchMock)); /* Check basic manager functionality */ @@ -127,7 +125,7 @@ tape('## E2E CI Tests ##', function (assert) { /* Check that impressions and events are sended to backend via Beacon API or Fetch when pagehide/visibilitychange events are triggered. */ assert.test('E2E / Use Beacon API (or Fetch if not available) to send remaining impressions and events when browser page is unload or hidden', useBeaconApiSuite.bind(null, fetchMock)); assert.test('E2E / Use Beacon API DEBUG (or Fetch if not available) to send remaining impressions and events when browser page is unload or hidden', useBeaconDebugApiSuite.bind(null, fetchMock)); - /* Validate ready from cache behaviour (might be merged into another suite if we end up having simple behavior around it as expected) */ + /* Validate ready from cache behavior (might be merged into another suite if we end up having simple behavior around it as expected) */ assert.test('E2E / Readiness from cache', readyFromCache.bind(null, fetchMock)); /* Validate readiness with ready promises */ assert.test('E2E / Ready promise', readyPromiseSuite.bind(null, fetchMock)); diff --git a/src/__tests__/testUtils/index.js b/src/__tests__/testUtils/index.js index 7f01fc5e4..5994a3c30 100644 --- a/src/__tests__/testUtils/index.js +++ b/src/__tests__/testUtils/index.js @@ -14,7 +14,7 @@ export function nearlyEqual(actual, expected, epsilon = DEFAULT_ERROR_MARGIN) { } /** - * mock the basic behaviour for `/segmentChanges` endpoint: + * mock the basic behavior for `/segmentChanges` endpoint: * - when `?since=-1`, it returns the given segment `keys` in `added` list. * - otherwise, it returns empty `added` and `removed` lists, and the same since and till values. * diff --git a/src/factory/browser.js b/src/factory/browser.js index 9b877a36d..b06eac524 100644 --- a/src/factory/browser.js +++ b/src/factory/browser.js @@ -5,9 +5,8 @@ import { pollingManagerCSFactory } from '@splitsoftware/splitio-commons/src/sync import { InLocalStorage } from '@splitsoftware/splitio-commons/src/storages/inLocalStorage'; import { InMemoryStorageCSFactory } from '@splitsoftware/splitio-commons/src/storages/inMemory/InMemoryStorageCS'; import { sdkManagerFactory } from '@splitsoftware/splitio-commons/src/sdkManager'; -import { sdkClientMethodCSFactory } from '@splitsoftware/splitio-commons/src/sdkClient/sdkClientMethodCSWithTT'; +import { sdkClientMethodCSFactory } from '@splitsoftware/splitio-commons/src/sdkClient/sdkClientMethodCS'; import { impressionObserverCSFactory } from '@splitsoftware/splitio-commons/src/trackers/impressionObserver/impressionObserverCS'; -import { integrationsManagerFactory } from '@splitsoftware/splitio-commons/src/integrations/browser'; import { __InLocalStorageMockFactory } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/storage/storageCS'; import { sdkFactory } from '@splitsoftware/splitio-commons/src/sdkFactory'; import { LOCALHOST_MODE, STORAGE_LOCALSTORAGE } from '@splitsoftware/splitio-commons/src/utils/constants'; @@ -49,8 +48,6 @@ function getModules(settings) { SignalListener, - integrationsManagerFactory: settings.integrations && settings.integrations.length > 0 ? integrationsManagerFactory.bind(null, settings.integrations) : undefined, - impressionsObserverFactory: impressionObserverCSFactory, extraProps: (params) => { diff --git a/src/settings/__tests__/browser.spec.js b/src/settings/__tests__/browser.spec.js index 0a37e0772..481b9e95e 100644 --- a/src/settings/__tests__/browser.spec.js +++ b/src/settings/__tests__/browser.spec.js @@ -1,36 +1,6 @@ import tape from 'tape-catch'; import { settingsFactory } from '../browser'; -tape('SETTINGS / Integrations should be properly parsed', assert => { - const settings = settingsFactory({ - core: { - authorizationKey: 'dummy token' - }, - integrations: [ - { type: 'GOOGLE_ANALYTICS_TO_SPLIT', prefix: 'prefix1' }, - { type: 'INVALID_INTEGRATION', prefix: 'prefix2' }, - { type: 'SPLIT_TO_GOOGLE_ANALYTICS', prefix: 'prefix3' }, - { type: 'INVALID_INTEGRATION_2', prefix: 'prefix4' }, - {}, - 'INVALID' - ] - }); - - assert.deepEqual(settings.integrations, [ - { type: 'GOOGLE_ANALYTICS_TO_SPLIT', prefix: 'prefix1' }, - { type: 'SPLIT_TO_GOOGLE_ANALYTICS', prefix: 'prefix3' } - ], 'Filters invalid integrations from `integrations` array'); - - assert.deepEqual(settingsFactory({ - core: { - authorizationKey: 'dummy token' - }, - integrations: 'INVALID' - }).integrations, [], 'Returns an empty array if `integrations` is an invalid object'); - - assert.end(); -}); - tape('SETTINGS / Consent is overwritable and "GRANTED" by default in client-side', assert => { let settings = settingsFactory({}); assert.equal(settings.userConsent, 'GRANTED', 'userConsent defaults to granted if not provided.'); diff --git a/src/settings/browser.js b/src/settings/browser.js index d3f04443e..5a1ae432b 100644 --- a/src/settings/browser.js +++ b/src/settings/browser.js @@ -6,14 +6,12 @@ import { validateConsent } from '@splitsoftware/splitio-commons/src/utils/settin import { defaults } from './defaults/browser'; import { validateStorage } from './storage/browser'; -import { validateIntegrations } from './integrations/browser'; const params = { defaults, - acceptKey: true, acceptTT: true, // Client with bound key and optional TT + acceptKey: true, // Client with bound key runtime: validateRuntime, storage: validateStorage, - integrations: validateIntegrations, logger: validateLogger, localhost: () => LocalhostFromObject(), consent: validateConsent, diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 1e30feddf..7f7b63b6a 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.1-rc.2'; +export const packageVersion = '11.0.0-rc.0'; diff --git a/src/sync/offline/splitsParserFromFile.js b/src/sync/offline/splitsParserFromFile.js index aef992544..13f2f1c29 100644 --- a/src/sync/offline/splitsParserFromFile.js +++ b/src/sync/offline/splitsParserFromFile.js @@ -31,7 +31,7 @@ function configFilesPath(configFilePath) { } // This function is not pure nor meant to be. Here we apply modifications to cover -// for behaviour that's ensured by the BE. +// for behavior that's ensured by the BE. function arrangeConditions(mocksData) { // Iterate through each feature flag data forOwn(mocksData, data => { diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 7bdc4c834..2440be58a 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -163,7 +163,6 @@ browserSettings = { } }; // With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK -SDK = SplitFactory(browserSettings); SDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); @@ -172,7 +171,6 @@ BrowserSDK = SplitFactory(browserSettings); const instantiatedSettingsCore: { authorizationKey: string, key: SplitIO.SplitKey, - trafficType: string, labelsEnabled: boolean, IPAddressesEnabled: boolean } = SDK.settings.core; @@ -195,9 +193,8 @@ SDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager client = SDK.client(); -client = SDK.client('a customer key'); -client = SDK.client('a customer key', 'a traffic type'); manager = SDK.manager(); +manager = BrowserSDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. asyncClient = AsyncSDK.client(); asyncManager = AsyncSDK.manager(); @@ -248,72 +245,69 @@ promise = SDK.destroy(); // We can call getTreatment with or without a key. treatment = client.getTreatment(splitKey, 'mySplit'); -treatment = client.getTreatment('mySplit'); +treatment = browserClient.getTreatment('mySplit'); // Attributes parameter is optional on both signatures. treatment = client.getTreatment(splitKey, 'mySplit', attributes); -treatment = client.getTreatment('mySplit', attributes); +treatment = browserClient.getTreatment('mySplit', attributes); // We can call getTreatments with or without a key. treatments = client.getTreatments(splitKey, ['mySplit']); -treatments = client.getTreatments(['mySplit']); +treatments = browserClient.getTreatments(['mySplit']); // Attributes parameter is optional on both signatures. treatments = client.getTreatments(splitKey, ['mySplit'], attributes); -treatments = client.getTreatments(['mySplit'], attributes); +treatments = browserClient.getTreatments(['mySplit'], attributes); // We can call getTreatmentWithConfig with or without a key. treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit'); -treatmentWithConfig = client.getTreatmentWithConfig('mySplit'); +treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit'); // Attributes parameter is optional on both signatures. treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit', attributes); -treatmentWithConfig = client.getTreatmentWithConfig('mySplit', attributes); +treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit', attributes); // We can call getTreatmentsWithConfig with or without a key. treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit']); -treatmentsWithConfig = client.getTreatmentsWithConfig(['mySplit']); +treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit']); // Attributes parameter is optional on both signatures. treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); -treatmentsWithConfig = client.getTreatmentsWithConfig(['mySplit'], attributes); +treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit'], attributes); -// We can call getTreatmentsByFlagSet without a key. +// We can call getTreatmentsByFlagSet with or without a key. treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a'); -treatments = client.getTreatmentsByFlagSet('set_a'); +treatments = browserClient.getTreatmentsByFlagSet('set_a'); // Attributes parameter is optional. treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); -treatments = client.getTreatmentsByFlagSet('set_a', attributes); +treatments = browserClient.getTreatmentsByFlagSet('set_a', attributes); -// We can call getTreatmentsByFlagSets without a key. +// We can call getTreatmentsByFlagSets with or without a key. treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a']); -treatments = client.getTreatmentsByFlagSets(['set_a']); +treatments = browserClient.getTreatmentsByFlagSets(['set_a']); // Attributes parameter is optional. treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); -treatments = client.getTreatmentsByFlagSets(['set_a'], attributes); +treatments = browserClient.getTreatmentsByFlagSets(['set_a'], attributes); -// We can call getTreatmentsWithConfigByFlagSet without a key. +// We can call getTreatmentsWithConfigByFlagSet with or without a key. treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet('set_a'); +treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a'); // Attributes parameter is optional. treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet('set_a', attributes); +treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a', attributes); -// We can call getTreatmentsWithConfigByFlagSets without a key. +// We can call getTreatmentsWithConfigByFlagSets with or without a key. treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(['set_a']); +treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a']); // Attributes parameter is optional. treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(['set_a'], attributes); +treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a'], attributes); -// We can call track with or without a key. Traffic type can also be bound to the client. +// We can call track with or without a key. tracked = client.track(splitKey, 'myTrafficType', 'myEventType'); // all params -tracked = client.track('myTrafficType', 'myEventType'); // key bound, tt provided. -tracked = client.track('myEventType'); // key and tt bound. +tracked = browserClient.track('myTrafficType', 'myEventType'); // key bound, tt provided. // Value parameter is optional on all signatures. tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10); -tracked = client.track('myTrafficType', 'myEventType', 10); -tracked = client.track('myEventType', 10); +tracked = browserClient.track('myTrafficType', 'myEventType', 10); // Properties parameter is optional on all signatures. tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); -tracked = client.track('myTrafficType', 'myEventType', null, { prop1: 1, prop2: '2', prop3: false, prop4: null }); -tracked = client.track('myEventType', undefined, { prop1: 1, prop2: '2', prop3: false, prop4: null }); +tracked = browserClient.track('myTrafficType', 'myEventType', undefined, { prop1: 1, prop2: '2', prop3: false, prop4: null }); /*** Repeating tests for Async Client ***/ @@ -494,40 +488,10 @@ userConsent = BrowserSDK.UserConsent.Status.UNKNOWN; // Split filters let splitFilters: SplitIO.SplitFilter[] = [{ type: 'bySet', values: ['set_a', 'set_b'] }, { type: 'byName', values: ['my_split_1', 'my_split_1'] }, { type: 'byPrefix', values: ['my_split', 'test_split_'] }] -// Browser integrations -let fieldsObjectSample: UniversalAnalytics.FieldsObject = { hitType: 'event', eventAction: 'action' }; -let eventDataSample: SplitIO.EventData = { eventTypeId: 'someEventTypeId', value: 10, properties: {} } - -let googleAnalyticsToSplitConfig: SplitIO.IGoogleAnalyticsToSplitConfig = { - type: 'GOOGLE_ANALYTICS_TO_SPLIT', -}; -let splitToGoogleAnalyticsConfig: SplitIO.ISplitToGoogleAnalyticsConfig = { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', -}; - -let customGoogleAnalyticsToSplitConfig: SplitIO.IGoogleAnalyticsToSplitConfig = { - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - hits: false, - filter: function (model: UniversalAnalytics.Model): boolean { return true; }, - mapper: function (model: UniversalAnalytics.Model, defaultMapping: SplitIO.EventData): SplitIO.EventData { return eventDataSample; }, - prefix: 'PREFIX', - identities: [{ key: 'key1', trafficType: 'tt1' }, { key: 'key2', trafficType: 'tt2' }], - autoRequire: true -}; -let customSplitToGoogleAnalyticsConfig: SplitIO.ISplitToGoogleAnalyticsConfig = { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - events: false, - impressions: true, - filter: function (model: SplitIO.IntegrationData): boolean { return true; }, - mapper: function (model: SplitIO.IntegrationData, defaultMapping: UniversalAnalytics.FieldsObject): UniversalAnalytics.FieldsObject { return fieldsObjectSample; }, - trackerNames: ['t0', 'myTracker'], -} - let fullBrowserSettings: SplitIO.IBrowserSettings = { core: { authorizationKey: 'asd', key: 'asd', - trafficType: 'myTT', labelsEnabled: false }, scheduler: { @@ -562,7 +526,6 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { }, impressionListener: impressionListener, debug: true, - integrations: [googleAnalyticsToSplitConfig, splitToGoogleAnalyticsConfig, customGoogleAnalyticsToSplitConfig, customSplitToGoogleAnalyticsConfig], streamingEnabled: true, sync: { splitFilters: splitFilters, @@ -575,7 +538,6 @@ let fullBrowserSettings: SplitIO.IBrowserSettings = { userConsent: 'GRANTED' }; fullBrowserSettings.storage.type = 'MEMORY'; -fullBrowserSettings.integrations[0].type = 'GOOGLE_ANALYTICS_TO_SPLIT'; fullBrowserSettings.userConsent = 'DECLINED'; fullBrowserSettings.userConsent = 'UNKNOWN'; diff --git a/types/client/index.d.ts b/types/client/index.d.ts index d94090d91..ba6d4a9d4 100644 --- a/types/client/index.d.ts +++ b/types/client/index.d.ts @@ -6,7 +6,7 @@ export = JsSdk; declare module JsSdk { /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ diff --git a/types/index.d.ts b/types/index.d.ts index 78c5d824f..adaf540dd 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -8,19 +8,19 @@ export = JsSdk; declare module JsSdk { /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.ISDK; /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ diff --git a/types/server/index.d.ts b/types/server/index.d.ts index a9a145a2f..f39f44bf6 100644 --- a/types/server/index.d.ts +++ b/types/server/index.d.ts @@ -6,13 +6,13 @@ export = JsSdk; declare module JsSdk { /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; /** - * Split.io sdk factory function. + * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ diff --git a/types/splitio.d.ts b/types/splitio.d.ts index e5fc78c28..7abd18d7c 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -2,7 +2,6 @@ // Project: http://www.split.io/ // Definitions by: Nico Zelaya -/// import { RedisOptions } from "ioredis"; import { RequestOptions } from "http"; @@ -63,7 +62,6 @@ interface ISettings { readonly core: { authorizationKey: string, key: SplitIO.SplitKey, - trafficType: string, labelsEnabled: boolean, IPAddressesEnabled: boolean }, @@ -354,7 +352,7 @@ interface INodeBasicSettings extends ISharedSettings { eventsQueueSize?: number, /** * For mocking/testing only. The SDK will refresh the features mocked data when mode is set to "localhost" by defining the key. - * For more information @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode} + * For more information see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode} * @property {number} offlineRefreshRate * @default 15 */ @@ -373,7 +371,8 @@ interface INodeBasicSettings extends ISharedSettings { */ core: { /** - * Your SDK key. More information: @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} + * Your SDK key. + * @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} * @property {string} authorizationKey */ authorizationKey: string, @@ -421,7 +420,7 @@ interface INodeBasicSettings extends ISharedSettings { */ mode?: SDKMode, /** - * Mocked features file path. For testing purposses only. For using this you should specify "localhost" as authorizationKey on core settings. + * Mocked features file path. For testing purposes only. For using this you should specify "localhost" as authorizationKey on core settings. * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode} * @property {MockedFeaturesFilePath} features * @default '$HOME/.split' @@ -440,20 +439,9 @@ interface IStatusInterface extends EventEmitter { */ Event: EventConsts, /** - * Returns a promise that resolves once the SDK has finished loading (SDK_READY event emitted) or rejected if the SDK has timedout (SDK_READY_TIMED_OUT event emitted). - * As it's meant to provide similar flexibility to the event approach, given that the SDK might be eventually ready after a timeout event, calling the `ready` method after the - * SDK had timed out will return a new promise that should eventually resolve if the SDK gets ready. - * - * Caveats: the method was designed to avoid an unhandled Promise rejection if the rejection case is not handled, so that `onRejected` handler is optional when using promises. - * However, when using async/await syntax, the rejection should be explicitly propagated like in the following example: - * ``` - * try { - * await client.ready().catch((e) => { throw e; }); - * // SDK is ready - * } catch(e) { - * // SDK has timedout - * } - * ``` + * Returns a promise that resolves once the SDK has finished loading (`SDK_READY` event emitted) or rejected if the SDK has timedout (`SDK_READY_TIMED_OUT` event emitted). + * As it's meant to provide similar flexibility to the event approach, given that the SDK might be eventually ready after a timeout event, the `ready` method will return a resolved promise once the SDK is ready. + * You must handle the promise rejection to avoid an unhandled promise rejection error, or you can set the `startup.readyTimeout` configuration option to 0 to avoid the timeout and thus the rejection. * * @function ready * @returns {Promise} @@ -500,9 +488,8 @@ interface IBasicSDK { } /****** Exposed namespace ******/ /** - * Types and interfaces for @splitsoftware/splitio package for usage when integrating javascript sdk on typescript apps. - * For the SDK package information - * @see {@link https://www.npmjs.com/package/@splitsoftware/splitio} + * Types and interfaces for `@splitsoftware/splitio` package for usage when integrating JavaScript SDK with TypeScript. + * For the SDK package information see {@link https://www.npmjs.com/package/@splitsoftware/splitio} */ declare namespace SplitIO { /** @@ -732,154 +719,6 @@ declare namespace SplitIO { interface IImpressionListener { logImpression(data: SplitIO.ImpressionData): void } - /** - * A pair of user key and it's trafficType, required for tracking valid Split events. - * @typedef {Object} Identity - * @property {string} key The user key. - * @property {string} trafficType The key traffic type. - */ - type Identity = { - key: string; - trafficType: string; - }; - /** - * Object with information about a Split event. - * @typedef {Object} EventData - */ - type EventData = { - eventTypeId: string; - value?: number; - properties?: Properties; - trafficTypeName?: string; - key?: string; - timestamp?: number; - }; - /** - * Enable 'Google Analytics to Split' integration, to track Google Analytics hits as Split events. - * - * @see {@link https://help.split.io/hc/en-us/articles/360040838752#google-analytics-to-split} - */ - interface IGoogleAnalyticsToSplitConfig { - type: 'GOOGLE_ANALYTICS_TO_SPLIT', - /** - * Optional flag to filter GA hits from being tracked as Split events. - * @property {boolean} hits - * @default true - */ - hits?: boolean, - /** - * Optional predicate used to define a custom filter for tracking GA hits as Split events. - * For example, the following filter allows to track only 'event' hits: - * `(model) => model.get('hitType') === 'event'` - * By default, all hits are tracked as Split events. - */ - filter?: (model: UniversalAnalytics.Model) => boolean, - /** - * Optional function useful when you need to modify the Split event before tracking it. - * This function is invoked with two arguments: - * 1. the GA model object representing the hit. - * 2. the default format of the mapped Split event instance. - * The return value must be a Split event, that can be the second argument or a new object. - * - * For example, the following mapper adds a custom property to events: - * `(model, defaultMapping) => { - * defaultMapping.properties.someProperty = SOME_VALUE; - * return defaultMapping; - * }` - */ - mapper?: (model: UniversalAnalytics.Model, defaultMapping: SplitIO.EventData) => SplitIO.EventData, - /** - * Optional prefix for EventTypeId, to prevent any kind of data collision between events. - * @property {string} prefix - * @default 'ga' - */ - prefix?: string, - /** - * List of Split identities (key & traffic type pairs) used to track events. - * If not provided, events are sent using the key and traffic type provided at SDK config - */ - identities?: Identity[], - /** - * Optional flag to log an error if the `auto-require` script is not detected. - * The auto-require script automatically requires the `splitTracker` plugin for created trackers, - * and should be placed right after your Google Analytics, Google Tag Manager or gtag.js script tag. - * - * @see {@link https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js} - * - * @property {boolean} autoRequire - * @default false - */ - autoRequire?: boolean, - } - /** - * Object representing the data sent by Split (events and impressions). - * @typedef {Object} IntegrationData - * @property {string} type The type of Split data, either 'IMPRESSION' or 'EVENT'. - * @property {ImpressionData | EventData} payload The data instance itself. - */ - type IntegrationData = { type: 'IMPRESSION', payload: SplitIO.ImpressionData } | { type: 'EVENT', payload: SplitIO.EventData }; - /** - * Enable 'Split to Google Analytics' integration, to track Split impressions and events as Google Analytics hits. - * - * @see {@link https://help.split.io/hc/en-us/articles/360040838752#split-to-google-analytics} - */ - interface ISplitToGoogleAnalyticsConfig { - type: 'SPLIT_TO_GOOGLE_ANALYTICS', - /** - * Optional flag to filter Split impressions from being tracked as GA hits. - * @property {boolean} impressions - * @default true - */ - impressions?: boolean, - /** - * Optional flag to filter Split events from being tracked as GA hits. - * @property {boolean} events - * @default true - */ - events?: boolean, - /** - * Optional predicate used to define a custom filter for tracking Split data (events and impressions) as GA hits. - * For example, the following filter allows to track only impressions, equivalent to setting events to false: - * `(data) => data.type === 'IMPRESSION'` - */ - filter?: (data: SplitIO.IntegrationData) => boolean, - /** - * Optional function useful when you need to modify the GA hit before sending it. - * This function is invoked with two arguments: - * 1. the input data (Split event or impression). - * 2. the default format of the mapped FieldsObject instance (GA hit). - * The return value must be a FieldsObject, that can be the second argument or a new object. - * - * For example, the following mapper adds a custom dimension to hits: - * `(data, defaultMapping) => { - * defaultMapping.dimension1 = SOME_VALUE; - * return defaultMapping; - * }` - * - * Default FieldsObject instance for data.type === 'IMPRESSION': - * `{ - * hitType: 'event', - * eventCategory: 'split-impression', - * eventAction: 'Evaluate ' + data.payload.impression.feature, - * eventLabel: 'Treatment: ' + data.payload.impression.treatment + '. Targeting rule: ' + data.payload.impression.label + '.', - * nonInteraction: true, - * }` - * Default FieldsObject instance for data.type === 'EVENT': - * `{ - * hitType: 'event', - * eventCategory: 'split-event', - * eventAction: data.payload.eventTypeId, - * eventValue: data.payload.value, - * nonInteraction: true, - * }` - */ - mapper?: (data: SplitIO.IntegrationData, defaultMapping: UniversalAnalytics.FieldsObject) => UniversalAnalytics.FieldsObject, - /** - * List of tracker names to send the hit. An empty string represents the default tracker. - * If not provided, hits are only sent to default tracker. - */ - trackerNames?: string[], - } /** * Available URL settings for the SDKs. */ @@ -916,10 +755,6 @@ declare namespace SplitIO { telemetry?: string }; - /** - * Available integration options for the browser - */ - type BrowserIntegration = ISplitToGoogleAnalyticsConfig | IGoogleAnalyticsToSplitConfig; /** * SplitFilter type. * @@ -1050,7 +885,7 @@ declare namespace SplitIO { eventsQueueSize?: number, /** * For mocking/testing only. The SDK will refresh the features mocked data when mode is set to "localhost" by defining the key. - * For more information @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode} + * For more information see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode} * @property {number} offlineRefreshRate * @default 15 */ @@ -1069,21 +904,17 @@ declare namespace SplitIO { */ core: { /** - * Your SDK key. More information: @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} + * Your SDK key. + * @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} * @property {string} authorizationKey */ authorizationKey: string, /** - * Customer identifier. Whatever this means to you. @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} + * Customer identifier. Whatever this means to you. + * @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} * @property {SplitKey} key */ key: SplitKey, - /** - * Traffic type associated with the customer identifier. @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} - * If no provided as a setting it will be required on the client.track() calls. - * @property {string} trafficType - */ - trafficType?: string, /** * Disable labels from being sent to Split backend. Labels may contain sensitive information. * @property {boolean} labelsEnabled @@ -1092,7 +923,7 @@ declare namespace SplitIO { labelsEnabled?: boolean }, /** - * Mocked features map. For testing purposses only. For using this you should specify "localhost" as authorizationKey on core settings. + * Mocked features map. For testing purposes only. For using this you should specify "localhost" as authorizationKey on core settings. * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode} */ features?: MockedFeaturesMap, @@ -1121,11 +952,6 @@ declare namespace SplitIO { * @property {Object} urls */ urls?: UrlSettings, - /** - * SDK integration settings for the Browser. - * @property {Object} integrations - */ - integrations?: BrowserIntegration[], /** * User consent status. Possible values are `'GRANTED'`, which is the default, `'DECLINED'` or `'UNKNOWN'`. * - `'GRANTED'`: the user grants consent for tracking events and impressions. The SDK sends them to Split cloud. @@ -1380,14 +1206,6 @@ declare namespace SplitIO { * @returns {IClient} The client instance. */ client(): IClient, - /** - * Returns a shared client of the SDK. For usage on the browser. - * @function client - * @param {SplitKey} key The key for the new client instance. - * @param {string=} trafficType The traffic type of the provided key. - * @returns {IClient} The client instance. - */ - client(key: SplitKey, trafficType?: string): IClient, /** * Returns a manager instance of the SDK to explore available information. * @function manager @@ -1398,9 +1216,9 @@ declare namespace SplitIO { /** * This represents the interface for the SDK instance with synchronous storage. * @interface IBrowserSDK - * @extends ISDK + * @extends IBasicSDK */ - interface IBrowserSDK extends ISDK { + interface IBrowserSDK extends IBasicSDK { /** * Returns the default client instance of the SDK. * @function client @@ -1408,13 +1226,18 @@ declare namespace SplitIO { */ client(): IBrowserClient, /** - * Returns a shared client of the SDK. For usage on the browser. + * Returns a shared client of the SDK. * @function client * @param {SplitKey} key The key for the new client instance. - * @param {string=} trafficType The traffic type of the provided key. * @returns {IBrowserClient} The client instance. */ - client(key: SplitKey, trafficType?: string): IBrowserClient + client(key: SplitKey): IBrowserClient + /** + * Returns a manager instance of the SDK to explore available information. + * @function manager + * @returns {IManager} The manager instance. + */ + manager(): IManager, /** * User consent API. * @property UserConsent @@ -1441,14 +1264,16 @@ declare namespace SplitIO { manager(): IAsyncManager } /** - * This represents the interface for the Client instance with synchronous storage. + * This represents the interface for the Client instance on server-side, where the user key is not bound to the instance and must be provided on each method call. + * This interface is available in NodeJS, or when importing the 'server' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/server'`). + * * @interface IClient * @extends IBasicClient */ interface IClient extends IBasicClient { /** * Returns a Treatment value, which is the treatment string for the given feature. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatment * @param {string} key - The string key representing the consumer. * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. @@ -1456,18 +1281,9 @@ declare namespace SplitIO { * @returns {Treatment} The treatment string. */ getTreatment(key: SplitKey, featureFlagName: string, attributes?: Attributes): Treatment, - /** - * Returns a Treatment value, which is the treatment string for the given feature. - * For usage on the Browser as we defined the key on the settings. - * @function getTreatment - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatment} The treatment string. - */ - getTreatment(featureFlagName: string, attributes?: Attributes): Treatment, /** * Returns a TreatmentWithConfig value, which is an object with both treatment and config string for the given feature. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentWithConfig * @param {string} key - The string key representing the consumer. * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. @@ -1476,20 +1292,9 @@ declare namespace SplitIO { * configuration stringified JSON (or null if there was no config for that treatment). */ getTreatmentWithConfig(key: SplitKey, featureFlagName: string, attributes?: Attributes): TreatmentWithConfig, - /** - * Returns a TreatmentWithConfig value, which an object with both treatment and config string for the given feature. - * For usage on the Browser as we defined the key on the settings. - * @function getTreatmentWithConfig - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentWithConfig} The TreatmentWithConfig, the object containing the treatment string and the - * configuration stringified JSON (or null if there was no config for that treatment). - */ - getTreatmentWithConfig(featureFlagName: string, attributes?: Attributes): TreatmentWithConfig, /** * Returns a Treatments value, which is an object map with the treatments for the given features. - * For usage on NodeJS as we don't have only one key. - * NOTE: Treatment will be a promise only in async storages, like REDIS. + * * @function getTreatments * @param {string} key - The string key representing the consumer. * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. @@ -1497,19 +1302,9 @@ declare namespace SplitIO { * @returns {Treatments} The treatments object map. */ getTreatments(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): Treatments, - /** - * Returns a Treatments value, which is an object map with the treatments for the given features. - * For usage on the Browser as we defined the key on the settings. - * NOTE: Treatment will be a promise only in async storages, like REDIS. - * @function getTreatments - * @param {Array} featureFlagNames - An array of the feature flags names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The treatments object map. - */ - getTreatments(featureFlagNames: string[], attributes?: Attributes): Treatments, /** * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsWithConfig * @param {string} key - The string key representing the consumer. * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. @@ -1517,17 +1312,9 @@ declare namespace SplitIO { * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects */ getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * For usage on the Browser as we defined the key on the settings. - * @function getTreatmentsWithConfig - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfig(featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig, /** * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. + * * @function getTreatmentsByFlagSet * @param {string} key - The string key representing the consumer. * @param {string} flagSet - The flag set name we want to get the treatments. @@ -1535,16 +1322,9 @@ declare namespace SplitIO { * @returns {Treatments} The map with all the Treatments objects */ getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments, - /** - * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. - * @function getTreatmentsByFlagSet - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSet(flagSet: string, attributes?: Attributes): Treatments, /** * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. + * * @function getTreatmentsWithConfigByFlagSet * @param {string} key - The string key representing the consumer. * @param {string} flagSet - The flag set name we want to get the treatments. @@ -1552,16 +1332,9 @@ declare namespace SplitIO { * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects */ getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. - * @function getTreatmentsWithConfigByFlagSet - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSet(flagSet: string, attributes?: Attributes): TreatmentsWithConfig, /** * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. + * * @function getTreatmentsByFlagSets * @param {string} key - The string key representing the consumer. * @param {Array} flagSets - An array of the flag set names we want to get the treatments. @@ -1569,16 +1342,9 @@ declare namespace SplitIO { * @returns {Treatments} The map with all the Treatments objects */ getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments, - /** - * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. - * @function getTreatmentsByFlagSets - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSets(flagSets: string[], attributes?: Attributes): Treatments, /** * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. + * * @function getTreatmentsWithConfigByFlagSets * @param {string} key - The string key representing the consumer. * @param {Array} flagSets - An array of the flag set names we want to get the treatments. @@ -1586,54 +1352,111 @@ declare namespace SplitIO { * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects */ getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. - * @function getTreatmentsWithConfigByFlagSets - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSets(flagSets: string[], attributes?: Attributes): TreatmentsWithConfig, /** * Tracks an event to be fed to the results product on Split user interface. - * For usage on NodeJS as we don't have only one key. + * * @function track * @param {SplitKey} key - The key that identifies the entity related to this event. - * @param {string} trafficType - The traffic type of the entity related to this event. + * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} * @param {string} eventType - The event type corresponding to this event. * @param {number=} value - The value of this event. * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. * @returns {boolean} Whether the event was added to the queue successfully or not. */ track(key: SplitIO.SplitKey, trafficType: string, eventType: string, value?: number, properties?: Properties): boolean, + } + /** + * This represents the interface for the Client instance on client-side, where the user key is bound to the instance on creation and does not need to be provided on each method call. + * This interface is the default when importing the SDK in the Browser, or when importing the 'client' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/client'`). + * + * @interface IBrowserClient + * @extends IBasicClient + */ + interface IBrowserClient extends IBasicClient { /** - * Tracks an event to be fed to the results product on Split user interface. - * For usage on the Browser as we defined the key on the settings. - * @function track - * @param {string} trafficType - The traffic type of the entity related to this event. - * @param {string} eventType - The event type corresponding to this event. - * @param {number=} value - The value of this event. - * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. - * @returns {boolean} Whether the event was added to the queue successfully or not. + * Returns a Treatment value, which is the treatment string for the given feature. + * + * @function getTreatment + * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {Treatment} The treatment string. */ - track(trafficType: string, eventType: string, value?: number, properties?: Properties): boolean, + getTreatment(featureFlagName: string, attributes?: Attributes): Treatment, + /** + * Returns a TreatmentWithConfig value, which an object with both treatment and config string for the given feature. + * + * @function getTreatmentWithConfig + * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {TreatmentWithConfig} The TreatmentWithConfig, the object containing the treatment string and the + * configuration stringified JSON (or null if there was no config for that treatment). + */ + getTreatmentWithConfig(featureFlagName: string, attributes?: Attributes): TreatmentWithConfig, + /** + * Returns a Treatments value, which is an object map with the treatments for the given features. + * + * @function getTreatments + * @param {Array} featureFlagNames - An array of the feature flags names we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {Treatments} The treatments object map. + */ + getTreatments(featureFlagNames: string[], attributes?: Attributes): Treatments, + /** + * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. + * + * @function getTreatmentsWithConfig + * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects + */ + getTreatmentsWithConfig(featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig, + /** + * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. + * + * @function getTreatmentsByFlagSet + * @param {string} flagSet - The flag set name we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {Treatments} The map with all the Treatments objects + */ + getTreatmentsByFlagSet(flagSet: string, attributes?: Attributes): Treatments, + /** + * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. + * + * @function getTreatmentsWithConfigByFlagSet + * @param {string} flagSet - The flag set name we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects + */ + getTreatmentsWithConfigByFlagSet(flagSet: string, attributes?: Attributes): TreatmentsWithConfig, + /** + * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. + * + * @function getTreatmentsByFlagSets + * @param {Array} flagSets - An array of the flag set names we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {Treatments} The map with all the Treatments objects + */ + getTreatmentsByFlagSets(flagSets: string[], attributes?: Attributes): Treatments, + /** + * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. + * + * @function getTreatmentsWithConfigByFlagSets + * @param {Array} flagSets - An array of the flag set names we want to get the treatments. + * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. + * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects + */ + getTreatmentsWithConfigByFlagSets(flagSets: string[], attributes?: Attributes): TreatmentsWithConfig, /** * Tracks an event to be fed to the results product on Split user interface. - * For usage on the Browser if we defined the key and also the trafficType on the settings. + * * @function track + * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} * @param {string} eventType - The event type corresponding to this event. * @param {number=} value - The value of this event. * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. * @returns {boolean} Whether the event was added to the queue successfully or not. */ - track(eventType: string, value?: number, properties?: Properties): boolean - } - /** - * This represents the interface for the Client instance with attributes binding. - * @interface IBrowserClient - * @Extends IClient - */ - interface IBrowserClient extends IClient { + track(trafficType: string, eventType: string, value?: number, properties?: Properties): boolean, /** * Add an attribute to client's in memory attributes storage. * @@ -1677,15 +1500,17 @@ declare namespace SplitIO { clearAttributes(): boolean } /** - * This represents the interface for the Client instance with asynchronous storage. + * This represents the interface for the Client instance on server-side with asynchronous storage, like REDIS. + * User key is not bound to the instance and must be provided on each method call, which returns a promise. + * This interface is available in NodeJS, or when importing the 'server' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/server'`). + * * @interface IAsyncClient * @extends IBasicClient */ interface IAsyncClient extends IBasicClient { /** * Returns a Treatment value, which will be (or eventually be) the treatment string for the given feature. - * For usage on NodeJS as we don't have only one key. - * NOTE: Treatment will be a promise only in async storages, like REDIS. + * * @function getTreatment * @param {string} key - The string key representing the consumer. * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. @@ -1695,8 +1520,7 @@ declare namespace SplitIO { getTreatment(key: SplitKey, featureFlagName: string, attributes?: Attributes): AsyncTreatment, /** * Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for the given feature. - * For usage on NodeJS as we don't have only one key. - * NOTE: Treatment will be a promise only in async storages, like REDIS. + * * @function getTreatmentWithConfig * @param {string} key - The string key representing the consumer. * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. @@ -1706,7 +1530,7 @@ declare namespace SplitIO { getTreatmentWithConfig(key: SplitKey, featureFlagName: string, attributes?: Attributes): AsyncTreatmentWithConfig, /** * Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the given features. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatments * @param {string} key - The string key representing the consumer. * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. @@ -1716,7 +1540,7 @@ declare namespace SplitIO { getTreatments(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatments, /** * Returns a TreatmentsWithConfig value, which will be (or eventually be) an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsWithConfig * @param {string} key - The string key representing the consumer. * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. @@ -1726,7 +1550,7 @@ declare namespace SplitIO { getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatmentsWithConfig, /** * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsByFlagSet * @param {string} key - The string key representing the consumer. * @param {string} flagSet - The flag set name we want to get the treatments. @@ -1736,7 +1560,7 @@ declare namespace SplitIO { getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatments, /** * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsWithConfigByFlagSet * @param {string} flagSet - The flag set name we want to get the treatments. * @param {string} key - The string key representing the consumer. @@ -1746,7 +1570,7 @@ declare namespace SplitIO { getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatmentsWithConfig, /** * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsByFlagSets * @param {string} key - The string key representing the consumer. * @param {Array} flagSets - An array of the flag set names we want to get the treatments. @@ -1756,7 +1580,7 @@ declare namespace SplitIO { getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatments, /** * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. - * For usage on NodeJS as we don't have only one key. + * * @function getTreatmentsWithConfigByFlagSets * @param {string} key - The string key representing the consumer. * @param {Array} flagSets - An array of the flag set names we want to get the treatments. @@ -1766,9 +1590,10 @@ declare namespace SplitIO { getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatmentsWithConfig, /** * Tracks an event to be fed to the results product on Split user interface, and returns a promise to signal when the event was successfully queued (or not). + * * @function track * @param {SplitKey} key - The key that identifies the entity related to this event. - * @param {string} trafficType - The traffic type of the entity related to this event. + * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} * @param {string} eventType - The event type corresponding to this event. * @param {number=} value - The value of this event. * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. From aaad4a23c796af3b036ad112e09a5c740fd84eea Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 8 Oct 2024 17:55:11 -0300 Subject: [PATCH 39/58] Remove lib folder --- lib/factory/package.json | 4 ---- lib/platform/getEventSource/package.json | 4 ---- lib/platform/getFetch/package.json | 4 ---- lib/platform/package.json | 4 ---- lib/settings/package.json | 4 ---- 5 files changed, 20 deletions(-) delete mode 100644 lib/factory/package.json delete mode 100644 lib/platform/getEventSource/package.json delete mode 100644 lib/platform/getFetch/package.json delete mode 100644 lib/platform/package.json delete mode 100644 lib/settings/package.json diff --git a/lib/factory/package.json b/lib/factory/package.json deleted file mode 100644 index a19625907..000000000 --- a/lib/factory/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./node.js", - "browser": "./browser.js" -} diff --git a/lib/platform/getEventSource/package.json b/lib/platform/getEventSource/package.json deleted file mode 100644 index a19625907..000000000 --- a/lib/platform/getEventSource/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./node.js", - "browser": "./browser.js" -} diff --git a/lib/platform/getFetch/package.json b/lib/platform/getFetch/package.json deleted file mode 100644 index a19625907..000000000 --- a/lib/platform/getFetch/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./node.js", - "browser": "./browser.js" -} diff --git a/lib/platform/package.json b/lib/platform/package.json deleted file mode 100644 index a19625907..000000000 --- a/lib/platform/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./node.js", - "browser": "./browser.js" -} diff --git a/lib/settings/package.json b/lib/settings/package.json deleted file mode 100644 index a19625907..000000000 --- a/lib/settings/package.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "main": "./node.js", - "browser": "./browser.js" -} From 7c0d0506d26249e5be5a9124edb28a01a5070357 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 8 Oct 2024 18:29:29 -0300 Subject: [PATCH 40/58] rc --- .github/workflows/ci-cd.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..e90c20e76 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/breaking_changes' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/breaking_changes' }} strategy: matrix: environment: From 3c1034b0dd9f7154eb2312b68f9d465773998ff2 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 9 Oct 2024 15:30:56 -0300 Subject: [PATCH 41/58] Update changelog entry --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 12 +++++++++--- types/splitio.d.ts | 12 +++++++++++- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index e90c20e76..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/breaking_changes' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/breaking_changes' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: diff --git a/CHANGES.txt b/CHANGES.txt index 6ec22cc7b..bb8faf1d9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,9 +2,15 @@ - Added support for targeting rules based on large segments for browsers. - Added `factory.destroy()` method, which invokes the `destroy` method of all clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 2.0.0 that includes major updates and updated some transitive dependencies for vulnerability fixes. + - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. - BREAKING CHANGES: - - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. - - Drop support for NodeJS v6. The SDK now requires NodeJS v14 or above. + - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. + - Removed internal ponyfills for the `Map`, `Set`, and `Array.from` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. + - Removed the deprecated `GOOGLE_ANALYTICS_TO_SPLIT` and `SPLIT_TO_GOOGLE_ANALYTICS` integrations. The `integrations` configuration option has been removed from the SDK factory configuration, along with the associated interfaces in the TypeScript definitions. + - Removed the `core.trafficType` configuration option in Browser (`SplitIO.IBrowserSettings['core']['trafficType]`) and the `trafficType` parameter from the SDK `client()` method in Browser (`SplitIO.IBrowserSDK['client']`). As a result, traffic types can no longer be bound to SDK clients, and the traffic type must be provided in the `track` method. + - TypeScript definitions: + - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted `key` and `trafficType` parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys. + - Updated the `SplitIO.IBrowserSDK` and `SplitIO.IBrowserClient` interfaces to no longer extend the `SplitIO.ISDK` and `SplitIO.IClient` interfaces respectively, as the SDK factory instance in NodeJS or server-side (`SplitIO.ISDK`) has a different API than the SDK client instance in the Browser or client-side (`SplitIO.IBrowserClient`). 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: @@ -515,7 +521,7 @@ - Bugfixing - Return correct label when consulted Split is not found. 9.1.1 (May 03, 2017) - - Bugfixing - Fixed invalid behaviour when using native Fetch API and comparing statusText + - Bugfixing - Fixed invalid behavior when using native Fetch API and comparing statusText instead of resp.ok 9.1.0 (April 21, 2017) diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 7abd18d7c..596fd9a80 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -441,7 +441,17 @@ interface IStatusInterface extends EventEmitter { /** * Returns a promise that resolves once the SDK has finished loading (`SDK_READY` event emitted) or rejected if the SDK has timedout (`SDK_READY_TIMED_OUT` event emitted). * As it's meant to provide similar flexibility to the event approach, given that the SDK might be eventually ready after a timeout event, the `ready` method will return a resolved promise once the SDK is ready. - * You must handle the promise rejection to avoid an unhandled promise rejection error, or you can set the `startup.readyTimeout` configuration option to 0 to avoid the timeout and thus the rejection. + * + * Caveats: the method was designed to avoid an unhandled Promise rejection if the rejection case is not handled, so that `onRejected` handler is optional when using promises. + * However, when using async/await syntax, the rejection should be explicitly propagated like in the following example: + * ``` + * try { + * await client.ready().catch((e) => { throw e; }); + * // SDK is ready + * } catch(e) { + * // SDK has timedout + * } + * ``` * * @function ready * @returns {Promise} From e0dd572680ebf1563ae44c08819d49b0933ecf2b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 9 Oct 2024 18:27:43 -0300 Subject: [PATCH 42/58] Update changelog entry --- CHANGES.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index bb8faf1d9..4d6b2a445 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,9 +5,9 @@ - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. - BREAKING CHANGES: - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. - - Removed internal ponyfills for the `Map`, `Set`, and `Array.from` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. + - Removed internal ponyfills for the `Map` and `Set` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. - Removed the deprecated `GOOGLE_ANALYTICS_TO_SPLIT` and `SPLIT_TO_GOOGLE_ANALYTICS` integrations. The `integrations` configuration option has been removed from the SDK factory configuration, along with the associated interfaces in the TypeScript definitions. - - Removed the `core.trafficType` configuration option in Browser (`SplitIO.IBrowserSettings['core']['trafficType]`) and the `trafficType` parameter from the SDK `client()` method in Browser (`SplitIO.IBrowserSDK['client']`). As a result, traffic types can no longer be bound to SDK clients, and the traffic type must be provided in the `track` method. + - Removed the `core.trafficType` configuration option (`SplitIO.IBrowserSettings['core']['trafficType]`) and the `trafficType` parameter from the SDK `client()` method in Browser (`SplitIO.IBrowserSDK['client']`). As a result, traffic types can no longer be bound to SDK clients, and the traffic type must be provided in the `track` method. - TypeScript definitions: - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted `key` and `trafficType` parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys. - Updated the `SplitIO.IBrowserSDK` and `SplitIO.IBrowserClient` interfaces to no longer extend the `SplitIO.ISDK` and `SplitIO.IClient` interfaces respectively, as the SDK factory instance in NodeJS or server-side (`SplitIO.ISDK`) has a different API than the SDK client instance in the Browser or client-side (`SplitIO.IBrowserClient`). From 9dce4023ef3212a2c831d55fdeec9b37b6147a00 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 18 Oct 2024 12:29:02 -0300 Subject: [PATCH 43/58] Update ts-test. Add tests for lazy init --- CHANGES.txt | 2 +- package-lock.json | 18 ++-- package.json | 4 +- .../browserSuites/ready-promise.spec.js | 2 +- src/__tests__/nodeSuites/lazy-init.spec.js | 89 +++++++++++++++++++ src/__tests__/online/node.spec.js | 9 +- src/settings/defaults/version.js | 2 +- ts-tests/index.ts | 2 +- types/splitio.d.ts | 6 ++ 9 files changed, 116 insertions(+), 18 deletions(-) create mode 100644 src/__tests__/nodeSuites/lazy-init.spec.js diff --git a/CHANGES.txt b/CHANGES.txt index f5569d556..51c6f7ee2 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -10.29.0 (September XX, 2024) +10.29.0 (October XX, 2024) - Added `factory.destroy()` method, which invokes the `destroy` method on all SDK clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 1.18.0 that includes minor updates: - Added support for targeting rules based on large segments for browsers. diff --git a/package-lock.json b/package-lock.json index 4fce49522..b510d72d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "10.28.1-rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "10.28.1-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.1", + "@splitsoftware/splitio-commons": "1.17.1-rc.3", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", - "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", + "version": "1.17.1-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.3.tgz", + "integrity": "sha512-cPjTdDtYHejjefNvyNUZrvhYSwe6ElWoCdU5l05XmMMHv4TJiDVWMP3opes6FulI0hYKjC6za0gqlR3H+kXEUg==", "dependencies": { "tslib": "^2.3.1" }, @@ -8528,9 +8528,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.1.tgz", - "integrity": "sha512-mmDcWW2iyqQF/FzLgPoRA3KXpvswk/sDIhQGWTg3WPkapnA+e4WXb+U/TSGGB/Ig88NlM76FlxMDkrHnBayDXg==", + "version": "1.17.1-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.3.tgz", + "integrity": "sha512-cPjTdDtYHejjefNvyNUZrvhYSwe6ElWoCdU5l05XmMMHv4TJiDVWMP3opes6FulI0hYKjC6za0gqlR3H+kXEUg==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index ed707f03c..2193414df 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "10.28.1-rc.2", + "version": "10.28.1-rc.4", "description": "Split SDK", "files": [ "README.md", @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.1", + "@splitsoftware/splitio-commons": "1.17.1-rc.3", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", diff --git a/src/__tests__/browserSuites/ready-promise.spec.js b/src/__tests__/browserSuites/ready-promise.spec.js index ebcd5843c..cb13c8107 100644 --- a/src/__tests__/browserSuites/ready-promise.spec.js +++ b/src/__tests__/browserSuites/ready-promise.spec.js @@ -561,7 +561,7 @@ export default function readyPromiseAssertions(fetchMock, assert) { }); }, 0); }); - }, fromSecondsToMillis(0.2)); + }, fromSecondsToMillis(0.25)); }, 'Validate that warning messages are properly sent'); diff --git a/src/__tests__/nodeSuites/lazy-init.spec.js b/src/__tests__/nodeSuites/lazy-init.spec.js new file mode 100644 index 000000000..68e92e8f5 --- /dev/null +++ b/src/__tests__/nodeSuites/lazy-init.spec.js @@ -0,0 +1,89 @@ +import { SplitFactory as SplitFactorySS } from '../../factory/node'; +import { SplitFactory as SplitFactoryCS } from '../../factory/browser'; + +// Tests should finish without dangling timers or requests +export default function (settings, fetchMock, t) { + + t.test('Server-side', async (assert) => { + let splitio; + + for (let i = 0; i < 100; i++) { + splitio = SplitFactorySS({ + core: { + authorizationKey: 'fake-token-' + i, + }, + urls: { + sdk: 'https://not-called/api', + events: 'https://not-called/api', + auth: 'https://not-called/api', + } + }, (modules) => { + modules.lazyInit = true; + }); + + const manager = splitio.manager(); + assert.deepEqual(manager.names(), [], 'We should not have done any request yet'); + + const client = splitio.client(); + assert.equal(client.getTreatment('user-1', 'split_test'), 'control', 'We should get control'); + assert.equal(client.track('user-1', 'user', 'my_event'), true, 'We should track the event'); + } + + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.1&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200); + fetchMock.postOnce('https://not-called/api/events/bulk', 200); + + splitio.init(); + await splitio.client().ready(); + assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready'); + await splitio.destroy(); + + assert.end(); + }); + + t.test('Client-side', async (assert) => { + let splitio; + + for (let i = 0; i < 100; i++) { + splitio = SplitFactoryCS({ + core: { + authorizationKey: 'fake-token-' + i, + key: 'user-' + i, + }, + urls: { + sdk: 'https://not-called/api', + events: 'https://not-called/api', + auth: 'https://not-called/api', + } + }, (modules) => { + modules.lazyInit = true; + }); + + const manager = splitio.manager(); + assert.deepEqual(manager.names(), [], 'We should not have done any request yet'); + + const client = splitio.client(); + assert.equal(client.getTreatment('split_test'), 'control', 'We should get control'); + assert.equal(client.track('user', 'my_event'), true, 'We should track the event'); + + const otherClient = splitio.client('other-user'); + assert.equal(otherClient.getTreatment('split_test'), 'control', 'We should get control'); + assert.equal(otherClient.track('user', 'my_event'), true, 'We should track the event'); + } + + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=-1', { status: 200, body: { splits: [], since: -1, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/splitChanges?s=1.2&since=1457552620999', { status: 200, body: { splits: [], since: 1457552620999, till: 1457552620999 } }); + fetchMock.getOnce('https://not-called/api/memberships/user-99', { status: 200, body: {} }); + fetchMock.getOnce('https://not-called/api/memberships/other-user', { status: 200, body: {} }); + fetchMock.postOnce('https://not-called/api/testImpressions/bulk', 200); + fetchMock.postOnce('https://not-called/api/events/bulk', 200); + + splitio.init(); + await splitio.client().ready(); + assert.true(splitio.client().__getStatus().isReady, 'Split SDK is ready'); + await splitio.destroy(); + + assert.end(); + }); +} diff --git a/src/__tests__/online/node.spec.js b/src/__tests__/online/node.spec.js index 94ca9d830..a3e4fcac7 100644 --- a/src/__tests__/online/node.spec.js +++ b/src/__tests__/online/node.spec.js @@ -3,6 +3,9 @@ import fetchMock from '../testUtils/nodeFetchMock'; import { url } from '../testUtils'; import { settingsFactory } from '../../settings/node'; +import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; +import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; + import evaluationsSuite from '../nodeSuites/evaluations.spec'; import evaluationsSemverSuite from '../nodeSuites/evaluations-semver.spec'; import eventsSuite from '../nodeSuites/events.spec'; @@ -18,10 +21,8 @@ import ipAddressesSettingDebug from '../nodeSuites/ip-addresses-setting.debug.sp import readinessSuite from '../nodeSuites/readiness.spec'; import readyPromiseSuite from '../nodeSuites/ready-promise.spec'; import { fetchSpecificSplits, fetchSpecificSplitsForFlagSets } from '../nodeSuites/fetch-specific-splits.spec'; - -import splitChangesMock1 from '../mocks/splitchanges.since.-1.json'; -import splitChangesMock2 from '../mocks/splitchanges.since.1457552620999.json'; import flagSets from '../nodeSuites/flag-sets.spec'; +import lazyInitSuite from '../nodeSuites/lazy-init.spec'; const config = { core: { @@ -94,5 +95,7 @@ tape('## Node JS - E2E CI Tests ##', async function (assert) { /* Validate flag sets */ assert.test('E2E / Flag sets', flagSets.bind(null, fetchMock)); + assert.test('E2E / SplitFactory with lazy init', lazyInitSuite.bind(null, settings, fetchMock)); + assert.end(); }); diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 1e30feddf..384a95183 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '10.28.1-rc.2'; +export const packageVersion = '10.28.1-rc.4'; diff --git a/ts-tests/index.ts b/ts-tests/index.ts index c7f84d29d..f3f0a926b 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -163,7 +163,6 @@ browserSettings = { } }; // With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK -SDK = SplitFactory(browserSettings); SDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); @@ -196,6 +195,7 @@ SDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager client = SDK.client(); manager = SDK.manager(); +manager = BrowserSDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. asyncClient = AsyncSDK.client(); asyncManager = AsyncSDK.manager(); diff --git a/types/splitio.d.ts b/types/splitio.d.ts index 27a1dcade..6edbb7cd6 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -1407,6 +1407,12 @@ declare namespace SplitIO { * @returns {IBrowserClient} The client instance. */ client(key: SplitKey, trafficType?: string): IBrowserClient + /** + * Returns a manager instance of the SDK to explore available information. + * @function manager + * @returns {IManager} The manager instance. + */ + manager(): IManager, /** * User consent API. * @property UserConsent From da09bce8e7f4f1eee232c8b48b743bebb91a0cef Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 18 Oct 2024 13:24:16 -0300 Subject: [PATCH 44/58] Vulnerability fixes --- package-lock.json | 291 +++++++++++++++++++++++++++++++++------------- package.json | 2 +- 2 files changed, 212 insertions(+), 81 deletions(-) diff --git a/package-lock.json b/package-lock.json index b510d72d2..399f249cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "10.28.1-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.3", + "@splitsoftware/splitio-commons": "1.17.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", @@ -872,9 +872,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.3.tgz", - "integrity": "sha512-cPjTdDtYHejjefNvyNUZrvhYSwe6ElWoCdU5l05XmMMHv4TJiDVWMP3opes6FulI0hYKjC6za0gqlR3H+kXEUg==", + "version": "1.17.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.4.tgz", + "integrity": "sha512-Yi/NkpBmvixnoTw5AxG+p3N88ZNyD0NfBdLlN+IxI7sQ6I7Sx/5yYSQSC6I68EiJZLu79fJ1xMJ3BPS+gVyqZA==", "dependencies": { "tslib": "^2.3.1" }, @@ -1357,15 +1357,14 @@ } }, "node_modules/asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" } }, "node_modules/asn1.js/node_modules/bn.js": { @@ -1695,25 +1694,75 @@ } }, "node_modules/browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "dependencies": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" }, "engines": { - "node": ">= 4" + "node": ">= 0.12" + } + }, + "node_modules/browserify-sign/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/browserify-sign/node_modules/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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/browserify-sign/node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, "node_modules/browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", @@ -2091,9 +2140,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -2612,9 +2661,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -2622,7 +2671,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -2633,9 +2682,9 @@ } }, "node_modules/engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true, "engines": { "node": ">=10.0.0" @@ -4951,9 +5000,9 @@ "dev": true }, "node_modules/nise/node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "dependencies": { "isarray": "0.0.1" @@ -5284,16 +5333,33 @@ } }, "node_modules/parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "dependencies": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse-asn1/node_modules/hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": ">=4" } }, "node_modules/parse-ms": { @@ -6435,16 +6501,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -8528,9 +8594,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "1.17.1-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.3.tgz", - "integrity": "sha512-cPjTdDtYHejjefNvyNUZrvhYSwe6ElWoCdU5l05XmMMHv4TJiDVWMP3opes6FulI0hYKjC6za0gqlR3H+kXEUg==", + "version": "1.17.1-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-1.17.1-rc.4.tgz", + "integrity": "sha512-Yi/NkpBmvixnoTw5AxG+p3N88ZNyD0NfBdLlN+IxI7sQ6I7Sx/5yYSQSC6I68EiJZLu79fJ1xMJ3BPS+gVyqZA==", "requires": { "tslib": "^2.3.1" } @@ -8943,15 +9009,14 @@ } }, "asn1.js": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", - "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "safer-buffer": "^2.1.0" + "minimalistic-assert": "^1.0.0" }, "dependencies": { "bn.js": { @@ -9234,20 +9299,73 @@ } }, "browserify-sign": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.2.tgz", - "integrity": "sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.3.tgz", + "integrity": "sha512-JWCZW6SKhfhjJxO8Tyiiy+XYB7cqd2S5/+WeYHsKdNKFlCBhKbblba1A/HN/90YwtxKc8tCErjffZl++UNmGiw==", "dev": true, "requires": { "bn.js": "^5.2.1", "browserify-rsa": "^4.1.0", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", - "elliptic": "^6.5.4", + "elliptic": "^6.5.5", + "hash-base": "~3.0", "inherits": "^2.0.4", - "parse-asn1": "^5.1.6", - "readable-stream": "^3.6.2", + "parse-asn1": "^5.1.7", + "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + }, + "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==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + } + } + } } }, "browserify-zlib": { @@ -9524,9 +9642,9 @@ "dev": true }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "copyfiles": { @@ -9954,9 +10072,9 @@ } }, "engine.io": { - "version": "6.5.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", - "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -9964,7 +10082,7 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", @@ -9981,9 +10099,9 @@ } }, "engine.io-parser": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", - "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", "dev": true }, "enhanced-resolve": { @@ -11715,9 +11833,9 @@ "dev": true }, "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.9.0.tgz", + "integrity": "sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==", "dev": true, "requires": { "isarray": "0.0.1" @@ -11977,16 +12095,29 @@ } }, "parse-asn1": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", - "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.7.tgz", + "integrity": "sha512-CTM5kuWR3sx9IFamcl5ErfPl6ea/N8IYwiJ+vpeB2g+1iknv7zBl5uPwbMbRVznRVbrNY6lGuDoE5b30grmbqg==", "dev": true, "requires": { - "asn1.js": "^5.2.0", - "browserify-aes": "^1.0.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" + "asn1.js": "^4.10.1", + "browserify-aes": "^1.2.0", + "evp_bytestokey": "^1.0.3", + "hash-base": "~3.0", + "pbkdf2": "^3.1.2", + "safe-buffer": "^5.2.1" + }, + "dependencies": { + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha512-EeeoJKjTyt868liAlVmcv2ZsUfGHlE3Q+BICOXcZiwN3osr5Q/zFGYmTJpoIzuaSTAwndFy+GqhEwlU4L3j4Ow==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + } } }, "parse-ms": { @@ -12848,16 +12979,16 @@ } }, "socket.io": { - "version": "4.7.5", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", - "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.0.tgz", + "integrity": "sha512-8U6BEgGjQOfGz3HHTYaC/L1GaxDCJ/KM0XTkJly0EhZ5U/du9uNEZy4ZgYzEzIqlx2CMm25CrCqr1ck899eLNA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" } diff --git a/package.json b/package.json index 2193414df..5561c0700 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "node": ">=6" }, "dependencies": { - "@splitsoftware/splitio-commons": "1.17.1-rc.3", + "@splitsoftware/splitio-commons": "1.17.1-rc.4", "@types/google.analytics": "0.0.40", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", From 79e33e70d2a9ee36940a7ddac591281abd654e3a Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 18 Oct 2024 17:31:55 -0300 Subject: [PATCH 45/58] Update JS-commons dep --- package-lock.json | 14 +++++++------- package.json | 2 +- types/splitio.d.ts | 6 ------ 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/package-lock.json b/package-lock.json index f9342fd31..40bd9f43a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "11.0.0-rc.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.0", + "@splitsoftware/splitio-commons": "2.0.0-rc.1", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", @@ -870,9 +870,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.0.tgz", - "integrity": "sha512-iNuGugPMXQ/+k+uSDyhsvwkaGdzQrRaxRtP1sv58STKQFwww1smPxRA1gKfawoQm04quEHtLMKYm25t6VL0fJw==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.1.tgz", + "integrity": "sha512-tjIDgNnrwOKphYtWKNv0HOU7LJQ+0ljgbmknhi3H7MDptvnwG7o8DHKtoAtuljcEqVjosLmhgzOxzTY9MGZruw==", "dependencies": { "tslib": "^2.3.1" }, @@ -8587,9 +8587,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.0", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.0.tgz", - "integrity": "sha512-iNuGugPMXQ/+k+uSDyhsvwkaGdzQrRaxRtP1sv58STKQFwww1smPxRA1gKfawoQm04quEHtLMKYm25t6VL0fJw==", + "version": "2.0.0-rc.1", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.1.tgz", + "integrity": "sha512-tjIDgNnrwOKphYtWKNv0HOU7LJQ+0ljgbmknhi3H7MDptvnwG7o8DHKtoAtuljcEqVjosLmhgzOxzTY9MGZruw==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 12856a9ac..7eaf5130f 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.0", + "@splitsoftware/splitio-commons": "2.0.0-rc.1", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", diff --git a/types/splitio.d.ts b/types/splitio.d.ts index a8bbed6aa..596fd9a80 100644 --- a/types/splitio.d.ts +++ b/types/splitio.d.ts @@ -1248,12 +1248,6 @@ declare namespace SplitIO { * @returns {IManager} The manager instance. */ manager(): IManager, - /** - * Returns a manager instance of the SDK to explore available information. - * @function manager - * @returns {IManager} The manager instance. - */ - manager(): IManager, /** * User consent API. * @property UserConsent From 7a9782cb3548c80a4b01a289d3db034935dc88fb Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 18 Oct 2024 17:33:03 -0300 Subject: [PATCH 46/58] rc --- package-lock.json | 4 ++-- package.json | 2 +- src/settings/defaults/version.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 40bd9f43a..f0c4ffe5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.0", + "version": "11.0.0-rc.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.0", + "version": "11.0.0-rc.1", "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "2.0.0-rc.1", diff --git a/package.json b/package.json index 7eaf5130f..8a0c2cd88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.0", + "version": "11.0.0-rc.1", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 7f7b63b6a..b631429a8 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '11.0.0-rc.0'; +export const packageVersion = '11.0.0-rc.1'; From a3230a2a64082a27a760c4247c67c3133a170ad2 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 18 Oct 2024 17:44:14 -0300 Subject: [PATCH 47/58] Fix test --- ts-tests/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 1a7585845..2440be58a 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -201,7 +201,6 @@ asyncManager = AsyncSDK.manager(); // Browser client for attributes binding browserClient = BrowserSDK.client(); browserClient = BrowserSDK.client('a customer key'); -browserClient = BrowserSDK.client('a customer key', 'a traffic type'); // Logger SDK.Logger.enable(); From c07824951ba39c669102a2f4dd6e0c05c06d9ad4 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 25 Oct 2024 02:34:17 -0300 Subject: [PATCH 48/58] Internal refactor after removing sync.localhostMode option in JS-commons --- package-lock.json | 14 +++++++------- package.json | 2 +- src/factory/browser.js | 3 ++- src/factory/node.js | 3 ++- src/settings/browser.js | 2 -- src/settings/node.js | 2 -- src/sync/offline/LocalhostFromFile.js | 9 ++------- 7 files changed, 14 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index f0c4ffe5e..64c5a0e6a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "11.0.0-rc.1", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.1", + "@splitsoftware/splitio-commons": "2.0.0-rc.3", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", @@ -870,9 +870,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.1.tgz", - "integrity": "sha512-tjIDgNnrwOKphYtWKNv0HOU7LJQ+0ljgbmknhi3H7MDptvnwG7o8DHKtoAtuljcEqVjosLmhgzOxzTY9MGZruw==", + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.3.tgz", + "integrity": "sha512-XkDbULWBg6nw061b4Vc425JyrpDe5nSypoScO4eVsFbgcCqUPlGbr+s9bfriwNFyZe2Q29ijIlyGM06TCt27kQ==", "dependencies": { "tslib": "^2.3.1" }, @@ -8587,9 +8587,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.1", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.1.tgz", - "integrity": "sha512-tjIDgNnrwOKphYtWKNv0HOU7LJQ+0ljgbmknhi3H7MDptvnwG7o8DHKtoAtuljcEqVjosLmhgzOxzTY9MGZruw==", + "version": "2.0.0-rc.3", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.3.tgz", + "integrity": "sha512-XkDbULWBg6nw061b4Vc425JyrpDe5nSypoScO4eVsFbgcCqUPlGbr+s9bfriwNFyZe2Q29ijIlyGM06TCt27kQ==", "requires": { "tslib": "^2.3.1" } diff --git a/package.json b/package.json index 8a0c2cd88..55f3ad188 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.1", + "@splitsoftware/splitio-commons": "2.0.0-rc.3", "@types/ioredis": "^4.28.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", diff --git a/src/factory/browser.js b/src/factory/browser.js index b06eac524..8b71ed235 100644 --- a/src/factory/browser.js +++ b/src/factory/browser.js @@ -11,6 +11,7 @@ import { __InLocalStorageMockFactory } from '@splitsoftware/splitio-commons/src/ import { sdkFactory } from '@splitsoftware/splitio-commons/src/sdkFactory'; import { LOCALHOST_MODE, STORAGE_LOCALSTORAGE } from '@splitsoftware/splitio-commons/src/utils/constants'; import { createUserConsentAPI } from '@splitsoftware/splitio-commons/src/consent/sdkUserConsent'; +import { localhostFromObjectFactory } from '@splitsoftware/splitio-commons/src/sync/offline/LocalhostFromObject'; import { settingsFactory } from '../settings/browser'; import { platform, SignalListener } from '../platform'; @@ -60,7 +61,7 @@ function getModules(settings) { switch (settings.mode) { case LOCALHOST_MODE: modules.splitApiFactory = undefined; - modules.syncManagerFactory = settings.sync.localhostMode; + modules.syncManagerFactory = localhostFromObjectFactory; modules.SignalListener = undefined; break; } diff --git a/src/factory/node.js b/src/factory/node.js index d8141037a..4142741b9 100644 --- a/src/factory/node.js +++ b/src/factory/node.js @@ -10,6 +10,7 @@ import { impressionObserverSSFactory } from '@splitsoftware/splitio-commons/src/ import { sdkFactory } from '@splitsoftware/splitio-commons/src/sdkFactory'; import { CONSUMER_MODE, LOCALHOST_MODE } from '@splitsoftware/splitio-commons/src/utils/constants'; +import { localhostFromFileFactory } from '../sync/offline/LocalhostFromFile'; import { settingsFactory } from '../settings/node'; import { platform, SignalListener } from '../platform'; import { bloomFilterFactory } from '../platform/filter/bloomFilter'; @@ -53,7 +54,7 @@ function getModules(settings) { switch (settings.mode) { case LOCALHOST_MODE: modules.splitApiFactory = undefined; - modules.syncManagerFactory = settings.sync.localhostMode; + modules.syncManagerFactory = localhostFromFileFactory; modules.SignalListener = undefined; break; case CONSUMER_MODE: diff --git a/src/settings/browser.js b/src/settings/browser.js index 5a1ae432b..584b11a23 100644 --- a/src/settings/browser.js +++ b/src/settings/browser.js @@ -1,7 +1,6 @@ import { settingsValidation } from '@splitsoftware/splitio-commons/src/utils/settingsValidation'; import { validateRuntime } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/runtime'; import { validateLogger } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/logger/builtinLogger'; -import { LocalhostFromObject } from '@splitsoftware/splitio-commons/src/sync/offline/LocalhostFromObject'; import { validateConsent } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/consent'; import { defaults } from './defaults/browser'; @@ -13,7 +12,6 @@ const params = { runtime: validateRuntime, storage: validateStorage, logger: validateLogger, - localhost: () => LocalhostFromObject(), consent: validateConsent, }; diff --git a/src/settings/node.js b/src/settings/node.js index f7664b3f6..5fe7d5535 100644 --- a/src/settings/node.js +++ b/src/settings/node.js @@ -1,6 +1,5 @@ import { settingsValidation } from '@splitsoftware/splitio-commons/src/utils/settingsValidation'; import { validateLogger } from '@splitsoftware/splitio-commons/src/utils/settingsValidation/logger/builtinLogger'; -import { LocalhostFromFile } from '../sync/offline/LocalhostFromFile'; import { defaults } from './defaults/node'; import { validateStorage } from './storage/node'; @@ -13,7 +12,6 @@ const params = { runtime: validateRuntime, storage: validateStorage, logger: validateLogger, - localhost: () => LocalhostFromFile(), flagSpec: () => FLAG_SPEC_VERSION // In Node.js the SDK ignores `config.integrations`, so a validator for integrations is not required }; diff --git a/src/sync/offline/LocalhostFromFile.js b/src/sync/offline/LocalhostFromFile.js index 3f63173ac..3dca10929 100644 --- a/src/sync/offline/LocalhostFromFile.js +++ b/src/sync/offline/LocalhostFromFile.js @@ -1,11 +1,6 @@ import { splitsParserFromFileFactory } from './splitsParserFromFile'; import { syncManagerOfflineFactory } from '@splitsoftware/splitio-commons/src/sync/offline/syncManagerOffline'; -// Singleton instance of the factory function for offline SyncManager from YAML file (a.k.a. localhostFromFile) +// Singleton instance of the factory function for offline SyncManager from YAML file // It uses NodeJS APIs. -const localhostFromFile = syncManagerOfflineFactory(splitsParserFromFileFactory); -localhostFromFile.type = 'LocalhostFromFile'; - -export function LocalhostFromFile() { - return localhostFromFile; -} +export const localhostFromFileFactory = syncManagerOfflineFactory(splitsParserFromFileFactory); From d7d6eb6cc167c3e6c20ea0aa2faf03cd57936368 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 25 Oct 2024 18:09:48 -0300 Subject: [PATCH 49/58] Move SplitIO namespace definition from JS SDK to JS-Commons and merge --- package-lock.json | 21 +- package.json | 9 +- scripts/ts-tests.sh | 28 - src/settings/defaults/version.js | 2 +- ts-tests/index.ts | 199 ++-- ts-tests/package.json | 12 - ts-tests/tsconfig.json | 3 +- types/client/index.d.ts | 5 +- types/index.d.ts | 8 +- types/server/index.d.ts | 7 +- types/splitio.d.ts | 1666 ------------------------------ 11 files changed, 125 insertions(+), 1835 deletions(-) delete mode 100755 scripts/ts-tests.sh delete mode 100644 ts-tests/package.json delete mode 100644 types/splitio.d.ts diff --git a/package-lock.json b/package-lock.json index 64c5a0e6a..5024d5fc6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.1", + "version": "11.0.0-rc.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.1", + "version": "11.0.0-rc.3", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.3", - "@types/ioredis": "^4.28.0", + "@splitsoftware/splitio-commons": "2.0.0-rc.4", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", @@ -870,10 +869,11 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.3.tgz", - "integrity": "sha512-XkDbULWBg6nw061b4Vc425JyrpDe5nSypoScO4eVsFbgcCqUPlGbr+s9bfriwNFyZe2Q29ijIlyGM06TCt27kQ==", + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.4.tgz", + "integrity": "sha512-z0rm4X9oh7LdIcHeEkh6Ca3JzfdhJ0IH3r7nZ6ghL0AXmPzbezoDswxjKOe/WYBbTW3utsgLqTTjr9Ww/b/hUw==", "dependencies": { + "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" }, "peerDependencies": { @@ -8587,10 +8587,11 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.3", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.3.tgz", - "integrity": "sha512-XkDbULWBg6nw061b4Vc425JyrpDe5nSypoScO4eVsFbgcCqUPlGbr+s9bfriwNFyZe2Q29ijIlyGM06TCt27kQ==", + "version": "2.0.0-rc.4", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.4.tgz", + "integrity": "sha512-z0rm4X9oh7LdIcHeEkh6Ca3JzfdhJ0IH3r7nZ6ghL0AXmPzbezoDswxjKOe/WYBbTW3utsgLqTTjr9Ww/b/hUw==", "requires": { + "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" } }, diff --git a/package.json b/package.json index 55f3ad188..6d564c8b1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.1", + "version": "11.0.0-rc.3", "description": "Split SDK", "files": [ "README.md", @@ -38,8 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.3", - "@types/ioredis": "^4.28.0", + "@splitsoftware/splitio-commons": "2.0.0-rc.4", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", @@ -109,9 +108,7 @@ "test-node-e2e-errorCatching": "cross-env NODE_ENV=test tape -r ./ts-node.register src/__tests__/errorCatching/node.spec.js | tap-min", "test-node-e2e-push": "cross-env NODE_ENV=test tape -r ./ts-node.register src/__tests__/push/node.spec.js | tap-min", "test-node-e2e-redis": "cross-env NODE_ENV=test tape -r ./ts-node.register src/__tests__/consumer/node_redis.spec.js | tap-min", - "pretest-ts-decls": "npm run build-esm && npm run build-cjs && npm link", - "test-ts-decls": "./scripts/ts-tests.sh", - "posttest-ts-decls": "npm rm --location=global @splitsoftware/splitio && npm install", + "test-ts-decls": "tsc --build ts-tests", "test": "npm run test-node && npm run test-browser", "all": "npm run check && npm run build && npm run test-ts-decls && npm run test", "publish:rc": "npm run check && npm run build && npm publish --tag canary", diff --git a/scripts/ts-tests.sh b/scripts/ts-tests.sh deleted file mode 100755 index 2263e923d..000000000 --- a/scripts/ts-tests.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash - -cd ts-tests ## Go to typescript tests folder -echo "Installing dependencies for TypeScript declarations testing..." -npm install ## Install dependencies -npm install @types/node@6.0.31 ## Install type definitions for Node.js v6.x (the oldest supported version) -echo "Dependencies installed, linking the package." -npm link @splitsoftware/splitio ## Link to the cloned code -echo "Running tsc compiler." -./node_modules/.bin/tsc ## Run typescript compiler. No need for flags as we have a tsconfig.json file - -echo "Testing again with the latest @types/node version..." -npm install @types/node@14 ## Install latest type definitions for Node.js -echo "Dependencies installed, linking the package." -npm link @splitsoftware/splitio ## Link to the cloned code -echo "Running tsc compiler." -./node_modules/.bin/tsc ## Run typescript compiler. No need for flags as we have a tsconfig.json file - -if [ $? -eq 0 ] -then - echo "✅ Successfully compiled TS tests." - npm unlink @splitsoftware/splitio - exit 0 -else - echo "☠️ Error compiling TS tests." - npm unlink @splitsoftware/splitio - exit 1 -fi diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index b631429a8..818b1f165 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '11.0.0-rc.1'; +export const packageVersion = '11.0.0-rc.3'; diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 2440be58a..1cbe834ea 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -11,7 +11,7 @@ * @author Nico Zelaya */ -import { SplitFactory } from '@splitsoftware/splitio'; +import { SplitFactory } from '../types/index'; let stringPromise: Promise; let splitNamesPromise: Promise; @@ -25,19 +25,19 @@ let trackPromise: Promise; /**** Interfaces ****/ // Facade return interface -let SDK: SplitIO.ISDK; -let AsyncSDK: SplitIO.IAsyncSDK; -let BrowserSDK: SplitIO.IBrowserSDK; +let NodeSDK: SplitIO.INodeSDK; +let AsyncSDK: SplitIO.INodeAsyncSDK; +let BrowserSDK: SplitIO.ISDK; // Settings interfaces let nodeSettings: SplitIO.INodeSettings; let asyncSettings: SplitIO.INodeAsyncSettings; let browserSettings: SplitIO.IBrowserSettings; // Client & Manager APIs -let client: SplitIO.IClient; +let nodeClient: SplitIO.INodeClient; let manager: SplitIO.IManager; -let asyncClient: SplitIO.IAsyncClient; +let nodeAsyncClient: SplitIO.INodeAsyncClient; let asyncManager: SplitIO.IAsyncManager; -let browserClient: SplitIO.IBrowserClient; +let browserClient: SplitIO.IClient; // Utility interfaces let impressionListener: SplitIO.IImpressionListener; @@ -137,7 +137,7 @@ splitViewsAsync = splitViewsPromise; splitKey = 'someKey'; splitKey = splitKeyObj; -/**** Tests for ISDK interface ****/ +/**** Tests for INodeSDK interface ****/ // For node with sync storage nodeSettings = { @@ -162,8 +162,8 @@ browserSettings = { key: 'customer-key' } }; -// With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK -SDK = SplitFactory(nodeSettings); +// With sync settings should return INodeSDK, if settings have async storage it should return INodeAsyncSDK +NodeSDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); @@ -173,43 +173,38 @@ const instantiatedSettingsCore: { key: SplitIO.SplitKey, labelsEnabled: boolean, IPAddressesEnabled: boolean -} = SDK.settings.core; -const instantiatedSettingsMode: ('standalone' | 'consumer') = SDK.settings.mode; -const instantiatedSettingsScheduler: { [key: string]: number } = SDK.settings.scheduler; -const instantiatedSettingsStartup: { [key: string]: number } = SDK.settings.startup; -const instantiatedSettingsStorage: { - prefix: string, - options: Object, - // It can have any of the storages. - type: SplitIO.NodeSyncStorage | SplitIO.NodeAsyncStorage | SplitIO.BrowserStorage -} = SDK.settings.storage; -const instantiatedSettingsUrls: { [key: string]: string } = SDK.settings.urls; -const instantiatedSettingsVersion: string = SDK.settings.version; -let instantiatedSettingsFeatures = SDK.settings.features as SplitIO.MockedFeaturesMap; +} = NodeSDK.settings.core; +const instantiatedSettingsMode: ('standalone' | 'consumer' | 'consumer_partial' | 'localhost') = NodeSDK.settings.mode; +const instantiatedSettingsScheduler: { [key: string]: number } = NodeSDK.settings.scheduler; +const instantiatedSettingsStartup: { [key: string]: number } = NodeSDK.settings.startup; +const instantiatedSettingsStorage = NodeSDK.settings.storage as SplitIO.StorageOptions; +const instantiatedSettingsUrls: { [key: string]: string } = NodeSDK.settings.urls; +const instantiatedSettingsVersion: string = NodeSDK.settings.version; +let instantiatedSettingsFeatures = NodeSDK.settings.features as SplitIO.MockedFeaturesMap; // We should be able to write on features prop. The rest are readonly props. instantiatedSettingsFeatures.something = 'something'; -SDK.settings.features = 'new_file_path'; // Node -SDK.settings.features = { 'split_x': 'on' }; // Browser +NodeSDK.settings.features = 'new_file_path'; // Node +NodeSDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager -client = SDK.client(); -manager = SDK.manager(); +nodeClient = NodeSDK.client(); +manager = NodeSDK.manager(); manager = BrowserSDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. -asyncClient = AsyncSDK.client(); +nodeAsyncClient = AsyncSDK.client(); asyncManager = AsyncSDK.manager(); // Browser client for attributes binding browserClient = BrowserSDK.client(); browserClient = BrowserSDK.client('a customer key'); // Logger -SDK.Logger.enable(); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.DEBUG); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.INFO); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.WARN); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.ERROR); -SDK.Logger.setLogLevel(SDK.Logger.LogLevel.NONE); -SDK.Logger.disable(); +NodeSDK.Logger.enable(); +NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.DEBUG); +NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.INFO); +NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.WARN); +NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.ERROR); +NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.NONE); +NodeSDK.Logger.disable(); AsyncSDK.Logger.enable(); AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.DEBUG); @@ -222,163 +217,163 @@ AsyncSDK.Logger.disable(); /**** Tests for IClient interface ****/ // Events constants we get -const eventConsts: { [key: string]: SplitIO.Event } = client.Event; -splitEvent = client.Event.SDK_READY; -splitEvent = client.Event.SDK_READY_FROM_CACHE; -splitEvent = client.Event.SDK_READY_TIMED_OUT; -splitEvent = client.Event.SDK_UPDATE; +const eventConsts: { [key: string]: SplitIO.Event } = nodeClient.Event; +splitEvent = nodeClient.Event.SDK_READY; +splitEvent = nodeClient.Event.SDK_READY_FROM_CACHE; +splitEvent = nodeClient.Event.SDK_READY_TIMED_OUT; +splitEvent = nodeClient.Event.SDK_UPDATE; // Client implements methods from NodeJS.Events. Testing a few. -client = client.on(splitEvent, () => { }); -const a: boolean = client.emit(splitEvent); -client = client.removeAllListeners(splitEvent); -client = client.removeAllListeners(); -const b: number = client.listenerCount(splitEvent); -let nodeEventEmitter: NodeJS.EventEmitter = client; +nodeClient = nodeClient.on(splitEvent, () => { }); +const a: boolean = nodeClient.emit(splitEvent); +nodeClient = nodeClient.removeAllListeners(splitEvent); +nodeClient = nodeClient.removeAllListeners(); +const b: number = nodeClient.listenerCount(splitEvent); +let nodeEventEmitter: NodeJS.EventEmitter = nodeClient; // Ready, destroy and flush -let promise: Promise = client.ready(); -promise = client.destroy(); -promise = SDK.destroy(); +let promise: Promise = nodeClient.ready(); +promise = nodeClient.destroy(); +promise = NodeSDK.destroy(); // @TODO not public yet -// promise = client.flush(); +// promise = nodeClient.flush(); // We can call getTreatment with or without a key. -treatment = client.getTreatment(splitKey, 'mySplit'); +treatment = nodeClient.getTreatment(splitKey, 'mySplit'); treatment = browserClient.getTreatment('mySplit'); // Attributes parameter is optional on both signatures. -treatment = client.getTreatment(splitKey, 'mySplit', attributes); +treatment = nodeClient.getTreatment(splitKey, 'mySplit', attributes); treatment = browserClient.getTreatment('mySplit', attributes); // We can call getTreatments with or without a key. -treatments = client.getTreatments(splitKey, ['mySplit']); +treatments = nodeClient.getTreatments(splitKey, ['mySplit']); treatments = browserClient.getTreatments(['mySplit']); // Attributes parameter is optional on both signatures. -treatments = client.getTreatments(splitKey, ['mySplit'], attributes); +treatments = nodeClient.getTreatments(splitKey, ['mySplit'], attributes); treatments = browserClient.getTreatments(['mySplit'], attributes); // We can call getTreatmentWithConfig with or without a key. -treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit'); +treatmentWithConfig = nodeClient.getTreatmentWithConfig(splitKey, 'mySplit'); treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit'); // Attributes parameter is optional on both signatures. -treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit', attributes); +treatmentWithConfig = nodeClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit', attributes); // We can call getTreatmentsWithConfig with or without a key. -treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit']); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfig(splitKey, ['mySplit']); treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit']); // Attributes parameter is optional on both signatures. -treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit'], attributes); // We can call getTreatmentsByFlagSet with or without a key. -treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a'); +treatments = nodeClient.getTreatmentsByFlagSet(splitKey, 'set_a'); treatments = browserClient.getTreatmentsByFlagSet('set_a'); // Attributes parameter is optional. -treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); +treatments = nodeClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); treatments = browserClient.getTreatmentsByFlagSet('set_a', attributes); // We can call getTreatmentsByFlagSets with or without a key. -treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a']); +treatments = nodeClient.getTreatmentsByFlagSets(splitKey, ['set_a']); treatments = browserClient.getTreatmentsByFlagSets(['set_a']); // Attributes parameter is optional. -treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); +treatments = nodeClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); treatments = browserClient.getTreatmentsByFlagSets(['set_a'], attributes); // We can call getTreatmentsWithConfigByFlagSet with or without a key. -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a'); // Attributes parameter is optional. -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a', attributes); // We can call getTreatmentsWithConfigByFlagSets with or without a key. -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a']); // Attributes parameter is optional. -treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); +treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a'], attributes); // We can call track with or without a key. -tracked = client.track(splitKey, 'myTrafficType', 'myEventType'); // all params +tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType'); // all params tracked = browserClient.track('myTrafficType', 'myEventType'); // key bound, tt provided. // Value parameter is optional on all signatures. -tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10); +tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType', 10); tracked = browserClient.track('myTrafficType', 'myEventType', 10); // Properties parameter is optional on all signatures. -tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); +tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); tracked = browserClient.track('myTrafficType', 'myEventType', undefined, { prop1: 1, prop2: '2', prop3: false, prop4: null }); /*** Repeating tests for Async Client ***/ // Events constants we get (same as for sync client, just for interface checking) -const eventConstsAsync: { [key: string]: SplitIO.Event } = asyncClient.Event; -splitEvent = asyncClient.Event.SDK_READY; -splitEvent = asyncClient.Event.SDK_READY_FROM_CACHE; -splitEvent = asyncClient.Event.SDK_READY_TIMED_OUT; -splitEvent = asyncClient.Event.SDK_UPDATE; +const eventConstsAsync: { [key: string]: SplitIO.Event } = nodeAsyncClient.Event; +splitEvent = nodeAsyncClient.Event.SDK_READY; +splitEvent = nodeAsyncClient.Event.SDK_READY_FROM_CACHE; +splitEvent = nodeAsyncClient.Event.SDK_READY_TIMED_OUT; +splitEvent = nodeAsyncClient.Event.SDK_UPDATE; // Client implements methods from NodeJS.Events. (same as for sync client, just for interface checking) -asyncClient = asyncClient.on(splitEvent, () => { }); -const a1: boolean = asyncClient.emit(splitEvent); -asyncClient = asyncClient.removeAllListeners(splitEvent); -asyncClient = asyncClient.removeAllListeners(); -const b1: number = asyncClient.listenerCount(splitEvent); -nodeEventEmitter = asyncClient; +nodeAsyncClient = nodeAsyncClient.on(splitEvent, () => { }); +const a1: boolean = nodeAsyncClient.emit(splitEvent); +nodeAsyncClient = nodeAsyncClient.removeAllListeners(splitEvent); +nodeAsyncClient = nodeAsyncClient.removeAllListeners(); +const b1: number = nodeAsyncClient.listenerCount(splitEvent); +nodeEventEmitter = nodeAsyncClient; // Ready, destroy and flush (same as for sync client, just for interface checking) -promise = asyncClient.ready(); -promise = asyncClient.destroy(); +promise = nodeAsyncClient.ready(); +promise = nodeAsyncClient.destroy(); promise = AsyncSDK.destroy(); // @TODO not public yet -// promise = asyncClient.flush(); +// promise = nodeAsyncClient.flush(); // We can call getTreatment but always with a key. -asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit'); +asyncTreatment = nodeAsyncClient.getTreatment(splitKey, 'mySplit'); // Attributes parameter is optional -asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit', attributes); +asyncTreatment = nodeAsyncClient.getTreatment(splitKey, 'mySplit', attributes); // We can call getTreatments but always with a key. -asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit']); +asyncTreatments = nodeAsyncClient.getTreatments(splitKey, ['mySplit']); // Attributes parameter is optional -asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit'], attributes); +asyncTreatments = nodeAsyncClient.getTreatments(splitKey, ['mySplit'], attributes); // We can call getTreatmentWithConfig but always with a key. -asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit'); +asyncTreatmentWithConfig = nodeAsyncClient.getTreatmentWithConfig(splitKey, 'mySplit'); // Attributes parameter is optional -asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); +asyncTreatmentWithConfig = nodeAsyncClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); // We can call getTreatments but always with a key. -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit']); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfig(splitKey, ['mySplit']); // Attributes parameter is optional -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); // We can call getTreatmentsByFlagSet -asyncTreatments = asyncClient.getTreatmentsByFlagSet(splitKey, 'set_a'); +asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSet(splitKey, 'set_a'); // Attributes parameter is optional -asyncTreatments = asyncClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); +asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); // We can call getTreatmentsByFlagSets -asyncTreatments = asyncClient.getTreatmentsByFlagSets(splitKey, ['set_a']); +asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSets(splitKey, ['set_a']); // Attributes parameter is optional -asyncTreatments = asyncClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); +asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); // We can call getTreatmentsWithConfigByFlagSet -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); // Attributes parameter is optional -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); // We can call getTreatmentsByFlagSets but always with a key. -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); // Attributes parameter is optional -asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); +asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); // We can call track only with a key. -trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType'); // all required params +trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType'); // all required params // Value parameter is optional. -trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10); +trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10); // Properties parameter is optional -trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); +trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); /**** Tests for IManager interface ****/ diff --git a/ts-tests/package.json b/ts-tests/package.json deleted file mode 100644 index d359b9e25..000000000 --- a/ts-tests/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "ts-tests", - "version": "1.0.0", - "description": "SDK tests for TypeScript declaration files", - "author": "Nico Zelaya", - "license": "Apache-2.0", - "repository": "splitio/javascript-client", - "dependencies": { - "@types/node": "^14.18.63", - "typescript": "^3.7.4" - } -} diff --git a/ts-tests/tsconfig.json b/ts-tests/tsconfig.json index 4adc23925..2c1ab20a8 100644 --- a/ts-tests/tsconfig.json +++ b/ts-tests/tsconfig.json @@ -2,7 +2,8 @@ "compilerOptions": { "noImplicitAny": true, "target": "es5", - "module": "commonjs" + "module": "commonjs", + "noEmit": true, }, "files": [ "index" diff --git a/types/client/index.d.ts b/types/client/index.d.ts index ba6d4a9d4..45efaa984 100644 --- a/types/client/index.d.ts +++ b/types/client/index.d.ts @@ -1,7 +1,8 @@ // Declaration file for JavaScript Split Software SDK // Project: http://www.split.io/ -/// +import '@splitsoftware/splitio-commons'; + export = JsSdk; declare module JsSdk { @@ -10,5 +11,5 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.IBrowserSDK; + export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.ISDK; } diff --git a/types/index.d.ts b/types/index.d.ts index adaf540dd..2bcd7c7db 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -2,7 +2,7 @@ // Project: http://www.split.io/ // Definitions by: Nico Zelaya -/// +import '@splitsoftware/splitio-commons'; export = JsSdk; @@ -12,17 +12,17 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; + export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.INodeAsyncSDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.ISDK; + export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.INodeSDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.IBrowserSDK; + export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.ISDK; } diff --git a/types/server/index.d.ts b/types/server/index.d.ts index f39f44bf6..f0e305fce 100644 --- a/types/server/index.d.ts +++ b/types/server/index.d.ts @@ -1,7 +1,8 @@ // Declaration file for JavaScript Split Software SDK // Project: http://www.split.io/ -/// +import '@splitsoftware/splitio-commons'; + export = JsSdk; declare module JsSdk { @@ -10,11 +11,11 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; + export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.INodeAsyncSDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.ISDK; + export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.INodeSDK; } diff --git a/types/splitio.d.ts b/types/splitio.d.ts deleted file mode 100644 index 596fd9a80..000000000 --- a/types/splitio.d.ts +++ /dev/null @@ -1,1666 +0,0 @@ -// Type definitions for JavaScript and NodeJS Split Software SDK -// Project: http://www.split.io/ -// Definitions by: Nico Zelaya - -import { RedisOptions } from "ioredis"; -import { RequestOptions } from "http"; - -export as namespace SplitIO; -export = SplitIO; - -/** - * NodeJS.EventEmitter interface - * @see {@link https://nodejs.org/api/events.html} - */ -interface EventEmitter { - addListener(event: string | symbol, listener: (...args: any[]) => void): this; - on(event: string | symbol, listener: (...args: any[]) => void): this; - once(event: string | symbol, listener: (...args: any[]) => void): this; - removeListener(event: string | symbol, listener: (...args: any[]) => void): this; - off(event: string | symbol, listener: (...args: any[]) => void): this; - removeAllListeners(event?: string | symbol): this; - setMaxListeners(n: number): this; - getMaxListeners(): number; - listeners(event: string | symbol): Function[]; - rawListeners(event: string | symbol): Function[]; - emit(event: string | symbol, ...args: any[]): boolean; - listenerCount(type: string | symbol): number; - // Added in Node 6... - prependListener(event: string | symbol, listener: (...args: any[]) => void): this; - prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this; - eventNames(): Array; -} -/** - * @typedef {Object} EventConsts - * @property {string} SDK_READY The ready event. - * @property {string} SDK_READY_FROM_CACHE The ready event when fired with cached data. - * @property {string} SDK_READY_TIMED_OUT The timeout event. - * @property {string} SDK_UPDATE The update event. - */ -type EventConsts = { - SDK_READY: 'init::ready', - SDK_READY_FROM_CACHE: 'init::cache-ready', - SDK_READY_TIMED_OUT: 'init::timeout', - SDK_UPDATE: 'state::update' -}; -/** - * SDK Modes. - * @typedef {string} SDKMode - */ -type SDKMode = 'standalone' | 'consumer'; -/** - * Storage types. - * @typedef {string} StorageType - */ -type StorageType = 'MEMORY' | 'LOCALSTORAGE' | 'REDIS'; -/** - * Settings interface. This is a representation of the settings the SDK expose, that's why - * most of it's props are readonly. Only features should be rewritten when localhost mode is active. - * @interface ISettings - */ -interface ISettings { - readonly core: { - authorizationKey: string, - key: SplitIO.SplitKey, - labelsEnabled: boolean, - IPAddressesEnabled: boolean - }, - readonly mode: SDKMode, - readonly scheduler: { - featuresRefreshRate: number, - impressionsRefreshRate: number, - impressionsQueueSize: number, - /** - * @deprecated - */ - metricsRefreshRate?: number, - telemetryRefreshRate: number, - segmentsRefreshRate: number, - offlineRefreshRate: number, - eventsPushRate: number, - eventsQueueSize: number, - pushRetryBackoffBase: number - }, - readonly startup: { - readyTimeout: number, - requestTimeoutBeforeReady: number, - retriesOnFailureBeforeReady: number, - eventsFirstPushWindow: number - }, - readonly storage: { - prefix: string, - options: Object, - type: StorageType - }, - readonly urls: { - events: string, - sdk: string, - auth: string, - streaming: string, - telemetry: string - }, - readonly debug: boolean | LogLevel, - readonly version: string, - /** - * Mocked features map if using in browser, or mocked features file path string if using in NodeJS. - */ - features: SplitIO.MockedFeaturesMap | SplitIO.MockedFeaturesFilePath, - readonly streamingEnabled: boolean, - readonly sync: { - splitFilters: SplitIO.SplitFilter[], - impressionsMode: SplitIO.ImpressionsMode, - enabled: boolean, - flagSpecVersion: string, - requestOptions?: { - getHeaderOverrides?: (context: { headers: Record }) => Record - } - } - /** - * User consent status if using in browser. Undefined if using in NodeJS. - */ - readonly userConsent?: SplitIO.ConsentStatus -} -/** - * Log levels. - * @typedef {string} LogLevel - */ -type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR' | 'NONE'; -/** - * Logger API - * @interface ILoggerAPI - */ -interface ILoggerAPI { - /** - * Enables SDK logging to the console. - * @function enable - * @returns {void} - */ - enable(): void, - /** - * Disables SDK logging. - * @function disable - * @returns {void} - */ - disable(): void, - /** - * Sets a log level for the SDK logs. - * @function setLogLevel - * @returns {void} - */ - setLogLevel(logLevel: LogLevel): void, - /** - * Log level constants. Use this to pass them to setLogLevel function. - */ - LogLevel: { - [level in LogLevel]: LogLevel - } -} -/** - * User consent API - * @interface IUserConsentAPI - */ -interface IUserConsentAPI { - /** - * Sets or updates the user consent status. Possible values are `true` and `false`, which represent user consent `'GRANTED'` and `'DECLINED'` respectively. - * - `true ('GRANTED')`: the user has granted consent for tracking events and impressions. The SDK will send them to Split cloud. - * - `false ('DECLINED')`: the user has declined consent for tracking events and impressions. The SDK will not send them to Split cloud. - * - * NOTE: calling this method updates the user consent at a factory level, affecting all clients of the same factory. - * - * @function setStatus - * @param {boolean} userConsent The user consent status, true for 'GRANTED' and false for 'DECLINED'. - * @returns {boolean} Whether the provided param is a valid value (i.e., a boolean value) or not. - */ - setStatus(userConsent: boolean): boolean; - /** - * Gets the user consent status. - * - * @function getStatus - * @returns {ConsentStatus} The user consent status. - */ - getStatus(): SplitIO.ConsentStatus; - /** - * Consent status constants. Use this to compare with the getStatus function result. - */ - Status: { - [status in SplitIO.ConsentStatus]: SplitIO.ConsentStatus - } -} -/** - * Common settings between Browser and NodeJS settings interface. - * @interface ISharedSettings - */ -interface ISharedSettings { - /** - * Boolean value to indicate whether the logger should be enabled or disabled, or a log level string. - * - * Examples: - * ```javascript - * config.debug = true - * config.debug = 'WARN' - * ``` - * @property {boolean | LogLevel} debug - * @default false - */ - debug?: boolean | LogLevel, - /** - * The impression listener, which is optional. Whatever you provide here needs to comply with the SplitIO.IImpressionListener interface, - * which will check for the logImpression method. - * @property {IImpressionListener} impressionListener - * @default undefined - */ - impressionListener?: SplitIO.IImpressionListener, - /** - * Boolean flag to enable the streaming service as default synchronization mechanism. In the event of any issue with streaming, - * the SDK would fallback to the polling mechanism. If false, the SDK would poll for changes as usual without attempting to use streaming. - * @property {boolean} streamingEnabled - * @default true - */ - streamingEnabled?: boolean, - /** - * SDK synchronization settings. - * @property {Object} sync - */ - sync?: { - /** - * List of feature flag filters. These filters are used to fetch a subset of the feature flag definitions in your environment, in order to reduce the delay of the SDK to be ready. - * This configuration is only meaningful when the SDK is working in "standalone" mode. - * - * Example: - * `splitFilter: [ - * { type: 'byName', values: ['my_feature_flag_1', 'my_feature_flag_2'] }, // will fetch feature flags named 'my_feature_flag_1' and 'my_feature_flag_2' - * ]` - * @property {SplitIO.SplitFilter[]} splitFilters - */ - splitFilters?: SplitIO.SplitFilter[] - /** - * Impressions Collection Mode. Option to determine how impressions are going to be sent to Split servers. - * Possible values are 'DEBUG', 'OPTIMIZED', and 'NONE'. - * - DEBUG: will send all the impressions generated (recommended only for debugging purposes). - * - OPTIMIZED: will send unique impressions to Split servers, avoiding a considerable amount of traffic that duplicated impressions could generate. - * - NONE: will send unique keys evaluated per feature to Split servers instead of full blown impressions, avoiding a considerable amount of traffic that impressions could generate. - * - * @property {string} impressionsMode - * @default 'OPTIMIZED' - */ - impressionsMode?: SplitIO.ImpressionsMode, - /** - * Controls the SDK continuous synchronization flags. - * - * When `true` a running SDK will process rollout plan updates performed on the UI (default). - * When false it'll just fetch all data upon init - * - * @property {boolean} enabled - * @default true - */ - enabled?: boolean - } -} -/** - * Common settings interface for SDK instances on NodeJS. - * @interface INodeBasicSettings - * @extends ISharedSettings - */ -interface INodeBasicSettings extends ISharedSettings { - /** - * SDK Startup settings for NodeJS. - * @property {Object} startup - */ - startup?: { - /** - * Maximum amount of time used before notify a timeout. - * @property {number} readyTimeout - * @default 15 - */ - readyTimeout?: number, - /** - * Time to wait for a request before the SDK is ready. If this time expires, JS Sdk will retry 'retriesOnFailureBeforeReady' times before notifying its failure to be 'ready'. - * @property {number} requestTimeoutBeforeReady - * @default 15 - */ - requestTimeoutBeforeReady?: number, - /** - * How many quick retries we will do while starting up the SDK. - * @property {number} retriesOnFailureBeforeReady - * @default 1 - */ - retriesOnFailureBeforeReady?: number, - /** - * For SDK posts the queued events data in bulks with a given rate, but the first push window is defined separately, - * to better control on browsers. This number defines that window before the first events push. - * - * @property {number} eventsFirstPushWindow - * @default 0 - */ - eventsFirstPushWindow?: number, - }, - /** - * SDK scheduler settings. - * @property {Object} scheduler - */ - scheduler?: { - /** - * The SDK polls Split servers for changes to feature flag definitions. This parameter controls this polling period in seconds. - * @property {number} featuresRefreshRate - * @default 60 - */ - featuresRefreshRate?: number, - /** - * The SDK sends information on who got what treatment at what time back to Split servers to power analytics. This parameter controls how often this data is sent to Split servers. The parameter should be in seconds. - * @property {number} impressionsRefreshRate - * @default 300 - */ - impressionsRefreshRate?: number, - /** - * The maximum number of impression items we want to queue. If we queue more values, it will trigger a flush and reset the timer. - * If you use a 0 here, the queue will have no maximum size. - * @property {number} impressionsQueueSize - * @default 30000 - */ - impressionsQueueSize?: number, - /** - * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. - * @property {number} metricsRefreshRate - * @default 120 - * @deprecated This parameter is ignored now. Use `telemetryRefreshRate` instead. - */ - metricsRefreshRate?: number, - /** - * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. - * @property {number} telemetryRefreshRate - * @default 3600 - */ - telemetryRefreshRate?: number, - /** - * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds. - * @property {number} segmentsRefreshRate - * @default 60 - */ - segmentsRefreshRate?: number, - /** - * The SDK posts the queued events data in bulks. This parameter controls the posting rate in seconds. - * @property {number} eventsPushRate - * @default 60 - */ - eventsPushRate?: number, - /** - * The maximum number of event items we want to queue. If we queue more values, it will trigger a flush and reset the timer. - * If you use a 0 here, the queue will have no maximum size. - * @property {number} eventsQueueSize - * @default 500 - */ - eventsQueueSize?: number, - /** - * For mocking/testing only. The SDK will refresh the features mocked data when mode is set to "localhost" by defining the key. - * For more information see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode} - * @property {number} offlineRefreshRate - * @default 15 - */ - offlineRefreshRate?: number - /** - * When using streaming mode, seconds to wait before re attempting to connect for push notifications. - * Next attempts follow intervals in power of two: base seconds, base x 2 seconds, base x 4 seconds, ... - * @property {number} pushRetryBackoffBase - * @default 1 - */ - pushRetryBackoffBase?: number, - }, - /** - * SDK Core settings for NodeJS. - * @property {Object} core - */ - core: { - /** - * Your SDK key. - * @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} - * @property {string} authorizationKey - */ - authorizationKey: string, - /** - * Disable labels from being sent to Split backend. Labels may contain sensitive information. - * @property {boolean} labelsEnabled - * @default true - */ - labelsEnabled?: boolean - /** - * Disable machine IP and Name from being sent to Split backend. - * @property {boolean} IPAddressesEnabled - * @default true - */ - IPAddressesEnabled?: boolean - }, - /** - * Defines which kind of storage we should instantiate. - * @property {Object} storage - */ - storage?: { - /** - * Storage type to be instantiated by the SDK. - * @property {StorageType} type - * @default 'MEMORY' - */ - type?: StorageType, - /** - * Options to be passed to the selected storage. - * @property {Object} options - */ - options?: Object, - /** - * Optional prefix to prevent any kind of data collision between SDK versions. - * @property {string} prefix - * @default 'SPLITIO' - */ - prefix?: string - }, - /** - * The SDK mode. Possible values are "standalone", which is the default when using a synchronous storage, like 'MEMORY' and 'LOCALSTORAGE', - * and "consumer", which must be set when using an asynchronous storage, like 'REDIS'. For "localhost" mode, use "localhost" as authorizationKey. - * @property {SDKMode} mode - * @default 'standalone' - */ - mode?: SDKMode, - /** - * Mocked features file path. For testing purposes only. For using this you should specify "localhost" as authorizationKey on core settings. - * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#localhost-mode} - * @property {MockedFeaturesFilePath} features - * @default '$HOME/.split' - */ - features?: SplitIO.MockedFeaturesFilePath, -} -/** - * Common API for entities that expose status handlers. - * @interface IStatusInterface - * @extends EventEmitter - */ -interface IStatusInterface extends EventEmitter { - /** - * Constant object containing the SDK events for you to use. - * @property {EventConsts} Event - */ - Event: EventConsts, - /** - * Returns a promise that resolves once the SDK has finished loading (`SDK_READY` event emitted) or rejected if the SDK has timedout (`SDK_READY_TIMED_OUT` event emitted). - * As it's meant to provide similar flexibility to the event approach, given that the SDK might be eventually ready after a timeout event, the `ready` method will return a resolved promise once the SDK is ready. - * - * Caveats: the method was designed to avoid an unhandled Promise rejection if the rejection case is not handled, so that `onRejected` handler is optional when using promises. - * However, when using async/await syntax, the rejection should be explicitly propagated like in the following example: - * ``` - * try { - * await client.ready().catch((e) => { throw e; }); - * // SDK is ready - * } catch(e) { - * // SDK has timedout - * } - * ``` - * - * @function ready - * @returns {Promise} - */ - ready(): Promise -} -/** - * Common definitions between clients for different environments interface. - * @interface IBasicClient - * @extends IStatusInterface - */ -interface IBasicClient extends IStatusInterface { - /** - * Destroys the client instance. - * In 'standalone' mode, this method will flush any pending impressions and events, and stop the synchronization of feature flag definitions with the backend. - * In 'consumer' mode, this method will disconnect the SDK from the Redis or Pluggable storage. - * - * @function destroy - * @returns {Promise} A promise that resolves once the client is destroyed. - */ - destroy(): Promise -} -/** - * Common definitions between SDK instances for different environments interface. - * @interface IBasicSDK - */ -interface IBasicSDK { - /** - * Current settings of the SDK instance. - * @property settings - */ - settings: ISettings, - /** - * Logger API. - * @property Logger - */ - Logger: ILoggerAPI - /** - * Destroys all the clients created by this factory. - * @function destroy - * @returns {Promise} - */ - destroy(): Promise -} -/****** Exposed namespace ******/ -/** - * Types and interfaces for `@splitsoftware/splitio` package for usage when integrating JavaScript SDK with TypeScript. - * For the SDK package information see {@link https://www.npmjs.com/package/@splitsoftware/splitio} - */ -declare namespace SplitIO { - /** - * Feature flag treatment value, returned by getTreatment. - * @typedef {string} Treatment - */ - type Treatment = string; - /** - * Feature flag treatment promise that resolves to actual treatment value. - * @typedef {Promise} AsyncTreatment - */ - type AsyncTreatment = Promise; - /** - * An object with the treatments for a bulk of feature flags, returned by getTreatments. For example: - * { - * feature1: 'on', - * feature2: 'off - * } - * @typedef {Object.} Treatments - */ - type Treatments = { - [featureName: string]: Treatment - }; - /** - * Feature flag treatments promise that resolves to the actual SplitIO.Treatments object. - * @typedef {Promise} AsyncTreatments - */ - type AsyncTreatments = Promise; - /** - * Feature flag evaluation result with treatment and configuration, returned by getTreatmentWithConfig. - * @typedef {Object} TreatmentWithConfig - * @property {string} treatment The treatment string - * @property {string | null} config The stringified version of the JSON config defined for that treatment, null if there is no config for the resulting treatment. - */ - type TreatmentWithConfig = { - treatment: string, - config: string | null - }; - /** - * Feature flag treatment promise that resolves to actual treatment with config value. - * @typedef {Promise} AsyncTreatmentWithConfig - */ - type AsyncTreatmentWithConfig = Promise; - /** - * An object with the treatments with configs for a bulk of feature flags, returned by getTreatmentsWithConfig. - * Each existing configuration is a stringified version of the JSON you defined on the Split user interface. For example: - * { - * feature1: { treatment: 'on', config: null } - * feature2: { treatment: 'off', config: '{"bannerText":"Click here."}' } - * } - * @typedef {Object.} Treatments - */ - type TreatmentsWithConfig = { - [featureName: string]: TreatmentWithConfig - }; - /** - * Feature flag treatments promise that resolves to the actual SplitIO.TreatmentsWithConfig object. - * @typedef {Promise} AsyncTreatmentsWithConfig - */ - type AsyncTreatmentsWithConfig = Promise; - /** - * Possible Split SDK events. - * @typedef {string} Event - */ - type Event = 'init::timeout' | 'init::ready' | 'init::cache-ready' | 'state::update'; - /** - * Attributes should be on object with values of type string, boolean, number (dates should be sent as millis since epoch) or array of strings or numbers. - * @typedef {Object.} Attributes - * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#attribute-syntax} - */ - type Attributes = { - [attributeName: string]: AttributeType - }; - /** - * Type of an attribute value - * @typedef {string | number | boolean | Array} AttributeType - */ - type AttributeType = string | number | boolean | Array; - /** - * Properties should be an object with values of type string, number, boolean or null. Size limit of ~31kb. - * @typedef {Object.} Properties - * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#track - */ - type Properties = { - [propertyName: string]: string | number | boolean | null - }; - /** - * The SplitKey object format. - * @typedef {Object.} SplitKeyObject - */ - type SplitKeyObject = { - matchingKey: string, - bucketingKey: string - }; - /** - * The customer identifier. Could be a SplitKeyObject or a string. - * @typedef {SplitKeyObject|string} SplitKey - */ - type SplitKey = SplitKeyObject | string; - /** - * Path to file with mocked features (for node). - * @typedef {string} MockedFeaturesFilePath - */ - type MockedFeaturesFilePath = string; - /** - * Object with mocked features mapping (for browser). We need to specify the featureName as key, and the mocked treatment as value. - * @typedef {Object} MockedFeaturesMap - */ - type MockedFeaturesMap = { - [featureName: string]: string | TreatmentWithConfig - }; - /** - * Object with information about an impression. It contains the generated impression DTO as well as - * complementary information around where and how it was generated in that way. - * @typedef {Object} ImpressionData - */ - type ImpressionData = { - impression: { - feature: string, - keyName: string, - treatment: string, - time: number, - bucketingKey?: string, - label: string, - changeNumber: number, - pt?: number, - }, - attributes?: SplitIO.Attributes, - ip: string, - hostname: string, - sdkLanguageVersion: string - }; - /** - * Data corresponding to one feature flag view. - * @typedef {Object} SplitView - */ - type SplitView = { - /** - * The name of the feature flag. - * @property {string} name - */ - name: string, - /** - * The traffic type of the feature flag. - * @property {string} trafficType - */ - trafficType: string, - /** - * Whether the feature flag is killed or not. - * @property {boolean} killed - */ - killed: boolean, - /** - * The list of treatments available for the feature flag. - * @property {Array} treatments - */ - treatments: Array, - /** - * Current change number of the feature flag. - * @property {number} changeNumber - */ - changeNumber: number, - /** - * Map of configurations per treatment. - * Each existing configuration is a stringified version of the JSON you defined on the Split user interface. - * @property {Object.} configs - */ - configs: { - [treatmentName: string]: string - }, - /** - * List of sets of the feature flag. - * @property {string[]} sets - */ - sets: string[], - /** - * The default treatment of the feature flag. - * @property {string} defaultTreatment - */ - defaultTreatment: string, - }; - /** - * A promise that resolves to a feature flag view. - * @typedef {Promise} SplitView - */ - type SplitViewAsync = Promise; - /** - * An array containing the SplitIO.SplitView elements. - */ - type SplitViews = Array; - /** - * A promise that resolves to an SplitIO.SplitViews array. - * @typedef {Promise} SplitViewsAsync - */ - type SplitViewsAsync = Promise; - /** - * An array of feature flag names. - * @typedef {Array} SplitNames - */ - type SplitNames = Array; - /** - * A promise that resolves to an array of feature flag names. - * @typedef {Promise} SplitNamesAsync - */ - type SplitNamesAsync = Promise; - /** - * Synchronous storage valid types for NodeJS. - * @typedef {string} NodeSyncStorage - */ - type NodeSyncStorage = 'MEMORY'; - /** - * Asynchronous storages valid types for NodeJS. - * @typedef {string} NodeAsyncStorage - */ - type NodeAsyncStorage = 'REDIS'; - /** - * Storage valid types for the browser. - * @typedef {string} BrowserStorage - */ - type BrowserStorage = 'MEMORY' | 'LOCALSTORAGE'; - /** - * Impression listener interface. This is the interface that needs to be implemented - * by the element you provide to the SDK as impression listener. - * @interface IImpressionListener - * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#listener} - */ - interface IImpressionListener { - logImpression(data: SplitIO.ImpressionData): void - } - /** - * Available URL settings for the SDKs. - */ - type UrlSettings = { - /** - * String property to override the base URL where the SDK will get rollout plan related data, like feature flags and segments definitions. - * @property {string} sdk - * @default 'https://sdk.split.io/api' - */ - sdk?: string, - /** - * String property to override the base URL where the SDK will post event-related information like impressions. - * @property {string} events - * @default 'https://events.split.io/api' - */ - events?: string, - /** - * String property to override the base URL where the SDK will get authorization tokens to be used with functionality that requires it, like streaming. - * @property {string} auth - * @default 'https://auth.split.io/api' - */ - auth?: string, - /** - * String property to override the base URL where the SDK will connect to receive streaming updates. - * @property {string} streaming - * @default 'https://streaming.split.io' - */ - streaming?: string, - /** - * String property to override the base URL where the SDK will post telemetry data. - * @property {string} telemetry - * @default 'https://telemetry.split.io/api' - */ - telemetry?: string - }; - - /** - * SplitFilter type. - * - * @typedef {string} SplitFilterType - */ - type SplitFilterType = 'bySet' | 'byName' | 'byPrefix'; - /** - * Defines a feature flag filter, described by a type and list of values. - */ - interface SplitFilter { - /** - * Type of the filter. - * - * @property {SplitFilterType} type - */ - type: SplitFilterType, - /** - * List of values: feature flag names for 'byName' filter type, and feature flag name prefixes for 'byPrefix' type. - * - * @property {string[]} values - */ - values: string[], - } - /** - * ImpressionsMode type - * @typedef {string} ImpressionsMode - */ - type ImpressionsMode = 'OPTIMIZED' | 'DEBUG' | 'NONE'; - /** - * User consent status. - * @typedef {string} ConsentStatus - */ - type ConsentStatus = 'GRANTED' | 'DECLINED' | 'UNKNOWN'; - /** - * Settings interface for SDK instances created on the browser - * @interface IBrowserSettings - * @extends ISharedSettings - * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} - */ - interface IBrowserSettings extends ISharedSettings { - /** - * SDK Startup settings for the Browser. - * @property {Object} startup - */ - startup?: { - /** - * Maximum amount of time used before notify a timeout. - * @property {number} readyTimeout - * @default 1.5 - */ - readyTimeout?: number, - /** - * Time to wait for a request before the SDK is ready. If this time expires, JS Sdk will retry 'retriesOnFailureBeforeReady' times before notifying its failure to be 'ready'. - * @property {number} requestTimeoutBeforeReady - * @default 1.5 - */ - requestTimeoutBeforeReady?: number, - /** - * How many quick retries we will do while starting up the SDK. - * @property {number} retriesOnFailureBeforeReady - * @default 1 - */ - retriesOnFailureBeforeReady?: number, - /** - * For SDK posts the queued events data in bulks with a given rate, but the first push window is defined separately, - * to better control on browsers. This number defines that window before the first events push. - * - * @property {number} eventsFirstPushWindow - * @default 10 - */ - eventsFirstPushWindow?: number, - }, - /** - * SDK scheduler settings. - * @property {Object} scheduler - */ - scheduler?: { - /** - * The SDK polls Split servers for changes to feature flag definitions. This parameter controls this polling period in seconds. - * @property {number} featuresRefreshRate - * @default 60 - */ - featuresRefreshRate?: number, - /** - * The SDK sends information on who got what treatment at what time back to Split servers to power analytics. This parameter controls how often this data is sent to Split servers. The parameter should be in seconds. - * @property {number} impressionsRefreshRate - * @default 60 - */ - impressionsRefreshRate?: number, - /** - * The maximum number of impression items we want to queue. If we queue more values, it will trigger a flush and reset the timer. - * If you use a 0 here, the queue will have no maximum size. - * @property {number} impressionsQueueSize - * @default 30000 - */ - impressionsQueueSize?: number, - /** - * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. - * @property {number} metricsRefreshRate - * @default 120 - * @deprecated This parameter is ignored now. Use `telemetryRefreshRate` instead. - */ - metricsRefreshRate?: number, - /** - * The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds. - * @property {number} telemetryRefreshRate - * @default 3600 - */ - telemetryRefreshRate?: number, - /** - * The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds. - * @property {number} segmentsRefreshRate - * @default 60 - */ - segmentsRefreshRate?: number, - /** - * The SDK posts the queued events data in bulks. This parameter controls the posting rate in seconds. - * @property {number} eventsPushRate - * @default 60 - */ - eventsPushRate?: number, - /** - * The maximum number of event items we want to queue. If we queue more values, it will trigger a flush and reset the timer. - * If you use a 0 here, the queue will have no maximum size. - * @property {number} eventsQueueSize - * @default 500 - */ - eventsQueueSize?: number, - /** - * For mocking/testing only. The SDK will refresh the features mocked data when mode is set to "localhost" by defining the key. - * For more information see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode} - * @property {number} offlineRefreshRate - * @default 15 - */ - offlineRefreshRate?: number, - /** - * When using streaming mode, seconds to wait before re attempting to connect for push notifications. - * Next attempts follow intervals in power of two: base seconds, base x 2 seconds, base x 4 seconds, ... - * @property {number} pushRetryBackoffBase - * @default 1 - */ - pushRetryBackoffBase?: number, - }, - /** - * SDK Core settings for the browser. - * @property {Object} core - */ - core: { - /** - * Your SDK key. - * @see {@link https://help.split.io/hc/en-us/articles/360019916211-API-keys} - * @property {string} authorizationKey - */ - authorizationKey: string, - /** - * Customer identifier. Whatever this means to you. - * @see {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} - * @property {SplitKey} key - */ - key: SplitKey, - /** - * Disable labels from being sent to Split backend. Labels may contain sensitive information. - * @property {boolean} labelsEnabled - * @default true - */ - labelsEnabled?: boolean - }, - /** - * Mocked features map. For testing purposes only. For using this you should specify "localhost" as authorizationKey on core settings. - * @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#localhost-mode} - */ - features?: MockedFeaturesMap, - /** - * Defines which kind of storage we can instantiate on the browser. - * Possible storage types are 'MEMORY', which is the default, and 'LOCALSTORAGE'. - * @property {Object} storage - */ - storage?: { - /** - * Storage type to be instantiated by the SDK. - * @property {BrowserStorage} type - * @default 'MEMORY' - */ - type?: BrowserStorage, - /** - * Optional prefix to prevent any kind of data collision between SDK versions. - * @property {string} prefix - * @default 'SPLITIO' - */ - prefix?: string - }, - /** - * List of URLs that the SDK will use as base for it's synchronization functionalities, applicable only when running as standalone. - * Do not change these settings unless you're working an advanced use case, like connecting to the Split proxy. - * @property {Object} urls - */ - urls?: UrlSettings, - /** - * User consent status. Possible values are `'GRANTED'`, which is the default, `'DECLINED'` or `'UNKNOWN'`. - * - `'GRANTED'`: the user grants consent for tracking events and impressions. The SDK sends them to Split cloud. - * - `'DECLINED'`: the user declines consent for tracking events and impressions. The SDK does not send them to Split cloud. - * - `'UNKNOWN'`: the user neither grants nor declines consent for tracking events and impressions. The SDK tracks them in its internal storage, and eventually either sends - * them or not if the consent status is updated to 'GRANTED' or 'DECLINED' respectively. The status can be updated at any time with the `UserConsent.setStatus` factory method. - * - * @typedef {string} userConsent - * @default 'GRANTED' - */ - userConsent?: ConsentStatus, - sync?: ISharedSettings['sync'] & { - /** - * Custom options object for HTTP(S) requests in the Browser. - * If provided, this object is merged with the options object passed by the SDK for EventSource and Fetch calls. - */ - requestOptions?: { - /** - * Custom function called before each request, allowing you to add or update headers in SDK HTTP requests. - * Some headers, such as `SplitSDKVersion`, are required by the SDK and cannot be overridden. - * To pass multiple headers with the same name, combine their values into a single line, separated by commas. Example: `{ 'Authorization': 'value1, value2' }` - * Or provide keys with different case since headers are case-insensitive. Example: `{ 'authorization': 'value1', 'Authorization': 'value2' }` - * - * NOTE: to pass custom headers to the streaming connection in Browser, you should polyfill the `window.EventSource` object with a library that supports headers, - * like https://www.npmjs.com/package/event-source-polyfill, since native EventSource does not support them and will be ignored. - * - * @property getHeaderOverrides - * @default undefined - * - * @param context - The context for the request. - * @param context.headers - The current headers in the request. - * @returns A set of headers to be merged with the current headers. - * - * @example - * const getHeaderOverrides = (context) => { - * return { - * 'Authorization': context.headers['Authorization'] + ', other-value', - * 'custom-header': 'custom-value' - * }; - * }; - */ - getHeaderOverrides?: (context: { headers: Record }) => Record - }, - } - } - /** - * Settings interface for SDK instances created on NodeJS. - * If your storage is asynchronous (Redis for example) use SplitIO.INodeAsyncSettings instead. - * @interface INodeSettings - * @extends INodeBasicSettings - * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} - */ - interface INodeSettings extends INodeBasicSettings { - /** - * List of URLs that the SDK will use as base for it's synchronization functionalities, applicable only when running as standalone. - * Do not change these settings unless you're working an advanced use case, like connecting to the Split proxy. - * @property {Object} urls - */ - urls?: UrlSettings, - /** - * Defines which kind of storage we can instantiate on NodeJS for 'standalone' mode. - * The only possible storage type is 'MEMORY', which is the default. - * @property {Object} storage - */ - storage?: { - /** - * Synchronous storage type to be instantiated by the SDK. - * @property {NodeSyncStorage} type - * @default 'MEMORY' - */ - type?: NodeSyncStorage, - /** - * Optional prefix to prevent any kind of data collision between SDK versions. - * @property {string} prefix - * @default 'SPLITIO' - */ - prefix?: string - }, - /** - * The SDK mode. When using the default 'MEMORY' storage, the only possible value is "standalone", which is the default. - * For "localhost" mode, use "localhost" as authorizationKey. - * - * @property {'standalone'} mode - * @default 'standalone' - */ - mode?: 'standalone' - sync?: INodeBasicSettings['sync'] & { - /** - * Custom options object for HTTP(S) requests in NodeJS. - * If provided, this object is merged with the options object passed by the SDK for EventSource and Node-Fetch calls. - * @see {@link https://www.npmjs.com/package/node-fetch#options} - */ - requestOptions?: { - /** - * Custom function called before each request, allowing you to add or update headers in SDK HTTP requests. - * Some headers, such as `SplitSDKVersion`, are required by the SDK and cannot be overridden. - * To pass multiple headers with the same name, combine their values into a single line, separated by commas. Example: `{ 'Authorization': 'value1, value2' }` - * Or provide keys with different case since headers are case-insensitive. Example: `{ 'authorization': 'value1', 'Authorization': 'value2' }` - * - * @property getHeaderOverrides - * @default undefined - * - * @param context - The context for the request. - * @param context.headers - The current headers in the request. - * @returns A set of headers to be merged with the current headers. - * - * @example - * const getHeaderOverrides = (context) => { - * return { - * 'Authorization': context.headers['Authorization'] + ', other-value', - * 'custom-header': 'custom-value' - * }; - * }; - */ - getHeaderOverrides?: (context: { headers: Record }) => Record - /** - * Custom NodeJS HTTP(S) Agent used by the SDK for HTTP(S) requests. - * - * You can use it, for example, for certificate pinning or setting a network proxy: - * - * ```javascript - * const { HttpsProxyAgent } = require('https-proxy-agent'); - * - * const proxyAgent = new HttpsProxyAgent(process.env.HTTPS_PROXY || 'http://10.10.1.10:1080'); - * - * const factory = SplitFactory({ - * ... - * sync: { - * requestOptions: { - * agent: proxyAgent - * } - * } - * }) - * ``` - * - * @see {@link https://nodejs.org/api/https.html#class-httpsagent} - * - * @property {http.Agent | https.Agent} agent - * @default undefined - */ - agent?: RequestOptions["agent"] - }, - } - } - /** - * Settings interface with async storage for SDK instances created on NodeJS. - * If your storage is synchronous (by defaut we use memory, which is sync) use SplitIO.INodeSettings instead. - * @interface INodeAsyncSettings - * @extends INodeBasicSettings - * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} - */ - interface INodeAsyncSettings extends INodeBasicSettings { - /** - * Defines which kind of async storage we can instantiate on NodeJS for 'consumer' mode. - * The only possible storage type is 'REDIS'. - * @property {Object} storage - */ - storage: { - /** - * 'REDIS' storage type to be instantiated by the SDK. - * @property {NodeAsyncStorage} type - */ - type: NodeAsyncStorage, - /** - * Options to be passed to the Redis storage. Use it with storage type: 'REDIS'. - * @property {Object} options - */ - options?: { - /** - * Redis URL. If set, `host`, `port`, `db` and `pass` params will be ignored. - * - * Examples: - * ``` - * url: 'localhost' - * url: '127.0.0.1:6379' - * url: 'redis://:authpassword@127.0.0.1:6379/0' - * ``` - * @property {string=} url - */ - url?: string, - /** - * Redis host. - * @property {string=} host - * @default 'localhost' - */ - host?: string, - /** - * Redis port. - * @property {number=} port - * @default 6379 - */ - port?: number, - /** - * Redis database to be used. - * @property {number=} db - * @default 0 - */ - db?: number, - /** - * Redis password. Don't define if no password is used. - * @property {string=} pass - * @default undefined - */ - pass?: string, - /** - * The milliseconds before a timeout occurs during the initial connection to the Redis server. - * @property {number=} connectionTimeout - * @default 10000 - */ - connectionTimeout?: number, - /** - * The milliseconds before Redis commands are timeout by the SDK. - * Method calls that involve Redis commands, like `client.getTreatment` or `client.track` calls, are resolved when the commands success or timeout. - * @property {number=} operationTimeout - * @default 5000 - */ - operationTimeout?: number, - /** - * TLS configuration for Redis connection. - * @see {@link https://www.npmjs.com/package/ioredis#tls-options } - * - * @property {Object=} tls - * @default undefined - */ - tls?: RedisOptions['tls'], - }, - /** - * Optional prefix to prevent any kind of data collision between SDK versions. - * @property {string} prefix - * @default 'SPLITIO' - */ - prefix?: string - }, - /** - * The SDK mode. When using 'REDIS' storage type, the only possible value is "consumer", which is required. - * - * @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#state-sharing-redis-integration} - * - * @property {'consumer'} mode - */ - mode: 'consumer' - } - /** - * This represents the interface for the SDK instance with synchronous storage. - * @interface ISDK - * @extends IBasicSDK - */ - interface ISDK extends IBasicSDK { - /** - * Returns the default client instance of the SDK. - * @function client - * @returns {IClient} The client instance. - */ - client(): IClient, - /** - * Returns a manager instance of the SDK to explore available information. - * @function manager - * @returns {IManager} The manager instance. - */ - manager(): IManager - } - /** - * This represents the interface for the SDK instance with synchronous storage. - * @interface IBrowserSDK - * @extends IBasicSDK - */ - interface IBrowserSDK extends IBasicSDK { - /** - * Returns the default client instance of the SDK. - * @function client - * @returns {IBrowserClient} The client instance. - */ - client(): IBrowserClient, - /** - * Returns a shared client of the SDK. - * @function client - * @param {SplitKey} key The key for the new client instance. - * @returns {IBrowserClient} The client instance. - */ - client(key: SplitKey): IBrowserClient - /** - * Returns a manager instance of the SDK to explore available information. - * @function manager - * @returns {IManager} The manager instance. - */ - manager(): IManager, - /** - * User consent API. - * @property UserConsent - */ - UserConsent: IUserConsentAPI - } - /** - * This represents the interface for the SDK instance with asynchronous storage. - * @interface IAsyncSDK - * @extends IBasicSDK - */ - interface IAsyncSDK extends IBasicSDK { - /** - * Returns the default client instance of the SDK. - * @function client - * @returns {IAsyncClient} The asynchronous client instance. - */ - client(): IAsyncClient, - /** - * Returns a manager instance of the SDK to explore available information. - * @function manager - * @returns {IManager} The manager instance. - */ - manager(): IAsyncManager - } - /** - * This represents the interface for the Client instance on server-side, where the user key is not bound to the instance and must be provided on each method call. - * This interface is available in NodeJS, or when importing the 'server' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/server'`). - * - * @interface IClient - * @extends IBasicClient - */ - interface IClient extends IBasicClient { - /** - * Returns a Treatment value, which is the treatment string for the given feature. - * - * @function getTreatment - * @param {string} key - The string key representing the consumer. - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatment} The treatment string. - */ - getTreatment(key: SplitKey, featureFlagName: string, attributes?: Attributes): Treatment, - /** - * Returns a TreatmentWithConfig value, which is an object with both treatment and config string for the given feature. - * - * @function getTreatmentWithConfig - * @param {string} key - The string key representing the consumer. - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentWithConfig} The TreatmentWithConfig, the object containing the treatment string and the - * configuration stringified JSON (or null if there was no config for that treatment). - */ - getTreatmentWithConfig(key: SplitKey, featureFlagName: string, attributes?: Attributes): TreatmentWithConfig, - /** - * Returns a Treatments value, which is an object map with the treatments for the given features. - * - * @function getTreatments - * @param {string} key - The string key representing the consumer. - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The treatments object map. - */ - getTreatments(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * - * @function getTreatmentsWithConfig - * @param {string} key - The string key representing the consumer. - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. - * - * @function getTreatmentsByFlagSet - * @param {string} key - The string key representing the consumer. - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. - * - * @function getTreatmentsWithConfigByFlagSet - * @param {string} key - The string key representing the consumer. - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. - * - * @function getTreatmentsByFlagSets - * @param {string} key - The string key representing the consumer. - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. - * - * @function getTreatmentsWithConfigByFlagSets - * @param {string} key - The string key representing the consumer. - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Tracks an event to be fed to the results product on Split user interface. - * - * @function track - * @param {SplitKey} key - The key that identifies the entity related to this event. - * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} - * @param {string} eventType - The event type corresponding to this event. - * @param {number=} value - The value of this event. - * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. - * @returns {boolean} Whether the event was added to the queue successfully or not. - */ - track(key: SplitIO.SplitKey, trafficType: string, eventType: string, value?: number, properties?: Properties): boolean, - } - /** - * This represents the interface for the Client instance on client-side, where the user key is bound to the instance on creation and does not need to be provided on each method call. - * This interface is the default when importing the SDK in the Browser, or when importing the 'client' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/client'`). - * - * @interface IBrowserClient - * @extends IBasicClient - */ - interface IBrowserClient extends IBasicClient { - /** - * Returns a Treatment value, which is the treatment string for the given feature. - * - * @function getTreatment - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatment} The treatment string. - */ - getTreatment(featureFlagName: string, attributes?: Attributes): Treatment, - /** - * Returns a TreatmentWithConfig value, which an object with both treatment and config string for the given feature. - * - * @function getTreatmentWithConfig - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentWithConfig} The TreatmentWithConfig, the object containing the treatment string and the - * configuration stringified JSON (or null if there was no config for that treatment). - */ - getTreatmentWithConfig(featureFlagName: string, attributes?: Attributes): TreatmentWithConfig, - /** - * Returns a Treatments value, which is an object map with the treatments for the given features. - * - * @function getTreatments - * @param {Array} featureFlagNames - An array of the feature flags names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The treatments object map. - */ - getTreatments(featureFlagNames: string[], attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * - * @function getTreatmentsWithConfig - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfig(featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. - * - * @function getTreatmentsByFlagSet - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSet(flagSet: string, attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. - * - * @function getTreatmentsWithConfigByFlagSet - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSet(flagSet: string, attributes?: Attributes): TreatmentsWithConfig, - /** - * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. - * - * @function getTreatmentsByFlagSets - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {Treatments} The map with all the Treatments objects - */ - getTreatmentsByFlagSets(flagSets: string[], attributes?: Attributes): Treatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. - * - * @function getTreatmentsWithConfigByFlagSets - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects - */ - getTreatmentsWithConfigByFlagSets(flagSets: string[], attributes?: Attributes): TreatmentsWithConfig, - /** - * Tracks an event to be fed to the results product on Split user interface. - * - * @function track - * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} - * @param {string} eventType - The event type corresponding to this event. - * @param {number=} value - The value of this event. - * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. - * @returns {boolean} Whether the event was added to the queue successfully or not. - */ - track(trafficType: string, eventType: string, value?: number, properties?: Properties): boolean, - /** - * Add an attribute to client's in memory attributes storage. - * - * @param {string} attributeName Attribute name - * @param {AttributeType} attributeValue Attribute value - * @returns {boolean} true if the attribute was stored and false otherwise - */ - setAttribute(attributeName: string, attributeValue: AttributeType): boolean, - /** - * Returns the attribute with the given name. - * - * @param {string} attributeName Attribute name - * @returns {AttributeType} Attribute with the given name - */ - getAttribute(attributeName: string): AttributeType, - /** - * Removes from client's in memory attributes storage the attribute with the given name. - * - * @param {string} attributeName - * @returns {boolean} true if attribute was removed and false otherwise - */ - removeAttribute(attributeName: string): boolean, - /** - * Add to client's in memory attributes storage the attributes in 'attributes'. - * - * @param {Attributes} attributes Object with attributes to store - * @returns true if attributes were stored an false otherwise - */ - setAttributes(attributes: Attributes): boolean, - /** - * Return all the attributes stored in client's in memory attributes storage. - * - * @returns {Attributes} returns all the stored attributes - */ - getAttributes(): Attributes, - /** - * Remove all the stored attributes in the client's in memory attribute storage. - * - * @returns {boolean} true if all attribute were removed and false otherwise - */ - clearAttributes(): boolean - } - /** - * This represents the interface for the Client instance on server-side with asynchronous storage, like REDIS. - * User key is not bound to the instance and must be provided on each method call, which returns a promise. - * This interface is available in NodeJS, or when importing the 'server' sub-package (e.g., `import { SplitFactory } from '@splitsoftware/splitio/server'`). - * - * @interface IAsyncClient - * @extends IBasicClient - */ - interface IAsyncClient extends IBasicClient { - /** - * Returns a Treatment value, which will be (or eventually be) the treatment string for the given feature. - * - * @function getTreatment - * @param {string} key - The string key representing the consumer. - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatment} Treatment promise that resolves to the treatment string. - */ - getTreatment(key: SplitKey, featureFlagName: string, attributes?: Attributes): AsyncTreatment, - /** - * Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for the given feature. - * - * @function getTreatmentWithConfig - * @param {string} key - The string key representing the consumer. - * @param {string} featureFlagName - The string that represents the feature flag we want to get the treatment. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatmentWithConfig} TreatmentWithConfig promise that resolves to the TreatmentWithConfig object. - */ - getTreatmentWithConfig(key: SplitKey, featureFlagName: string, attributes?: Attributes): AsyncTreatmentWithConfig, - /** - * Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the given features. - * - * @function getTreatments - * @param {string} key - The string key representing the consumer. - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatments} Treatments promise that resolves to the treatments object map. - */ - getTreatments(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatments, - /** - * Returns a TreatmentsWithConfig value, which will be (or eventually be) an object map with the TreatmentWithConfig (an object with both treatment and config string) for the given features. - * - * @function getTreatmentsWithConfig - * @param {string} key - The string key representing the consumer. - * @param {Array} featureFlagNames - An array of the feature flag names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatmentsWithConfig} TreatmentsWithConfig promise that resolves to the map of TreatmentsWithConfig objects. - */ - getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatmentsWithConfig, - /** - * Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set. - * - * @function getTreatmentsByFlagSet - * @param {string} key - The string key representing the consumer. - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatments} Treatments promise that resolves to the treatments object map. - */ - getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag set. - * - * @function getTreatmentsWithConfigByFlagSet - * @param {string} flagSet - The flag set name we want to get the treatments. - * @param {string} key - The string key representing the consumer. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatmentsWithConfig} TreatmentsWithConfig promise that resolves to the TreatmentsWithConfig object. - */ - getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatmentsWithConfig, - /** - * Returns a Returns a Treatments value, which is an object with both treatment and config string for to the feature flags related to the given flag sets. - * - * @function getTreatmentsByFlagSets - * @param {string} key - The string key representing the consumer. - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatments} Treatments promise that resolves to the treatments object map. - */ - getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatments, - /** - * Returns a TreatmentsWithConfig value, which is an object map with the TreatmentWithConfig (an object with both treatment and config string) for the feature flags related to the given flag sets. - * - * @function getTreatmentsWithConfigByFlagSets - * @param {string} key - The string key representing the consumer. - * @param {Array} flagSets - An array of the flag set names we want to get the treatments. - * @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key. - * @returns {AsyncTreatmentsWithConfig} TreatmentsWithConfig promise that resolves to the TreatmentsWithConfig object. - */ - getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatmentsWithConfig, - /** - * Tracks an event to be fed to the results product on Split user interface, and returns a promise to signal when the event was successfully queued (or not). - * - * @function track - * @param {SplitKey} key - The key that identifies the entity related to this event. - * @param {string} trafficType - The traffic type of the entity related to this event. See {@link https://help.split.io/hc/en-us/articles/360019916311-Traffic-type} - * @param {string} eventType - The event type corresponding to this event. - * @param {number=} value - The value of this event. - * @param {Properties=} properties - The properties of this event. Values can be string, number, boolean or null. - * @returns {Promise} A promise that resolves to a boolean indicating if the event was added to the queue successfully or not. - */ - track(key: SplitIO.SplitKey, trafficType: string, eventType: string, value?: number, properties?: Properties): Promise - } - /** - * Representation of a manager instance with synchronous storage of the SDK. - * @interface IManager - * @extends IStatusInterface - */ - interface IManager extends IStatusInterface { - /** - * Get the array of feature flag names. - * @function names - * @returns {SplitNames} The list of feature flag names. - */ - names(): SplitNames; - /** - * Get the array of feature flags data in SplitView format. - * @function splits - * @returns {SplitViews} The list of SplitIO.SplitView. - */ - splits(): SplitViews; - /** - * Get the data of a feature flag in SplitView format. - * @function split - * @param {string} featureFlagName The name of the feature flag we want to get info of. - * @returns {SplitView | null} The SplitIO.SplitView of the given feature flag name or null if the feature flag is not found. - */ - split(featureFlagName: string): SplitView | null; - } - /** - * Representation of a manager instance with asynchronous storage of the SDK. - * @interface IAsyncManager - * @extends IStatusInterface - */ - interface IAsyncManager extends IStatusInterface { - /** - * Get the array of feature flag names. - * @function names - * @returns {SplitNamesAsync} A promise that resolves to the list of feature flag names. - */ - names(): SplitNamesAsync; - /** - * Get the array of feature flags data in SplitView format. - * @function splits - * @returns {SplitViewsAsync} A promise that resolves to the SplitIO.SplitView list. - */ - splits(): SplitViewsAsync; - /** - * Get the data of a feature flag in SplitView format. - * @function split - * @param {string} featureFlagName The name of the feature flag we want to get info of. - * @returns {SplitViewAsync} A promise that resolves to the SplitIO.SplitView value. - */ - split(featureFlagName: string): SplitViewAsync; - } -} From 194e58a84c470f88d7c653a3203b191a5221b00a Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Sat, 26 Oct 2024 12:37:56 -0300 Subject: [PATCH 50/58] Update changelog entry --- CHANGES.txt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/CHANGES.txt b/CHANGES.txt index 4d6b2a445..c5b3767f4 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,12 +5,10 @@ - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. - BREAKING CHANGES: - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. + - Renamed some TypeScript definitions in the SplitIO namespace to avoid conflicts with other libraries: `ISDK` to `INodeSDK`, `IAsyncSDK` to `INodeAsyncSDK`, `IBrowserSDK` to `ISDK`, `IClient` to `INodeClient`, `IAsyncClient` to `INodeAsyncClient`, `IBrowserClient` to `IClient`. - Removed internal ponyfills for the `Map` and `Set` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. - Removed the deprecated `GOOGLE_ANALYTICS_TO_SPLIT` and `SPLIT_TO_GOOGLE_ANALYTICS` integrations. The `integrations` configuration option has been removed from the SDK factory configuration, along with the associated interfaces in the TypeScript definitions. - Removed the `core.trafficType` configuration option (`SplitIO.IBrowserSettings['core']['trafficType]`) and the `trafficType` parameter from the SDK `client()` method in Browser (`SplitIO.IBrowserSDK['client']`). As a result, traffic types can no longer be bound to SDK clients, and the traffic type must be provided in the `track` method. - - TypeScript definitions: - - Removed an overloaded `client` method in the `SplitIO.ISDK` interface that accepted `key` and `trafficType` parameters. This interface corresponds to the SDK factory instance in NodeJS, which, unlike `SplitIO.IBrowserSDK` for the Browser, does not handle multiple client instances based on keys. - - Updated the `SplitIO.IBrowserSDK` and `SplitIO.IBrowserClient` interfaces to no longer extend the `SplitIO.ISDK` and `SplitIO.IClient` interfaces respectively, as the SDK factory instance in NodeJS or server-side (`SplitIO.ISDK`) has a different API than the SDK client instance in the Browser or client-side (`SplitIO.IBrowserClient`). 10.28.0 (September 6, 2024) - Updated @splitsoftware/splitio-commons package to version 1.17.0 that includes minor updates: From 93d807e2e6c6719782f528cbec5a05450c9c3bb8 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Mon, 28 Oct 2024 13:01:55 -0300 Subject: [PATCH 51/58] Update eslint config --- .eslintrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 1d7f59384..b410eddeb 100644 --- a/.eslintrc +++ b/.eslintrc @@ -46,7 +46,7 @@ ], "rules": { "no-restricted-syntax": ["error", "ForOfStatement", "ForInStatement", "ArrayPattern"], - "compat/compat": ["error", "defaults, ie 10, node 6"], + "compat/compat": ["error", "defaults, node >=14"], "no-throw-literal": "error", "import/no-default-export": "error", "import/no-self-import": "error" From e2f1b71ad71a44e89c21277aff80e639e25911b5 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Tue, 29 Oct 2024 13:51:53 -0300 Subject: [PATCH 52/58] Update JS-commons and prepare rc --- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- src/settings/defaults/version.js | 2 +- ts-tests/index.ts | 15 +-------------- 4 files changed, 13 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5024d5fc6..5e7c259f2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.3", + "version": "11.0.0-rc.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.3", + "version": "11.0.0-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.4", + "@splitsoftware/splitio-commons": "2.0.0-rc.5", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", @@ -869,9 +869,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.4.tgz", - "integrity": "sha512-z0rm4X9oh7LdIcHeEkh6Ca3JzfdhJ0IH3r7nZ6ghL0AXmPzbezoDswxjKOe/WYBbTW3utsgLqTTjr9Ww/b/hUw==", + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.5.tgz", + "integrity": "sha512-hNLA3cfVj5yGSHpOyTQVzcU2kIceJtJOdatcuue2ENOesjwDHfpvEy/YkIgLcLwXpvUxTFKpZd1BRej8gSbWoA==", "dependencies": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" @@ -8587,9 +8587,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.4", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.4.tgz", - "integrity": "sha512-z0rm4X9oh7LdIcHeEkh6Ca3JzfdhJ0IH3r7nZ6ghL0AXmPzbezoDswxjKOe/WYBbTW3utsgLqTTjr9Ww/b/hUw==", + "version": "2.0.0-rc.5", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.5.tgz", + "integrity": "sha512-hNLA3cfVj5yGSHpOyTQVzcU2kIceJtJOdatcuue2ENOesjwDHfpvEy/YkIgLcLwXpvUxTFKpZd1BRej8gSbWoA==", "requires": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" diff --git a/package.json b/package.json index 6d564c8b1..3a73c4a9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.3", + "version": "11.0.0-rc.4", "description": "Split SDK", "files": [ "README.md", @@ -38,7 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.4", + "@splitsoftware/splitio-commons": "2.0.0-rc.5", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 818b1f165..36355d51c 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '11.0.0-rc.3'; +export const packageVersion = '11.0.0-rc.4'; diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 1cbe834ea..226c17626 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -594,23 +594,9 @@ let fullAsyncSettings: SplitIO.INodeAsyncSettings = { labelsEnabled: false, IPAddressesEnabled: false }, - scheduler: { - featuresRefreshRate: 1, - impressionsRefreshRate: 1, - impressionsQueueSize: 1, - metricsRefreshRate: 1, - telemetryRefreshRate: 1, - segmentsRefreshRate: 1, - offlineRefreshRate: 1, - eventsPushRate: 1, - eventsQueueSize: 1 - }, startup: { readyTimeout: 1, - requestTimeoutBeforeReady: 1, - retriesOnFailureBeforeReady: 1 }, - features: mockedFeaturesPath, storage: { type: 'REDIS', options: { @@ -630,6 +616,7 @@ let fullAsyncSettings: SplitIO.INodeAsyncSettings = { debug: true, sync: { splitFilters: splitFilters, + impressionsMode: 'DEBUG', } }; From e0229c4555ce972f4f480210d11e69f71fee351e Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Wed, 30 Oct 2024 18:02:14 -0300 Subject: [PATCH 53/58] rc in CDN --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..6d498d43d 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/refactor_type_definitions' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/refactor_type_definitions' }} strategy: matrix: environment: diff --git a/CHANGES.txt b/CHANGES.txt index c5b3767f4..d881aa7f5 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -2,7 +2,7 @@ - Added support for targeting rules based on large segments for browsers. - Added `factory.destroy()` method, which invokes the `destroy` method of all clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 2.0.0 that includes major updates and updated some transitive dependencies for vulnerability fixes. - - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for EcmaScript Modules build. + - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for ECMAScript Modules build. - BREAKING CHANGES: - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. - Renamed some TypeScript definitions in the SplitIO namespace to avoid conflicts with other libraries: `ISDK` to `INodeSDK`, `IAsyncSDK` to `INodeAsyncSDK`, `IBrowserSDK` to `ISDK`, `IClient` to `INodeClient`, `IAsyncClient` to `INodeAsyncClient`, `IBrowserClient` to `IClient`. From 7945e0067f65af9429c4bff80ad1883d7bdca861 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 31 Oct 2024 00:32:49 -0300 Subject: [PATCH 54/58] Update ts test --- ts-tests/index.ts | 206 +++++++++++++++++++++++++--------------------- types/index.d.ts | 6 +- 2 files changed, 113 insertions(+), 99 deletions(-) diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 226c17626..562b95b91 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -25,19 +25,19 @@ let trackPromise: Promise; /**** Interfaces ****/ // Facade return interface -let NodeSDK: SplitIO.INodeSDK; -let AsyncSDK: SplitIO.INodeAsyncSDK; -let BrowserSDK: SplitIO.ISDK; +let SDK: SplitIO.ISDK; +let AsyncSDK: SplitIO.IAsyncSDK; +let BrowserSDK: SplitIO.IBrowserSDK; // Settings interfaces let nodeSettings: SplitIO.INodeSettings; let asyncSettings: SplitIO.INodeAsyncSettings; let browserSettings: SplitIO.IBrowserSettings; // Client & Manager APIs -let nodeClient: SplitIO.INodeClient; +let client: SplitIO.IClient; let manager: SplitIO.IManager; -let nodeAsyncClient: SplitIO.INodeAsyncClient; +let asyncClient: SplitIO.IAsyncClient; let asyncManager: SplitIO.IAsyncManager; -let browserClient: SplitIO.IClient; +let browserClient: SplitIO.IBrowserClient; // Utility interfaces let impressionListener: SplitIO.IImpressionListener; @@ -137,7 +137,7 @@ splitViewsAsync = splitViewsPromise; splitKey = 'someKey'; splitKey = splitKeyObj; -/**** Tests for INodeSDK interface ****/ +/**** Tests for ISDK interface ****/ // For node with sync storage nodeSettings = { @@ -162,8 +162,8 @@ browserSettings = { key: 'customer-key' } }; -// With sync settings should return INodeSDK, if settings have async storage it should return INodeAsyncSDK -NodeSDK = SplitFactory(nodeSettings); +// With sync settings should return ISDK, if settings have async storage it should return IAsyncSDK +SDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); @@ -173,38 +173,38 @@ const instantiatedSettingsCore: { key: SplitIO.SplitKey, labelsEnabled: boolean, IPAddressesEnabled: boolean -} = NodeSDK.settings.core; -const instantiatedSettingsMode: ('standalone' | 'consumer' | 'consumer_partial' | 'localhost') = NodeSDK.settings.mode; -const instantiatedSettingsScheduler: { [key: string]: number } = NodeSDK.settings.scheduler; -const instantiatedSettingsStartup: { [key: string]: number } = NodeSDK.settings.startup; -const instantiatedSettingsStorage = NodeSDK.settings.storage as SplitIO.StorageOptions; -const instantiatedSettingsUrls: { [key: string]: string } = NodeSDK.settings.urls; -const instantiatedSettingsVersion: string = NodeSDK.settings.version; -let instantiatedSettingsFeatures = NodeSDK.settings.features as SplitIO.MockedFeaturesMap; +} = SDK.settings.core; +const instantiatedSettingsMode: ('standalone' | 'consumer' | 'consumer_partial' | 'localhost') = SDK.settings.mode; +const instantiatedSettingsScheduler: { [key: string]: number } = SDK.settings.scheduler; +const instantiatedSettingsStartup: { [key: string]: number } = SDK.settings.startup; +const instantiatedSettingsStorage = SDK.settings.storage as SplitIO.StorageOptions; +const instantiatedSettingsUrls: { [key: string]: string } = SDK.settings.urls; +const instantiatedSettingsVersion: string = SDK.settings.version; +let instantiatedSettingsFeatures = SDK.settings.features as SplitIO.MockedFeaturesMap; // We should be able to write on features prop. The rest are readonly props. instantiatedSettingsFeatures.something = 'something'; -NodeSDK.settings.features = 'new_file_path'; // Node -NodeSDK.settings.features = { 'split_x': 'on' }; // Browser +SDK.settings.features = 'new_file_path'; // Node +SDK.settings.features = { 'split_x': 'on' }; // Browser // Client and Manager -nodeClient = NodeSDK.client(); -manager = NodeSDK.manager(); +client = SDK.client(); +manager = SDK.manager(); manager = BrowserSDK.manager(); // Today async clients are only possible on Node. Shared client creation not available here. -nodeAsyncClient = AsyncSDK.client(); +asyncClient = AsyncSDK.client(); asyncManager = AsyncSDK.manager(); // Browser client for attributes binding browserClient = BrowserSDK.client(); browserClient = BrowserSDK.client('a customer key'); // Logger -NodeSDK.Logger.enable(); -NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.DEBUG); -NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.INFO); -NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.WARN); -NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.ERROR); -NodeSDK.Logger.setLogLevel(NodeSDK.Logger.LogLevel.NONE); -NodeSDK.Logger.disable(); +SDK.Logger.enable(); +SDK.Logger.setLogLevel(SDK.Logger.LogLevel.DEBUG); +SDK.Logger.setLogLevel(SDK.Logger.LogLevel.INFO); +SDK.Logger.setLogLevel(SDK.Logger.LogLevel.WARN); +SDK.Logger.setLogLevel(SDK.Logger.LogLevel.ERROR); +SDK.Logger.setLogLevel(SDK.Logger.LogLevel.NONE); +SDK.Logger.disable(); AsyncSDK.Logger.enable(); AsyncSDK.Logger.setLogLevel(AsyncSDK.Logger.LogLevel.DEBUG); @@ -217,163 +217,163 @@ AsyncSDK.Logger.disable(); /**** Tests for IClient interface ****/ // Events constants we get -const eventConsts: { [key: string]: SplitIO.Event } = nodeClient.Event; -splitEvent = nodeClient.Event.SDK_READY; -splitEvent = nodeClient.Event.SDK_READY_FROM_CACHE; -splitEvent = nodeClient.Event.SDK_READY_TIMED_OUT; -splitEvent = nodeClient.Event.SDK_UPDATE; +const eventConsts: { [key: string]: SplitIO.Event } = client.Event; +splitEvent = client.Event.SDK_READY; +splitEvent = client.Event.SDK_READY_FROM_CACHE; +splitEvent = client.Event.SDK_READY_TIMED_OUT; +splitEvent = client.Event.SDK_UPDATE; // Client implements methods from NodeJS.Events. Testing a few. -nodeClient = nodeClient.on(splitEvent, () => { }); -const a: boolean = nodeClient.emit(splitEvent); -nodeClient = nodeClient.removeAllListeners(splitEvent); -nodeClient = nodeClient.removeAllListeners(); -const b: number = nodeClient.listenerCount(splitEvent); -let nodeEventEmitter: NodeJS.EventEmitter = nodeClient; +client = client.on(splitEvent, () => { }); +const a: boolean = client.emit(splitEvent); +client = client.removeAllListeners(splitEvent); +client = client.removeAllListeners(); +const b: number = client.listenerCount(splitEvent); +let nodeEventEmitter: NodeJS.EventEmitter = client; // Ready, destroy and flush -let promise: Promise = nodeClient.ready(); -promise = nodeClient.destroy(); -promise = NodeSDK.destroy(); +let promise: Promise = client.ready(); +promise = client.destroy(); +promise = SDK.destroy(); // @TODO not public yet -// promise = nodeClient.flush(); +// promise = client.flush(); // We can call getTreatment with or without a key. -treatment = nodeClient.getTreatment(splitKey, 'mySplit'); +treatment = client.getTreatment(splitKey, 'mySplit'); treatment = browserClient.getTreatment('mySplit'); // Attributes parameter is optional on both signatures. -treatment = nodeClient.getTreatment(splitKey, 'mySplit', attributes); +treatment = client.getTreatment(splitKey, 'mySplit', attributes); treatment = browserClient.getTreatment('mySplit', attributes); // We can call getTreatments with or without a key. -treatments = nodeClient.getTreatments(splitKey, ['mySplit']); +treatments = client.getTreatments(splitKey, ['mySplit']); treatments = browserClient.getTreatments(['mySplit']); // Attributes parameter is optional on both signatures. -treatments = nodeClient.getTreatments(splitKey, ['mySplit'], attributes); +treatments = client.getTreatments(splitKey, ['mySplit'], attributes); treatments = browserClient.getTreatments(['mySplit'], attributes); // We can call getTreatmentWithConfig with or without a key. -treatmentWithConfig = nodeClient.getTreatmentWithConfig(splitKey, 'mySplit'); +treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit'); treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit'); // Attributes parameter is optional on both signatures. -treatmentWithConfig = nodeClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); +treatmentWithConfig = client.getTreatmentWithConfig(splitKey, 'mySplit', attributes); treatmentWithConfig = browserClient.getTreatmentWithConfig('mySplit', attributes); // We can call getTreatmentsWithConfig with or without a key. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfig(splitKey, ['mySplit']); +treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit']); treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit']); // Attributes parameter is optional on both signatures. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); +treatmentsWithConfig = client.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfig(['mySplit'], attributes); // We can call getTreatmentsByFlagSet with or without a key. -treatments = nodeClient.getTreatmentsByFlagSet(splitKey, 'set_a'); +treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a'); treatments = browserClient.getTreatmentsByFlagSet('set_a'); // Attributes parameter is optional. -treatments = nodeClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); +treatments = client.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); treatments = browserClient.getTreatmentsByFlagSet('set_a', attributes); // We can call getTreatmentsByFlagSets with or without a key. -treatments = nodeClient.getTreatmentsByFlagSets(splitKey, ['set_a']); +treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a']); treatments = browserClient.getTreatmentsByFlagSets(['set_a']); // Attributes parameter is optional. -treatments = nodeClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); +treatments = client.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); treatments = browserClient.getTreatmentsByFlagSets(['set_a'], attributes); // We can call getTreatmentsWithConfigByFlagSet with or without a key. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); +treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a'); // Attributes parameter is optional. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); +treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSet('set_a', attributes); // We can call getTreatmentsWithConfigByFlagSets with or without a key. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); +treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a']); // Attributes parameter is optional. -treatmentsWithConfig = nodeClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); +treatmentsWithConfig = client.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); treatmentsWithConfig = browserClient.getTreatmentsWithConfigByFlagSets(['set_a'], attributes); // We can call track with or without a key. -tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType'); // all params +tracked = client.track(splitKey, 'myTrafficType', 'myEventType'); // all params tracked = browserClient.track('myTrafficType', 'myEventType'); // key bound, tt provided. // Value parameter is optional on all signatures. -tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType', 10); +tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10); tracked = browserClient.track('myTrafficType', 'myEventType', 10); // Properties parameter is optional on all signatures. -tracked = nodeClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); +tracked = client.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: false, prop4: null }); tracked = browserClient.track('myTrafficType', 'myEventType', undefined, { prop1: 1, prop2: '2', prop3: false, prop4: null }); /*** Repeating tests for Async Client ***/ // Events constants we get (same as for sync client, just for interface checking) -const eventConstsAsync: { [key: string]: SplitIO.Event } = nodeAsyncClient.Event; -splitEvent = nodeAsyncClient.Event.SDK_READY; -splitEvent = nodeAsyncClient.Event.SDK_READY_FROM_CACHE; -splitEvent = nodeAsyncClient.Event.SDK_READY_TIMED_OUT; -splitEvent = nodeAsyncClient.Event.SDK_UPDATE; +const eventConstsAsync: { [key: string]: SplitIO.Event } = asyncClient.Event; +splitEvent = asyncClient.Event.SDK_READY; +splitEvent = asyncClient.Event.SDK_READY_FROM_CACHE; +splitEvent = asyncClient.Event.SDK_READY_TIMED_OUT; +splitEvent = asyncClient.Event.SDK_UPDATE; // Client implements methods from NodeJS.Events. (same as for sync client, just for interface checking) -nodeAsyncClient = nodeAsyncClient.on(splitEvent, () => { }); -const a1: boolean = nodeAsyncClient.emit(splitEvent); -nodeAsyncClient = nodeAsyncClient.removeAllListeners(splitEvent); -nodeAsyncClient = nodeAsyncClient.removeAllListeners(); -const b1: number = nodeAsyncClient.listenerCount(splitEvent); -nodeEventEmitter = nodeAsyncClient; +asyncClient = asyncClient.on(splitEvent, () => { }); +const a1: boolean = asyncClient.emit(splitEvent); +asyncClient = asyncClient.removeAllListeners(splitEvent); +asyncClient = asyncClient.removeAllListeners(); +const b1: number = asyncClient.listenerCount(splitEvent); +nodeEventEmitter = asyncClient; // Ready, destroy and flush (same as for sync client, just for interface checking) -promise = nodeAsyncClient.ready(); -promise = nodeAsyncClient.destroy(); +promise = asyncClient.ready(); +promise = asyncClient.destroy(); promise = AsyncSDK.destroy(); // @TODO not public yet -// promise = nodeAsyncClient.flush(); +// promise = asyncClient.flush(); // We can call getTreatment but always with a key. -asyncTreatment = nodeAsyncClient.getTreatment(splitKey, 'mySplit'); +asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit'); // Attributes parameter is optional -asyncTreatment = nodeAsyncClient.getTreatment(splitKey, 'mySplit', attributes); +asyncTreatment = asyncClient.getTreatment(splitKey, 'mySplit', attributes); // We can call getTreatments but always with a key. -asyncTreatments = nodeAsyncClient.getTreatments(splitKey, ['mySplit']); +asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit']); // Attributes parameter is optional -asyncTreatments = nodeAsyncClient.getTreatments(splitKey, ['mySplit'], attributes); +asyncTreatments = asyncClient.getTreatments(splitKey, ['mySplit'], attributes); // We can call getTreatmentWithConfig but always with a key. -asyncTreatmentWithConfig = nodeAsyncClient.getTreatmentWithConfig(splitKey, 'mySplit'); +asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit'); // Attributes parameter is optional -asyncTreatmentWithConfig = nodeAsyncClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); +asyncTreatmentWithConfig = asyncClient.getTreatmentWithConfig(splitKey, 'mySplit', attributes); // We can call getTreatments but always with a key. -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfig(splitKey, ['mySplit']); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit']); // Attributes parameter is optional -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfig(splitKey, ['mySplit'], attributes); // We can call getTreatmentsByFlagSet -asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSet(splitKey, 'set_a'); +asyncTreatments = asyncClient.getTreatmentsByFlagSet(splitKey, 'set_a'); // Attributes parameter is optional -asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); +asyncTreatments = asyncClient.getTreatmentsByFlagSet(splitKey, 'set_a', attributes); // We can call getTreatmentsByFlagSets -asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSets(splitKey, ['set_a']); +asyncTreatments = asyncClient.getTreatmentsByFlagSets(splitKey, ['set_a']); // Attributes parameter is optional -asyncTreatments = nodeAsyncClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); +asyncTreatments = asyncClient.getTreatmentsByFlagSets(splitKey, ['set_a'], attributes); // We can call getTreatmentsWithConfigByFlagSet -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a'); // Attributes parameter is optional -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSet(splitKey, 'set_a', attributes); // We can call getTreatmentsByFlagSets but always with a key. -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a']); // Attributes parameter is optional -asyncTreatmentsWithConfig = nodeAsyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); +asyncTreatmentsWithConfig = asyncClient.getTreatmentsWithConfigByFlagSets(splitKey, ['set_a'], attributes); // We can call track only with a key. -trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType'); // all required params +trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType'); // all required params // Value parameter is optional. -trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10); +trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10); // Properties parameter is optional -trackPromise = nodeAsyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); +trackPromise = asyncClient.track(splitKey, 'myTrafficType', 'myEventType', 10, { prop1: 1, prop2: '2', prop3: true, prop4: null }); /**** Tests for IManager interface ****/ @@ -594,9 +594,23 @@ let fullAsyncSettings: SplitIO.INodeAsyncSettings = { labelsEnabled: false, IPAddressesEnabled: false }, + scheduler: { + featuresRefreshRate: 1, + impressionsRefreshRate: 1, + impressionsQueueSize: 1, + metricsRefreshRate: 1, + telemetryRefreshRate: 1, + segmentsRefreshRate: 1, + offlineRefreshRate: 1, + eventsPushRate: 1, + eventsQueueSize: 1 + }, startup: { readyTimeout: 1, + requestTimeoutBeforeReady: 1, + retriesOnFailureBeforeReady: 1 }, + features: mockedFeaturesPath, storage: { type: 'REDIS', options: { diff --git a/types/index.d.ts b/types/index.d.ts index 2bcd7c7db..e3f81c3e4 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -12,17 +12,17 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.INodeAsyncSDK; + export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.INodeSDK; + export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.ISDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.ISDK; + export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.IBrowserSDK; } From 98df0fd7f6d9df03f38a19b059b82027e7cf175b Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 31 Oct 2024 00:59:00 -0300 Subject: [PATCH 55/58] Upgrade JS-commons --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 1 - package-lock.json | 14 +++++++------- package.json | 2 +- types/client/index.d.ts | 2 +- types/server/index.d.ts | 4 ++-- 6 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6d498d43d..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/refactor_type_definitions' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/refactor_type_definitions' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: diff --git a/CHANGES.txt b/CHANGES.txt index d881aa7f5..c5a6cf638 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -5,7 +5,6 @@ - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for ECMAScript Modules build. - BREAKING CHANGES: - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. - - Renamed some TypeScript definitions in the SplitIO namespace to avoid conflicts with other libraries: `ISDK` to `INodeSDK`, `IAsyncSDK` to `INodeAsyncSDK`, `IBrowserSDK` to `ISDK`, `IClient` to `INodeClient`, `IAsyncClient` to `INodeAsyncClient`, `IBrowserClient` to `IClient`. - Removed internal ponyfills for the `Map` and `Set` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. - Removed the deprecated `GOOGLE_ANALYTICS_TO_SPLIT` and `SPLIT_TO_GOOGLE_ANALYTICS` integrations. The `integrations` configuration option has been removed from the SDK factory configuration, along with the associated interfaces in the TypeScript definitions. - Removed the `core.trafficType` configuration option (`SplitIO.IBrowserSettings['core']['trafficType]`) and the `trafficType` parameter from the SDK `client()` method in Browser (`SplitIO.IBrowserSDK['client']`). As a result, traffic types can no longer be bound to SDK clients, and the traffic type must be provided in the `track` method. diff --git a/package-lock.json b/package-lock.json index 5e7c259f2..446444bdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "11.0.0-rc.4", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.5", + "@splitsoftware/splitio-commons": "2.0.0-rc.6", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", @@ -869,9 +869,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.5", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.5.tgz", - "integrity": "sha512-hNLA3cfVj5yGSHpOyTQVzcU2kIceJtJOdatcuue2ENOesjwDHfpvEy/YkIgLcLwXpvUxTFKpZd1BRej8gSbWoA==", + "version": "2.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.6.tgz", + "integrity": "sha512-A4Dk02ShJBjXqtPro6ylBAPc344Unnyk7YmEmvQqv1x4VUKloLw76PI7FgUgG7bM2UH079jSIeUg8HePW2PL1g==", "dependencies": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" @@ -8587,9 +8587,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.5", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.5.tgz", - "integrity": "sha512-hNLA3cfVj5yGSHpOyTQVzcU2kIceJtJOdatcuue2ENOesjwDHfpvEy/YkIgLcLwXpvUxTFKpZd1BRej8gSbWoA==", + "version": "2.0.0-rc.6", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.6.tgz", + "integrity": "sha512-A4Dk02ShJBjXqtPro6ylBAPc344Unnyk7YmEmvQqv1x4VUKloLw76PI7FgUgG7bM2UH079jSIeUg8HePW2PL1g==", "requires": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" diff --git a/package.json b/package.json index 3a73c4a9f..de1ed2243 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.5", + "@splitsoftware/splitio-commons": "2.0.0-rc.6", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", diff --git a/types/client/index.d.ts b/types/client/index.d.ts index 45efaa984..efa3a8f03 100644 --- a/types/client/index.d.ts +++ b/types/client/index.d.ts @@ -11,5 +11,5 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.IBrowserSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020448791-JavaScript-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.ISDK; + export function SplitFactory(settings: SplitIO.IBrowserSettings): SplitIO.IBrowserSDK; } diff --git a/types/server/index.d.ts b/types/server/index.d.ts index f0e305fce..fcbc2bd59 100644 --- a/types/server/index.d.ts +++ b/types/server/index.d.ts @@ -11,11 +11,11 @@ declare module JsSdk { * The settings parameter should be an object that complies with the SplitIO.INodeAsyncSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.INodeAsyncSDK; + export function SplitFactory(settings: SplitIO.INodeAsyncSettings): SplitIO.IAsyncSDK; /** * Split.io SDK factory function. * The settings parameter should be an object that complies with the SplitIO.INodeSettings. * For more information read the corresponding article: @see {@link https://help.split.io/hc/en-us/articles/360020564931-Node-js-SDK#configuration} */ - export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.INodeSDK; + export function SplitFactory(settings: SplitIO.INodeSettings): SplitIO.ISDK; } From 94670959378cc005515b6ad56e79ce6eb74290b3 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 31 Oct 2024 11:02:07 -0300 Subject: [PATCH 56/58] Update ts test --- ts-tests/index.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ts-tests/index.ts b/ts-tests/index.ts index 562b95b91..2e2588d9f 100644 --- a/ts-tests/index.ts +++ b/ts-tests/index.ts @@ -12,6 +12,8 @@ */ import { SplitFactory } from '../types/index'; +import { SplitFactory as SplitFactoryCS } from '../types/client'; +import { SplitFactory as SplitFactorySS } from '../types/server'; let stringPromise: Promise; let splitNamesPromise: Promise; @@ -166,6 +168,9 @@ browserSettings = { SDK = SplitFactory(nodeSettings); AsyncSDK = SplitFactory(asyncSettings); BrowserSDK = SplitFactory(browserSettings); +SDK = SplitFactorySS(nodeSettings); +AsyncSDK = SplitFactorySS(asyncSettings); +BrowserSDK = SplitFactoryCS(browserSettings); // The settings values the SDK expose. const instantiatedSettingsCore: { From 4c9b7afcc80f1977197c9ea9534e039afee89232 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Thu, 31 Oct 2024 14:07:54 -0300 Subject: [PATCH 57/58] rc --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 2 +- package-lock.json | 4 ++-- package.json | 2 +- src/settings/defaults/version.js | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index d28295fdb..6d498d43d 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/refactor_type_definitions' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/refactor_type_definitions' }} strategy: matrix: environment: diff --git a/CHANGES.txt b/CHANGES.txt index c5a6cf638..ab03511a1 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,4 @@ -11.0.0 (October XX, 2024) +11.0.0 (November 1, 2024) - Added support for targeting rules based on large segments for browsers. - Added `factory.destroy()` method, which invokes the `destroy` method of all clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 2.0.0 that includes major updates and updated some transitive dependencies for vulnerability fixes. diff --git a/package-lock.json b/package-lock.json index 446444bdf..7c93bfadf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.4", + "version": "11.0.0-rc.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.4", + "version": "11.0.0-rc.5", "license": "Apache-2.0", "dependencies": { "@splitsoftware/splitio-commons": "2.0.0-rc.6", diff --git a/package.json b/package.json index de1ed2243..952d43865 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.4", + "version": "11.0.0-rc.5", "description": "Split SDK", "files": [ "README.md", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index 36355d51c..b48d27e57 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '11.0.0-rc.4'; +export const packageVersion = '11.0.0-rc.5'; From 72faa4bb9635c66fe900f06f942be19ed48ec104 Mon Sep 17 00:00:00 2001 From: Emiliano Sanchez Date: Fri, 1 Nov 2024 21:40:45 -0300 Subject: [PATCH 58/58] stable version --- .github/workflows/ci-cd.yml | 4 ++-- CHANGES.txt | 3 ++- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- src/settings/defaults/version.js | 2 +- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci-cd.yml b/.github/workflows/ci-cd.yml index 6d498d43d..d28295fdb 100644 --- a/.github/workflows/ci-cd.yml +++ b/.github/workflows/ci-cd.yml @@ -58,7 +58,7 @@ jobs: run: BUILD_BRANCH=$(echo "${GITHUB_REF#refs/heads/}") npm run build - name: Store assets - if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/refactor_type_definitions' || github.ref == 'refs/heads/master') }} + if: ${{ github.event_name == 'push' && (github.ref == 'refs/heads/development' || github.ref == 'refs/heads/master') }} uses: actions/upload-artifact@v3 with: name: assets @@ -69,7 +69,7 @@ jobs: name: Upload assets runs-on: ubuntu-20.04 needs: build - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/refactor_type_definitions' }} + if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/development' }} strategy: matrix: environment: diff --git a/CHANGES.txt b/CHANGES.txt index ab03511a1..4dfe7bf8d 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,10 @@ 11.0.0 (November 1, 2024) - - Added support for targeting rules based on large segments for browsers. + - Added support for targeting rules based on large segments for browsers (client-side API). - Added `factory.destroy()` method, which invokes the `destroy` method of all clients created by the factory. - Updated @splitsoftware/splitio-commons package to version 2.0.0 that includes major updates and updated some transitive dependencies for vulnerability fixes. - Renamed distribution folders from `/lib` to `/cjs` for CommonJS build, and `/es` to `/esm` for ECMAScript Modules build. - BREAKING CHANGES: + - Dropped support for Split Proxy below version 5.9.0, when using in the browser (client-side API). The SDK now requires Split Proxy 5.9.0 or above. - Dropped support for NodeJS v6. The SDK now requires NodeJS v14 or above. - Removed internal ponyfills for the `Map` and `Set` global objects, dropping support for IE and other outdated browsers. The SDK now requires the runtime environment to support these features natively or provide a polyfill. - Removed the deprecated `GOOGLE_ANALYTICS_TO_SPLIT` and `SPLIT_TO_GOOGLE_ANALYTICS` integrations. The `integrations` configuration option has been removed from the SDK factory configuration, along with the associated interfaces in the TypeScript definitions. diff --git a/package-lock.json b/package-lock.json index 2c9ce39da..d5457999a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,15 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.5", + "version": "11.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.5", + "version": "11.0.0", "license": "Apache-2.0", "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.6", + "@splitsoftware/splitio-commons": "2.0.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", @@ -869,9 +869,9 @@ "dev": true }, "node_modules/@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.6", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.6.tgz", - "integrity": "sha512-A4Dk02ShJBjXqtPro6ylBAPc344Unnyk7YmEmvQqv1x4VUKloLw76PI7FgUgG7bM2UH079jSIeUg8HePW2PL1g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0.tgz", + "integrity": "sha512-Sz4+vFacl29xw3451z9IUgB4zBFKUWZdCnmOB0DDXA803YKPqjXphdAwN6nV+1vsX9pXV/OS6UaNC4oUICa6PA==", "dependencies": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" @@ -8587,9 +8587,9 @@ "dev": true }, "@splitsoftware/splitio-commons": { - "version": "2.0.0-rc.6", - "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0-rc.6.tgz", - "integrity": "sha512-A4Dk02ShJBjXqtPro6ylBAPc344Unnyk7YmEmvQqv1x4VUKloLw76PI7FgUgG7bM2UH079jSIeUg8HePW2PL1g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@splitsoftware/splitio-commons/-/splitio-commons-2.0.0.tgz", + "integrity": "sha512-Sz4+vFacl29xw3451z9IUgB4zBFKUWZdCnmOB0DDXA803YKPqjXphdAwN6nV+1vsX9pXV/OS6UaNC4oUICa6PA==", "requires": { "@types/ioredis": "^4.28.0", "tslib": "^2.3.1" diff --git a/package.json b/package.json index 952d43865..f6083e0b2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@splitsoftware/splitio", - "version": "11.0.0-rc.5", + "version": "11.0.0", "description": "Split SDK", "files": [ "README.md", @@ -38,7 +38,7 @@ "node": ">=14.0.0" }, "dependencies": { - "@splitsoftware/splitio-commons": "2.0.0-rc.6", + "@splitsoftware/splitio-commons": "2.0.0", "bloom-filters": "^3.0.0", "ioredis": "^4.28.0", "js-yaml": "^3.13.1", diff --git a/src/settings/defaults/version.js b/src/settings/defaults/version.js index b48d27e57..087efdda2 100644 --- a/src/settings/defaults/version.js +++ b/src/settings/defaults/version.js @@ -1 +1 @@ -export const packageVersion = '11.0.0-rc.5'; +export const packageVersion = '11.0.0';