diff --git a/package.json b/package.json index 191a123..53da36e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "switcher-client", - "version": "4.4.2", + "version": "4.5.0", "description": "Client JS SDK for working with Switcher-API", "main": "./switcher-client.js", "type": "module", @@ -32,8 +32,8 @@ ], "devDependencies": { "@babel/eslint-parser": "^7.28.4", - "@typescript-eslint/eslint-plugin": "^8.45.0", - "@typescript-eslint/parser": "^8.45.0", + "@typescript-eslint/eslint-plugin": "^8.46.0", + "@typescript-eslint/parser": "^8.46.0", "c8": "^10.1.3", "chai": "^6.2.0", "env-cmd": "^11.0.0", diff --git a/sonar-project.properties b/sonar-project.properties index 1e88e30..4067cc1 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,7 +1,7 @@ sonar.projectKey=switcherapi_switcher-client-master sonar.projectName=switcher-client-js sonar.organization=switcherapi -sonar.projectVersion=4.4.2 +sonar.projectVersion=4.5.0 sonar.links.homepage=https://github.com/switcherapi/switcher-client-js sonar.javascript.lcov.reportPaths=coverage/lcov.info diff --git a/src/client.js b/src/client.js index f82f0b1..d707447 100644 --- a/src/client.js +++ b/src/client.js @@ -118,7 +118,7 @@ export class Client { const snapshot = await validateSnapshot( Client.#context, - GlobalSnapshot.snapshot.data.domain.version + GlobalSnapshot.snapshot.domain.version ); if (snapshot) { @@ -149,7 +149,7 @@ export class Client { Client.watchSnapshot(); } - return GlobalSnapshot.snapshot?.data.domain.version || 0; + return GlobalSnapshot.snapshot?.domain.version || 0; } /** @@ -160,7 +160,7 @@ export class Client { * - GlobalOptions.local is false, meaning it will not use the local snapshot. */ static #isCheckSnapshotAvailable(fetchRemote) { - return GlobalSnapshot.snapshot?.data.domain.version == 0 && (fetchRemote || !GlobalOptions.local); + return GlobalSnapshot.snapshot?.domain.version == 0 && (fetchRemote || !GlobalOptions.local); } static watchSnapshot(callback = {}) { @@ -256,7 +256,7 @@ export class Client { } static get snapshotVersion() { - return GlobalSnapshot.snapshot?.data.domain.version || 0; + return GlobalSnapshot.snapshot?.domain.version || 0; } } diff --git a/src/lib/remote.js b/src/lib/remote.js index a000c2e..a2ced8e 100644 --- a/src/lib/remote.js +++ b/src/lib/remote.js @@ -166,7 +166,7 @@ export async function resolveSnapshot(domain, environment, component) { }); if (response.status == 200) { - return JSON.stringify(response.json(), null, 4); + return JSON.stringify(response.json().data, null, 4); } throw new RemoteError(`[resolveSnapshot] failed with status ${response.status}`); diff --git a/src/lib/resolver.js b/src/lib/resolver.js index 5165dc5..6da3128 100644 --- a/src/lib/resolver.js +++ b/src/lib/resolver.js @@ -4,18 +4,18 @@ import * as util from '../lib/utils/index.js'; import { SwitcherResult } from './result.js'; /** - * Resolves the criteria for a given switcher request against the snapshot data. + * Resolves the criteria for a given switcher request against the snapshot domain. * - * @param {SnapshotData} data - The snapshot data containing domain and group information. + * @param {Domain} domain - The domain containing groups and configurations. * @param {SwitcherRequest} switcher - The switcher request to be evaluated. * @returns {SwitcherResult} - The result of the switcher evaluation. */ -function resolveCriteria(data, switcher) { - if (!data.domain.activated) { +function resolveCriteria(domain, switcher) { + if (!domain.activated) { return SwitcherResult.disabled('Domain disabled'); } - const { group } = data.domain; + const { group } = domain; return checkGroup(group, switcher); } @@ -127,7 +127,7 @@ function isStrategyFulfilled(strategyEntry, strategyConfig) { /** * Checks the criteria for a switcher request against the local snapshot. * - * @param {Snapshot | undefined} snapshot - The snapshot containing the data to check against. + * @param {Snapshot | undefined} snapshot - The snapshot containing the domain to check against. * @param {SwitcherRequest} switcher - The switcher request to be evaluated. * @returns {SwitcherResult} - The result of the switcher evaluation. * @throws {Error} - If the snapshot is not loaded. @@ -137,6 +137,6 @@ export default function checkCriteriaLocal(snapshot, switcher) { throw new Error('Snapshot not loaded. Try to use \'Client.loadSnapshot()\''); } - const { data } = snapshot; - return resolveCriteria(data, switcher); + const { domain } = snapshot; + return resolveCriteria(domain, switcher); } \ No newline at end of file diff --git a/src/lib/snapshot.js b/src/lib/snapshot.js index 652cebc..12e7846 100644 --- a/src/lib/snapshot.js +++ b/src/lib/snapshot.js @@ -14,7 +14,7 @@ const loadDomain = (snapshotLocation, environment) => { if (existsSync(snapshotFile)) { dataBuffer = readFileSync(snapshotFile); } else { - dataBuffer = JSON.stringify({ data: { domain: { version: 0 } } }, null, 4); + dataBuffer = JSON.stringify({ domain: { version: 0 } }, null, 4); if (snapshotLocation.length) { mkdirSync(snapshotLocation, { recursive: true }); @@ -40,7 +40,7 @@ const validateSnapshot = async (context, snapshotVersion) => { }; const checkSwitchersLocal = (snapshot, switcherKeys) => { - const { group } = snapshot.data.domain; + const { group } = snapshot.domain; let notFound = [], found = false; for (const switcher of switcherKeys) { diff --git a/tests/playground/index.js b/tests/playground/index.js index ea0855b..34f9f3c 100644 --- a/tests/playground/index.js +++ b/tests/playground/index.js @@ -187,7 +187,7 @@ const _testSnapshotAutoUpdate = async () => { const time = Date.now(); await switcher.checkValue('user_1').isItOn(SWITCHER_KEY); console.clear(); - console.log(Client.getLogger(SWITCHER_KEY), `executed in ${Date.now() - time}ms`); + console.log(JSON.stringify(Client.getLogger(SWITCHER_KEY)), `executed in ${Date.now() - time}ms`); }, 2000); }; diff --git a/tests/playground/snapshot/default.json b/tests/playground/snapshot/default.json index 7747d85..39cb896 100644 --- a/tests/playground/snapshot/default.json +++ b/tests/playground/snapshot/default.json @@ -1,34 +1,32 @@ { - "data": { - "domain": { - "name": "Switcher API", - "version": 1, - "activated": true, - "group": [ - { - "name": "Test Project", - "activated": true, - "config": [ - { - "key": "CLIENT_JS_FEATURE", - "activated": true, - "strategies": [ - { - "strategy": "VALUE_VALIDATION", - "activated": false, - "operation": "EXIST", - "values": [ - "user_1" - ] - } - ], - "components": [ - "switcher-client-js" - ] - } - ] - } - ] - } + "domain": { + "name": "Switcher API", + "version": 1, + "activated": true, + "group": [ + { + "name": "Test Project", + "activated": true, + "config": [ + { + "key": "CLIENT_JS_FEATURE", + "activated": true, + "strategies": [ + { + "strategy": "VALUE_VALIDATION", + "activated": false, + "operation": "EXIST", + "values": [ + "user_1" + ] + } + ], + "components": [ + "switcher-client-js" + ] + } + ] + } + ] } } \ No newline at end of file diff --git a/tests/playground/snapshot/local.json b/tests/playground/snapshot/local.json index 3df5455..1f71cc1 100644 --- a/tests/playground/snapshot/local.json +++ b/tests/playground/snapshot/local.json @@ -1,25 +1,23 @@ { - "data": { - "domain": { - "name": "Switcher API", - "version": 1, - "activated": true, - "group": [ - { - "name": "Test Project", - "activated": true, - "config": [ - { - "key": "CLIENT_JS_FEATURE", - "activated": true, - "strategies": [], - "components": [ - "switcher-client-js" - ] - } - ] - } - ] - } + "domain": { + "name": "Switcher API", + "version": 1, + "activated": true, + "group": [ + { + "name": "Test Project", + "activated": true, + "config": [ + { + "key": "CLIENT_JS_FEATURE", + "activated": true, + "strategies": [], + "components": [ + "switcher-client-js" + ] + } + ] + } + ] } } \ No newline at end of file diff --git a/tests/snapshot/default.json b/tests/snapshot/default.json index a2d3174..f51b04c 100644 --- a/tests/snapshot/default.json +++ b/tests/snapshot/default.json @@ -1,161 +1,159 @@ { - "data": { - "domain": { - "name": "Business", - "description": "Business description", - "activated": true, - "group": [ - { - "name": "Rollout 2020", - "description": "Changes that will be applied during the rollout", - "activated": true, - "config": [ - { - "key": "FF2FOR2020", - "description": "Feature Flag", - "activated": true, - "strategies": [ - { - "strategy": "NETWORK_VALIDATION", - "activated": true, - "operation": "EXIST", - "values": [ - "10.0.0.3/24" - ] - }, - { - "strategy": "VALUE_VALIDATION", - "activated": true, - "operation": "NOT_EXIST", - "values": [ - "USA", - "Canada", - "Australia", - "Africa" - ] - } - ], - "components": [] - }, - { - "key": "FF2FOR2021", - "description": "Strategy disabled", - "activated": true, - "strategies": [ - { - "strategy": "NETWORK_VALIDATION", - "activated": false, - "operation": "EXIST", - "values": [ - "10.0.0.3/24" - ] - } - ], - "components": [] - }, - { - "key": "FF2FOR2022", - "description": "No strategies", - "activated": true, - "components": [] - }, - { - "key": "FF2FOR2023", - "description": "Feature Flag - Payload Strategy", - "activated": true, - "strategies": [ - { - "strategy": "PAYLOAD_VALIDATION", - "activated": true, - "operation": "HAS_ALL", - "values": [ - "id", "user", "user.login", "user.role" - ] - } - ], - "components": [] - }, - { - "key": "FF2FOR2024", - "description": "reDOS safe test", - "activated": true, - "strategies": [ - { - "strategy": "REGEX_VALIDATION", - "activated": true, - "operation": "EXIST", - "values": [ - "^(([a-z])+.)+[A-Z]([a-z])+$" - ] - } - ], - "components": [] - } - ] - }, - { - "name": "Rollout 2030", - "description": "Changes that will be applied during the rollout", - "activated": true, - "config": [ - { - "key": "FF2FOR2030", - "description": "Feature Flag", - "activated": true, - "strategies": [], - "components": [] - }, - { - "key": "FF2FOR2031", - "description": "Feature Flag disabled", - "activated": false, - "strategies": [], - "components": [] - } - ] - }, - { - "name": "Rollout 2040", - "description": "Project is disabled", - "activated": false, - "config": [ - { - "key": "FF2FOR2040", - "description": "Feature Flag", - "activated": true, - "strategies": [], - "components": [] - } - ] - }, - { - "name": "Relay test", - "description": "Relay group", - "activated": true, - "config": [ - { - "key": "USECASE103", - "description": "Relay enabled", - "activated": true, - "relay": { - "type": "VALIDATOR", - "activated": true + "domain": { + "name": "Business", + "description": "Business description", + "activated": true, + "group": [ + { + "name": "Rollout 2020", + "description": "Changes that will be applied during the rollout", + "activated": true, + "config": [ + { + "key": "FF2FOR2020", + "description": "Feature Flag", + "activated": true, + "strategies": [ + { + "strategy": "NETWORK_VALIDATION", + "activated": true, + "operation": "EXIST", + "values": [ + "10.0.0.3/24" + ] }, - "components": [] + { + "strategy": "VALUE_VALIDATION", + "activated": true, + "operation": "NOT_EXIST", + "values": [ + "USA", + "Canada", + "Australia", + "Africa" + ] + } + ], + "components": [] + }, + { + "key": "FF2FOR2021", + "description": "Strategy disabled", + "activated": true, + "strategies": [ + { + "strategy": "NETWORK_VALIDATION", + "activated": false, + "operation": "EXIST", + "values": [ + "10.0.0.3/24" + ] + } + ], + "components": [] + }, + { + "key": "FF2FOR2022", + "description": "No strategies", + "activated": true, + "components": [] + }, + { + "key": "FF2FOR2023", + "description": "Feature Flag - Payload Strategy", + "activated": true, + "strategies": [ + { + "strategy": "PAYLOAD_VALIDATION", + "activated": true, + "operation": "HAS_ALL", + "values": [ + "id", "user", "user.login", "user.role" + ] + } + ], + "components": [] + }, + { + "key": "FF2FOR2024", + "description": "reDOS safe test", + "activated": true, + "strategies": [ + { + "strategy": "REGEX_VALIDATION", + "activated": true, + "operation": "EXIST", + "values": [ + "^(([a-z])+.)+[A-Z]([a-z])+$" + ] + } + ], + "components": [] + } + ] + }, + { + "name": "Rollout 2030", + "description": "Changes that will be applied during the rollout", + "activated": true, + "config": [ + { + "key": "FF2FOR2030", + "description": "Feature Flag", + "activated": true, + "strategies": [], + "components": [] + }, + { + "key": "FF2FOR2031", + "description": "Feature Flag disabled", + "activated": false, + "strategies": [], + "components": [] + } + ] + }, + { + "name": "Rollout 2040", + "description": "Project is disabled", + "activated": false, + "config": [ + { + "key": "FF2FOR2040", + "description": "Feature Flag", + "activated": true, + "strategies": [], + "components": [] + } + ] + }, + { + "name": "Relay test", + "description": "Relay group", + "activated": true, + "config": [ + { + "key": "USECASE103", + "description": "Relay enabled", + "activated": true, + "relay": { + "type": "VALIDATOR", + "activated": true }, - { - "key": "USECASE104", - "description": "Relay disabled", - "relay": { - "type": "VALIDATOR", - "activated": false - }, - "activated": true, - "components": [] - } - ] - } - ] - } + "components": [] + }, + { + "key": "USECASE104", + "description": "Relay disabled", + "relay": { + "type": "VALIDATOR", + "activated": false + }, + "activated": true, + "components": [] + } + ] + } + ] } } \ No newline at end of file diff --git a/tests/snapshot/default_disabled.json b/tests/snapshot/default_disabled.json index 7d30c80..e70b62f 100644 --- a/tests/snapshot/default_disabled.json +++ b/tests/snapshot/default_disabled.json @@ -1,10 +1,8 @@ { - "data": { - "domain": { - "name": "Business", - "description": "Business description", - "activated": false, - "group": [] - } + "domain": { + "name": "Business", + "description": "Business description", + "activated": false, + "group": [] } } \ No newline at end of file diff --git a/tests/snapshot/dev.json b/tests/snapshot/dev.json index 4ec6ed6..1a0c957 100644 --- a/tests/snapshot/dev.json +++ b/tests/snapshot/dev.json @@ -1,26 +1,24 @@ { - "data": { - "domain": { - "name": "Business", - "description": "Business description", - "version": 1588557288037, - "activated": true, - "group": [ - { - "name": "Rollout 2030", - "description": "Changes that will be applied during the rollout", - "activated": true, - "config": [ - { - "key": "FF2FOR2030", - "description": "Feature Flag", - "activated": false, - "strategies": [], - "components": [] - } - ] - } - ] - } + "domain": { + "name": "Business", + "description": "Business description", + "version": 1588557288037, + "activated": true, + "group": [ + { + "name": "Rollout 2030", + "description": "Changes that will be applied during the rollout", + "activated": true, + "config": [ + { + "key": "FF2FOR2030", + "description": "Feature Flag", + "activated": false, + "strategies": [], + "components": [] + } + ] + } + ] } } \ No newline at end of file diff --git a/tests/snapshot/dev_v2.json b/tests/snapshot/dev_v2.json index 17dd1d2..ed53063 100644 --- a/tests/snapshot/dev_v2.json +++ b/tests/snapshot/dev_v2.json @@ -1,26 +1,24 @@ { - "data": { - "domain": { - "name": "Business", - "description": "Business description", - "version": 1588557288040, - "activated": true, - "group": [ - { - "name": "Rollout 2030", - "description": "Changes that will be applied during the rollout", - "activated": true, - "config": [ - { - "key": "FF2FOR2030", - "description": "Feature Flag", - "activated": true, - "strategies": [], - "components": [] - } - ] - } - ] - } + "domain": { + "name": "Business", + "description": "Business description", + "version": 1588557288040, + "activated": true, + "group": [ + { + "name": "Rollout 2030", + "description": "Changes that will be applied during the rollout", + "activated": true, + "config": [ + { + "key": "FF2FOR2030", + "description": "Feature Flag", + "activated": true, + "strategies": [], + "components": [] + } + ] + } + ] } } \ No newline at end of file diff --git a/tests/switcher-snapshot.test.js b/tests/switcher-snapshot.test.js index 3ead6c3..35e6c4d 100644 --- a/tests/switcher-snapshot.test.js +++ b/tests/switcher-snapshot.test.js @@ -20,7 +20,7 @@ describe('E2E test - Switcher local - Snapshot:', function () { const url = 'http://localhost:3000'; const dataBuffer = readFileSync('./tests/snapshot/dev.json'); - const dataJSON = dataBuffer.toString(); + const dataJSON = `{ "data": ${dataBuffer.toString()} }`; let fetchStub; @@ -277,7 +277,7 @@ describe('E2E test - Snapshot AutoUpdater:', function () { const dataJSON = dataBuffer.toString(); const dataBufferV2 = readFileSync('./tests/snapshot/dev_v2.json'); - const dataJSONV2 = dataBufferV2.toString(); + const dataJSONV2 = `{ "data": ${dataBufferV2.toString()} }`; let fetchStub; diff --git a/tests/switcher-watch-snapshot.test.js b/tests/switcher-watch-snapshot.test.js index 36ab084..179b053 100644 --- a/tests/switcher-watch-snapshot.test.js +++ b/tests/switcher-watch-snapshot.test.js @@ -10,7 +10,7 @@ let devJSON; const updateSwitcher = (environment, status) => { const copyOfDevJSON = JSON.parse(JSON.stringify(devJSON)); - copyOfDevJSON.data.domain.group[0].config[0].activated = status; + copyOfDevJSON.domain.group[0].config[0].activated = status; writeFileSync(`generated-watch-snapshots/${environment}.json`, JSON.stringify(copyOfDevJSON, null, 4)); }; @@ -25,7 +25,7 @@ const beforeAll = () => { const dataBuffer = readFileSync('./tests/snapshot/dev.json'); devJSON = JSON.parse(dataBuffer.toString()); - devJSON.data.domain.group[0].config[0].activated = true; + devJSON.domain.group[0].config[0].activated = true; }; const afterAll = () => {