diff --git a/src/lib/resolver.js b/src/lib/resolver.js index 07bd6c7..cd07352 100644 --- a/src/lib/resolver.js +++ b/src/lib/resolver.js @@ -1,7 +1,8 @@ import { processOperation } from './snapshot.js'; import { getEntry } from '../lib/remote.js'; +import * as util from '../lib/utils/index.js'; -async function resolveCriteria(key, input, { domain }) { +async function resolveCriteria({ domain }, switcher) { let result = true, reason = ''; try { @@ -10,8 +11,8 @@ async function resolveCriteria(key, input, { domain }) { } const { group } = domain; - if (!(await checkGroup(group, key, input))) { - throw new Error(`Something went wrong: {"error":"Unable to load a key ${key}"}`); + if (!(await checkGroup(group, switcher))) { + throw new Error(`Something went wrong: {"error":"Unable to load a key ${switcher.key}"}`); } reason = 'Success'; @@ -32,18 +33,19 @@ async function resolveCriteria(key, input, { domain }) { /** * @param {*} groups from a specific Domain - * @param {*} key to be filtered - * @param {*} input strategy if exists + * @param {*} switcher Switcher to check * @return true if Switcher found */ -async function checkGroup(groups, key, input) { +async function checkGroup(groups, switcher) { + const key = util.get(switcher.key, ''); + if (groups) { for (const group of groups) { const { config } = group; const configFound = config.filter(c => c.key === key); // Switcher Configs are always supplied as the snapshot is loaded from components linked to the Switcher. - if (await checkConfig(group, configFound[0], input)) { + if (await checkConfig(group, configFound[0], switcher)) { return true; } } @@ -54,10 +56,10 @@ async function checkGroup(groups, key, input) { /** * @param {*} group in which Switcher has been found * @param {*} config Switcher found - * @param {*} input Strategy input if exists + * @param {*} switcher Switcher to check * @return true if Switcher found */ -async function checkConfig(group, config, input) { +async function checkConfig(group, config, switcher) { if (!config) { return false; } @@ -71,7 +73,7 @@ async function checkConfig(group, config, input) { } if (config.strategies) { - return await checkStrategy(config, input); + return await checkStrategy(config, util.get(switcher.input, [])); } return true; @@ -103,13 +105,13 @@ async function checkStrategyInput(entry, { strategy, operation, values }) { } } -export default async function checkCriteriaLocal(key, input, snapshot) { +export default async function checkCriteriaLocal(snapshot, switcher) { if (!snapshot) { throw new Error('Snapshot not loaded. Try to use \'Client.loadSnapshot()\''); } const { data } = snapshot; - return resolveCriteria(key, input, data); + return resolveCriteria(data, switcher); } class CriteriaFailed extends Error { diff --git a/src/switcher.js b/src/switcher.js index ca64e5d..b5c5f7b 100644 --- a/src/switcher.js +++ b/src/switcher.js @@ -1,31 +1,24 @@ import Bypasser from './lib/bypasser/index.js'; import ExecutionLogger from './lib/utils/executionLogger.js'; import checkCriteriaLocal from './lib/resolver.js'; -import { StrategiesType } from './lib/snapshot.js'; import * as remote from './lib/remote.js'; import * as util from './lib/utils/index.js'; import { Auth } from './lib/remoteAuth.js'; import { GlobalAuth } from './lib/globals/globalAuth.js'; import { GlobalOptions } from './lib/globals/globalOptions.js'; import { GlobalSnapshot } from './lib/globals/globalSnapshot.js'; +import { SwitcherRequest } from './switcherRequest.js'; -export class Switcher { - #delay = 0; - #nextRun = 0; - #input; - #key = ''; - #defaultResult; - #forceRemote = false; - #showDetail = false; - +export class Switcher extends SwitcherRequest { constructor(key) { + super(); this.#validateArgs(key); } async prepare(key) { this.#validateArgs(key); - if (!GlobalOptions.local || this.#forceRemote) { + if (!GlobalOptions.local || this._forceRemote) { await Auth.auth(); } } @@ -35,7 +28,7 @@ export class Switcher { Auth.isValid(); - if (!this.#key) { + if (!this._key) { errors.push('Missing key field'); } @@ -54,15 +47,15 @@ export class Switcher { this.#validateArgs(key); // verify if query from Bypasser - const bypassKey = Bypasser.searchBypassed(this.#key); + const bypassKey = Bypasser.searchBypassed(this._key); if (bypassKey) { - const response = bypassKey.getResponse(util.get(this.#input, [])); - return this.#showDetail ? response : response.result; + const response = bypassKey.getResponse(util.get(this._input, [])); + return this._showDetail ? response : response.result; } try { // verify if query from local snapshot - if (GlobalOptions.local && !this.#forceRemote) { + if (GlobalOptions.local && !this._forceRemote) { return await this._executeLocalCriteria(); } @@ -87,102 +80,36 @@ export class Switcher { return result; } - throttle(delay) { - this.#delay = delay; - - if (delay > 0) { - GlobalOptions.updateOptions({ logger: true }); - } - - return this; - } - - remote(forceRemote = true) { - if (!GlobalOptions.local) { - throw new Error('Local mode is not enabled'); - } - - this.#forceRemote = forceRemote; - return this; - } - - detail(showDetail = true) { - this.#showDetail = showDetail; - return this; - } - - defaultResult(defaultResult) { - this.#defaultResult = defaultResult; - return this; - } - - check(startegyType, input) { - if (!this.#input) { - this.#input = []; - } - - this.#input.push([startegyType, input]); - return this; - } - - checkValue(input) { - return this.check(StrategiesType.VALUE, input); - } - - checkNumeric(input) { - return this.check(StrategiesType.NUMERIC, input); - } - - checkNetwork(input) { - return this.check(StrategiesType.NETWORK, input); - } - - checkDate(input) { - return this.check(StrategiesType.DATE, input); - } - - checkTime(input) { - return this.check(StrategiesType.TIME, input); - } - - checkRegex(input) { - return this.check(StrategiesType.REGEX, input); - } - - checkPayload(input) { - return this.check(StrategiesType.PAYLOAD, input); - } - async _executeRemoteCriteria() { let responseCriteria; if (this.#useSync()) { try { responseCriteria = await remote.checkCriteria( - this.#key, - this.#input, - this.#showDetail + this._key, + this._input, + this._showDetail ); } catch (err) { responseCriteria = this.#getDefaultResultOrThrow(err); } - if (GlobalOptions.logger && this.#key) { - ExecutionLogger.add(responseCriteria, this.#key, this.#input); + if (GlobalOptions.logger && this._key) { + ExecutionLogger.add(responseCriteria, this._key, this._input); } } else { responseCriteria = this._executeAsyncRemoteCriteria(); } - return this.#showDetail ? responseCriteria : responseCriteria.result; + return this._showDetail ? responseCriteria : responseCriteria.result; } _executeAsyncRemoteCriteria() { - if (this.#nextRun < Date.now()) { - this.#nextRun = Date.now() + this.#delay; + if (this._nextRun < Date.now()) { + this._nextRun = Date.now() + this._delay; if (Auth.isTokenExpired()) { - this.prepare(this.#key) + this.prepare(this._key) .then(() => this.#executeAsyncCheckCriteria()) .catch(err => this.#notifyError(err)); } else { @@ -190,13 +117,13 @@ export class Switcher { } } - const executionLog = ExecutionLogger.getExecution(this.#key, this.#input); + const executionLog = ExecutionLogger.getExecution(this._key, this._input); return executionLog.response; } #executeAsyncCheckCriteria() { - remote.checkCriteria(this.#key, this.#input, this.#showDetail) - .then(response => ExecutionLogger.add(response, this.#key, this.#input)) + remote.checkCriteria(this._key, this._input, this._showDetail) + .then(response => ExecutionLogger.add(response, this._key, this._input)) .catch(err => this.#notifyError(err)); } @@ -211,27 +138,23 @@ export class Switcher { Auth.checkHealth(); if (Auth.isTokenExpired()) { - await this.prepare(this.#key); + await this.prepare(this._key); } } async _executeLocalCriteria() { let response; try { - response = await checkCriteriaLocal( - util.get(this.#key, ''), - util.get(this.#input, []), - GlobalSnapshot.snapshot - ); + response = await checkCriteriaLocal(GlobalSnapshot.snapshot, this); } catch (err) { response = this.#getDefaultResultOrThrow(err); } if (GlobalOptions.logger) { - ExecutionLogger.add(response, this.#key, this.#input); + ExecutionLogger.add(response, this._key, this._input); } - if (this.#showDetail) { + if (this._showDetail) { return response; } @@ -240,21 +163,21 @@ export class Switcher { #validateArgs(key) { if (key) { - this.#key = key; + this._key = key; } } #useSync() { - return this.#delay == 0 || !ExecutionLogger.getExecution(this.#key, this.#input); + return this._delay == 0 || !ExecutionLogger.getExecution(this._key, this._input); } #getDefaultResultOrThrow(err) { - if (this.#defaultResult === undefined) { + if (this._defaultResult === undefined) { throw err; } const response = { - result: this.#defaultResult, + result: this._defaultResult, reason: 'Default result' }; @@ -262,12 +185,4 @@ export class Switcher { return response; } - get key() { - return this.#key; - } - - get input() { - return this.#input; - } - } \ No newline at end of file diff --git a/src/switcherBuilder.js b/src/switcherBuilder.js new file mode 100644 index 0000000..640f304 --- /dev/null +++ b/src/switcherBuilder.js @@ -0,0 +1,82 @@ +import { GlobalOptions } from './lib/globals/globalOptions.js'; +import { StrategiesType } from './lib/snapshot.js'; + +export class SwitcherBuilder { + _delay = 0; + _nextRun = 0; + _input; + _key = ''; + _defaultResult; + _forceRemote = false; + _showDetail = false; + + constructor(key) { + this._key = key; + } + + throttle(delay) { + this._delay = delay; + + if (delay > 0) { + GlobalOptions.updateOptions({ logger: true }); + } + + return this; + } + + remote(forceRemote = true) { + if (!GlobalOptions.local) { + throw new Error('Local mode is not enabled'); + } + + this._forceRemote = forceRemote; + return this; + } + + detail(showDetail = true) { + this._showDetail = showDetail; + return this; + } + + defaultResult(defaultResult) { + this._defaultResult = defaultResult; + return this; + } + + check(startegyType, input) { + if (!this._input) { + this._input = []; + } + + this._input.push([startegyType, input]); + return this; + } + + checkValue(input) { + return this.check(StrategiesType.VALUE, input); + } + + checkNumeric(input) { + return this.check(StrategiesType.NUMERIC, input); + } + + checkNetwork(input) { + return this.check(StrategiesType.NETWORK, input); + } + + checkDate(input) { + return this.check(StrategiesType.DATE, input); + } + + checkTime(input) { + return this.check(StrategiesType.TIME, input); + } + + checkRegex(input) { + return this.check(StrategiesType.REGEX, input); + } + + checkPayload(input) { + return this.check(StrategiesType.PAYLOAD, input); + } +} \ No newline at end of file diff --git a/src/switcherRequest.js b/src/switcherRequest.js new file mode 100644 index 0000000..75d89e2 --- /dev/null +++ b/src/switcherRequest.js @@ -0,0 +1,17 @@ +import { SwitcherBuilder } from './switcherBuilder.js'; + +export class SwitcherRequest extends SwitcherBuilder { + /** + * Return switcher key + */ + get key() { + return this._key; + } + + /** + * Return switcher current strategy input + */ + get input() { + return this._input; + } +} \ No newline at end of file