@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +14 -1
- package/cjs/evaluator/condition/engineUtils.js +2 -2
- package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
- package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
- package/cjs/evaluator/index.js +67 -42
- package/cjs/evaluator/matchers/whitelist.js +1 -1
- package/cjs/integrations/pluggable.js +1 -1
- package/cjs/listeners/browser.js +4 -3
- package/cjs/listeners/node.js +4 -4
- package/cjs/logger/constants.js +14 -20
- package/cjs/logger/index.js +1 -1
- package/cjs/logger/messages/debug.js +6 -7
- package/cjs/logger/messages/error.js +4 -4
- package/cjs/logger/messages/info.js +2 -4
- package/cjs/logger/messages/warn.js +9 -9
- package/cjs/platform/browser.js +15 -0
- package/cjs/platform/getEventSource/browser.js +8 -0
- package/cjs/platform/getEventSource/eventsource.js +480 -0
- package/cjs/platform/getEventSource/node.js +26 -0
- package/cjs/platform/getFetch/browser.js +9 -0
- package/cjs/platform/getFetch/node.js +27 -0
- package/cjs/platform/getOptions/node.js +25 -0
- package/cjs/platform/node.js +17 -0
- package/cjs/readiness/constants.js +2 -1
- package/cjs/sdkClient/client.js +9 -35
- package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
- package/cjs/sdkClient/clientInputValidation.js +38 -81
- package/cjs/sdkClient/identity.js +1 -1
- package/cjs/sdkClient/sdkClient.js +4 -49
- package/cjs/sdkClient/sdkLifecycle.js +70 -0
- package/cjs/sdkClient/trackMethod.js +56 -0
- package/cjs/sdkFactory/index.js +8 -45
- package/cjs/sdkManager/index.js +3 -3
- package/cjs/services/splitApi.js +18 -13
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/AbstractSplitsCacheAsync.js +1 -1
- package/cjs/storages/AbstractSplitsCacheSync.js +1 -1
- package/cjs/storages/KeyBuilder.js +12 -12
- package/cjs/storages/KeyBuilderCS.js +13 -13
- package/cjs/storages/KeyBuilderSS.js +15 -15
- package/cjs/storages/getRolloutPlan.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
- package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +8 -8
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +6 -6
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
- package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
- package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +4 -4
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
- package/cjs/storages/pluggable/index.js +3 -3
- package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
- package/cjs/storages/setRolloutPlan.js +1 -1
- package/cjs/storages/utils.js +6 -6
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/fetchers/splitChangesFetcher.js +23 -14
- package/cjs/sync/polling/pollingManagerCS.js +11 -11
- package/cjs/sync/polling/pollingManagerSS.js +13 -13
- package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
- package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/cjs/sync/streaming/parseUtils.js +12 -12
- package/cjs/sync/streaming/pushManager.js +2 -2
- package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
- package/cjs/sync/submitters/submitter.js +1 -1
- package/cjs/sync/syncManagerOnline.js +5 -2
- package/cjs/trackers/eventTracker.js +10 -12
- package/cjs/trackers/impressionObserver/buildKey.js +1 -1
- package/cjs/trackers/impressionsTracker.js +37 -20
- package/cjs/trackers/uniqueKeysTracker.js +1 -1
- package/cjs/utils/EventEmitter.js +391 -0
- package/cjs/utils/filter/bloomFilter.js +37 -0
- package/cjs/utils/inputValidation/apiKey.js +1 -1
- package/cjs/utils/inputValidation/attribute.js +2 -2
- package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
- package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
- package/cjs/utils/inputValidation/definitions.js +25 -0
- package/cjs/utils/inputValidation/eventProperties.js +1 -1
- package/cjs/utils/inputValidation/index.js +7 -7
- package/cjs/utils/inputValidation/isOperational.js +4 -4
- package/cjs/utils/inputValidation/target.js +22 -0
- package/cjs/utils/labels/index.js +3 -3
- package/cjs/utils/lang/index.js +1 -1
- package/cjs/utils/promise/timeout.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +4 -4
- package/cjs/utils/settingsValidation/url.js +5 -5
- package/esm/evaluator/condition/engineUtils.js +2 -2
- package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
- package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
- package/esm/evaluator/index.js +66 -42
- package/esm/evaluator/matchers/whitelist.js +1 -1
- package/esm/integrations/pluggable.js +1 -1
- package/esm/listeners/browser.js +4 -3
- package/esm/listeners/node.js +4 -4
- package/esm/logger/constants.js +11 -17
- package/esm/logger/index.js +1 -1
- package/esm/logger/messages/debug.js +5 -6
- package/esm/logger/messages/error.js +3 -3
- package/esm/logger/messages/info.js +1 -3
- package/esm/logger/messages/warn.js +8 -8
- package/esm/platform/browser.js +12 -0
- package/esm/platform/getEventSource/browser.js +4 -0
- package/esm/platform/getEventSource/eventsource.js +480 -0
- package/esm/platform/getEventSource/node.js +20 -0
- package/esm/platform/getFetch/browser.js +5 -0
- package/esm/platform/getFetch/node.js +22 -0
- package/esm/platform/getOptions/node.js +20 -0
- package/esm/platform/node.js +14 -0
- package/esm/readiness/constants.js +1 -0
- package/esm/sdkClient/client.js +10 -37
- package/esm/sdkClient/clientAttributesDecoration.js +3 -3
- package/esm/sdkClient/clientInputValidation.js +40 -83
- package/esm/sdkClient/identity.js +1 -1
- package/esm/sdkClient/sdkClient.js +4 -49
- package/esm/sdkClient/sdkLifecycle.js +66 -0
- package/esm/sdkClient/trackMethod.js +52 -0
- package/esm/sdkFactory/index.js +8 -45
- package/esm/sdkManager/index.js +4 -4
- package/esm/services/splitApi.js +18 -13
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +1 -1
- package/esm/storages/AbstractSplitsCacheSync.js +1 -1
- package/esm/storages/KeyBuilder.js +12 -12
- package/esm/storages/KeyBuilderCS.js +12 -12
- package/esm/storages/KeyBuilderSS.js +14 -14
- package/esm/storages/getRolloutPlan.js +1 -1
- package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +1 -1
- package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +1 -1
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +2 -2
- package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
- package/esm/storages/inRedis/RedisAdapter.js +7 -7
- package/esm/storages/inRedis/SplitsCacheInRedis.js +4 -4
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
- package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
- package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
- package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
- package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
- package/esm/storages/pluggable/SplitsCachePluggable.js +2 -2
- package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
- package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/storages/pluggable/wrapperAdapter.js +1 -1
- package/esm/storages/setRolloutPlan.js +1 -1
- package/esm/storages/utils.js +6 -6
- package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
- package/esm/sync/polling/fetchers/splitChangesFetcher.js +24 -15
- package/esm/sync/polling/pollingManagerCS.js +11 -11
- package/esm/sync/polling/pollingManagerSS.js +13 -13
- package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
- package/esm/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +67 -59
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
- package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +4 -4
- package/esm/sync/streaming/parseUtils.js +10 -10
- package/esm/sync/streaming/pushManager.js +3 -3
- package/esm/sync/submitters/impressionsSubmitter.js +6 -6
- package/esm/sync/submitters/submitter.js +1 -1
- package/esm/sync/syncManagerOnline.js +5 -2
- package/esm/trackers/eventTracker.js +10 -12
- package/esm/trackers/impressionObserver/buildKey.js +1 -1
- package/esm/trackers/impressionsTracker.js +38 -21
- package/esm/trackers/uniqueKeysTracker.js +1 -1
- package/esm/utils/EventEmitter.js +387 -0
- package/esm/utils/filter/bloomFilter.js +33 -0
- package/esm/utils/inputValidation/apiKey.js +1 -1
- package/esm/utils/inputValidation/attribute.js +2 -2
- package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
- package/esm/utils/inputValidation/definitionExistence.js +15 -0
- package/esm/utils/inputValidation/definitions.js +21 -0
- package/esm/utils/inputValidation/index.js +3 -3
- package/esm/utils/inputValidation/isOperational.js +4 -4
- package/esm/utils/inputValidation/target.js +18 -0
- package/esm/utils/labels/index.js +2 -2
- package/esm/utils/promise/timeout.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +4 -4
- package/esm/utils/settingsValidation/url.js +5 -5
- package/package.json +15 -6
- package/src/dtos/types.ts +65 -70
- package/src/evaluator/Engine.ts +4 -4
- package/src/evaluator/combiners/and.ts +3 -3
- package/src/evaluator/combiners/ifelseif.ts +2 -2
- package/src/evaluator/condition/engineUtils.ts +2 -2
- package/src/evaluator/condition/index.ts +3 -3
- package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
- package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
- package/src/evaluator/index.ts +80 -45
- package/src/evaluator/matchers/dependency.ts +2 -2
- package/src/evaluator/matchers/matcherTypes.ts +2 -2
- package/src/evaluator/matchers/prerequisites.ts +4 -4
- package/src/evaluator/matchers/rbsegment.ts +2 -2
- package/src/evaluator/matchers/whitelist.ts +2 -2
- package/src/evaluator/matchersTransform/index.ts +2 -2
- package/src/evaluator/matchersTransform/whitelist.ts +2 -2
- package/src/evaluator/parser/index.ts +4 -4
- package/src/evaluator/treatments/index.ts +2 -2
- package/src/evaluator/types.ts +6 -6
- package/src/evaluator/value/index.ts +1 -1
- package/src/integrations/pluggable.ts +1 -1
- package/src/listeners/browser.ts +11 -8
- package/src/listeners/node.ts +2 -5
- package/src/logger/constants.ts +11 -17
- package/src/logger/messages/debug.ts +5 -6
- package/src/logger/messages/error.ts +3 -3
- package/src/logger/messages/info.ts +1 -3
- package/src/logger/messages/warn.ts +8 -8
- package/src/platform/browser.ts +14 -0
- package/src/platform/getEventSource/browser.ts +4 -0
- package/src/platform/getEventSource/eventsource.js +519 -0
- package/src/platform/getEventSource/node.ts +23 -0
- package/src/platform/getFetch/browser.ts +5 -0
- package/src/platform/getFetch/node.ts +27 -0
- package/src/platform/getOptions/node.ts +24 -0
- package/src/platform/node.ts +16 -0
- package/src/readiness/constants.ts +1 -0
- package/src/sdkClient/client.ts +11 -41
- package/src/sdkClient/clientInputValidation.ts +44 -84
- package/src/sdkClient/sdkClient.ts +5 -54
- package/src/sdkClient/sdkLifecycle.ts +78 -0
- package/src/sdkClient/trackMethod.ts +59 -0
- package/src/sdkFactory/index.ts +10 -54
- package/src/sdkFactory/types.ts +19 -16
- package/src/sdkManager/index.ts +9 -9
- package/src/services/splitApi.ts +6 -0
- package/src/services/types.ts +3 -2
- package/src/storages/AbstractSplitsCacheAsync.ts +7 -7
- package/src/storages/AbstractSplitsCacheSync.ts +10 -10
- package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +2 -2
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -6
- package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +2 -2
- package/src/storages/inMemory/SplitsCacheInMemory.ts +5 -5
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +2 -2
- package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
- package/src/storages/inRedis/SplitsCacheInRedis.ts +9 -9
- package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
- package/src/storages/pluggable/SplitsCachePluggable.ts +9 -9
- package/src/storages/types.ts +21 -16
- package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
- package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
- package/src/sync/offline/splitsParser/types.ts +6 -3
- package/src/sync/offline/syncManagerOffline.ts +2 -2
- package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +6 -6
- package/src/sync/polling/fetchers/splitChangesFetcher.ts +57 -22
- package/src/sync/polling/fetchers/types.ts +5 -3
- package/src/sync/polling/pollingManagerCS.ts +12 -10
- package/src/sync/polling/pollingManagerSS.ts +15 -13
- package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +10 -11
- package/src/sync/polling/types.ts +3 -3
- package/src/sync/polling/updaters/{splitChangesUpdater.ts → definitionChangesUpdater.ts} +77 -68
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +6 -6
- package/src/sync/streaming/parseUtils.ts +12 -12
- package/src/sync/streaming/pushManager.ts +3 -3
- package/src/sync/submitters/impressionsSubmitter.ts +9 -9
- package/src/sync/submitters/types.ts +3 -0
- package/src/sync/syncManagerOnline.ts +6 -2
- package/src/trackers/eventTracker.ts +7 -10
- package/src/trackers/impressionsTracker.ts +42 -26
- package/src/trackers/types.ts +3 -1
- package/src/utils/EventEmitter.js +444 -0
- package/src/utils/filter/bloomFilter.ts +38 -0
- package/src/utils/inputValidation/definition.ts +27 -0
- package/src/utils/inputValidation/definitionExistence.ts +19 -0
- package/src/utils/inputValidation/definitions.ts +21 -0
- package/src/utils/inputValidation/index.ts +3 -3
- package/src/utils/inputValidation/isOperational.ts +4 -4
- package/src/utils/inputValidation/target.ts +21 -0
- package/src/utils/labels/index.ts +2 -2
- package/src/utils/settingsValidation/splitFilters.ts +3 -3
- package/types/splitio.d.ts +202 -9
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
- package/cjs/utils/inputValidation/splits.js +0 -25
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
- package/esm/utils/inputValidation/splitExistence.js +0 -15
- package/esm/utils/inputValidation/splits.js +0 -21
- package/src/utils/inputValidation/split.ts +0 -27
- package/src/utils/inputValidation/splitExistence.ts +0 -19
- package/src/utils/inputValidation/splits.ts +0 -21
|
@@ -2,10 +2,8 @@ import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '
|
|
|
2
2
|
import { ILogger } from '../../../logger/types';
|
|
3
3
|
import { isObject, isString } from '../../../utils/lang';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Treatment = 'Invalid treatment (max 100 chars and must match pattern)',
|
|
8
|
-
}
|
|
5
|
+
const FLAG_NAME_DISCARD_REASON = 'Invalid flag name (max 100 chars, no spaces)';
|
|
6
|
+
const TREATMENT_DISCARD_REASON = 'Invalid treatment (max 100 chars and must match pattern)';
|
|
9
7
|
|
|
10
8
|
const TREATMENT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
|
|
11
9
|
|
|
@@ -25,7 +23,7 @@ export function isValidTreatment(t?: Treatment | TreatmentWithConfig): boolean {
|
|
|
25
23
|
function sanitizeGlobal(logger: ILogger, treatment?: Treatment | TreatmentWithConfig): Treatment | TreatmentWithConfig | undefined {
|
|
26
24
|
if (treatment === undefined) return undefined;
|
|
27
25
|
if (!isValidTreatment(treatment)) {
|
|
28
|
-
logger.error(`Fallback treatments - Discarded fallback: ${
|
|
26
|
+
logger.error(`Fallback treatments - Discarded fallback: ${TREATMENT_DISCARD_REASON}`);
|
|
29
27
|
return undefined;
|
|
30
28
|
}
|
|
31
29
|
return treatment;
|
|
@@ -43,12 +41,12 @@ function sanitizeByFlag(
|
|
|
43
41
|
const t = byFlagFallbacks![flag];
|
|
44
42
|
|
|
45
43
|
if (!isValidFlagName(flag)) {
|
|
46
|
-
logger.error(`Fallback treatments - Discarded flag '${flag}': ${
|
|
44
|
+
logger.error(`Fallback treatments - Discarded flag '${flag}': ${FLAG_NAME_DISCARD_REASON}`);
|
|
47
45
|
return;
|
|
48
46
|
}
|
|
49
47
|
|
|
50
48
|
if (!isValidTreatment(t)) {
|
|
51
|
-
logger.error(`Fallback treatments - Discarded treatment for flag '${flag}': ${
|
|
49
|
+
logger.error(`Fallback treatments - Discarded treatment for flag '${flag}': ${TREATMENT_DISCARD_REASON}`);
|
|
52
50
|
return;
|
|
53
51
|
}
|
|
54
52
|
|
|
@@ -1,50 +1,36 @@
|
|
|
1
|
-
import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '../../../types/splitio';
|
|
2
1
|
import { CONTROL } from '../../utils/constants';
|
|
3
2
|
import { isString } from '../../utils/lang';
|
|
3
|
+
import SplitIO from '../../../types/splitio';
|
|
4
4
|
|
|
5
|
-
export type
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
export type IFallbackCalculator = (definitionName: string, label?: string) => {
|
|
6
|
+
treatment: string;
|
|
7
|
+
config: string | null | SplitIO.JsonObject;
|
|
8
|
+
label: string
|
|
9
|
+
};
|
|
8
10
|
|
|
9
11
|
export const FALLBACK_PREFIX = 'fallback - ';
|
|
10
12
|
|
|
11
|
-
export
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
config: null,
|
|
31
|
-
label,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
private copyWithLabel(fallback: Treatment | TreatmentWithConfig, label: string): TreatmentWithConfig & { label: string } {
|
|
36
|
-
if (isString(fallback)) {
|
|
37
|
-
return {
|
|
38
|
-
treatment: fallback,
|
|
13
|
+
export function FallbackTreatmentsCalculator(fallbacks: SplitIO.FallbackTreatmentConfiguration = {}): IFallbackCalculator {
|
|
14
|
+
|
|
15
|
+
return (flagName: string, label = '') => {
|
|
16
|
+
const fallback = fallbacks.byFlag?.[flagName] || fallbacks.global;
|
|
17
|
+
|
|
18
|
+
return fallback ?
|
|
19
|
+
isString(fallback) ?
|
|
20
|
+
{
|
|
21
|
+
treatment: fallback,
|
|
22
|
+
config: null,
|
|
23
|
+
label: `${FALLBACK_PREFIX}${label}`,
|
|
24
|
+
} :
|
|
25
|
+
{
|
|
26
|
+
treatment: fallback.treatment,
|
|
27
|
+
config: fallback.config,
|
|
28
|
+
label: `${FALLBACK_PREFIX}${label}`,
|
|
29
|
+
} :
|
|
30
|
+
{
|
|
31
|
+
treatment: CONTROL,
|
|
39
32
|
config: null,
|
|
40
|
-
label
|
|
33
|
+
label,
|
|
41
34
|
};
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return {
|
|
45
|
-
treatment: fallback.treatment,
|
|
46
|
-
config: fallback.config,
|
|
47
|
-
label: `${FALLBACK_PREFIX}${label}`,
|
|
48
|
-
};
|
|
49
|
-
}
|
|
35
|
+
};
|
|
50
36
|
}
|
package/src/evaluator/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { engineParser } from './Engine';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
|
-
import { EXCEPTION,
|
|
3
|
+
import { EXCEPTION, NO_CONDITION_MATCH, DEFINITION_NOT_FOUND } from '../utils/labels';
|
|
4
4
|
import { CONTROL } from '../utils/constants';
|
|
5
|
-
import {
|
|
5
|
+
import { IDefinition, MaybeThenable } from '../dtos/types';
|
|
6
6
|
import { IStorageAsync, IStorageSync } from '../storages/types';
|
|
7
7
|
import { IEvaluationResult } from './types';
|
|
8
8
|
import SplitIO from '../../types/splitio';
|
|
@@ -10,16 +10,22 @@ import { ILogger } from '../logger/types';
|
|
|
10
10
|
import { returnSetsUnion, setToArray } from '../utils/lang/sets';
|
|
11
11
|
import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
|
|
12
12
|
|
|
13
|
-
const
|
|
13
|
+
const EVALUATION_EXCEPTION = {
|
|
14
14
|
treatment: CONTROL,
|
|
15
15
|
label: EXCEPTION,
|
|
16
16
|
config: null
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
const EVALUATION_DEFINITION_NOT_FOUND = {
|
|
20
|
+
treatment: CONTROL,
|
|
21
|
+
label: DEFINITION_NOT_FOUND,
|
|
22
|
+
config: null
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
function treatmentsException(definitionNames: string[]) {
|
|
20
26
|
const evaluations: Record<string, IEvaluationResult> = {};
|
|
21
|
-
|
|
22
|
-
evaluations[
|
|
27
|
+
definitionNames.forEach(definitionName => {
|
|
28
|
+
evaluations[definitionName] = EVALUATION_EXCEPTION;
|
|
23
29
|
});
|
|
24
30
|
return evaluations;
|
|
25
31
|
}
|
|
@@ -27,39 +33,39 @@ function treatmentsException(splitNames: string[]) {
|
|
|
27
33
|
export function evaluateFeature(
|
|
28
34
|
log: ILogger,
|
|
29
35
|
key: SplitIO.SplitKey,
|
|
30
|
-
|
|
36
|
+
definitionName: string,
|
|
31
37
|
attributes: SplitIO.Attributes | undefined,
|
|
32
38
|
storage: IStorageSync | IStorageAsync,
|
|
33
39
|
options?: SplitIO.EvaluationOptions
|
|
34
40
|
): MaybeThenable<IEvaluationResult> {
|
|
35
|
-
let
|
|
41
|
+
let definition;
|
|
36
42
|
|
|
37
43
|
try {
|
|
38
|
-
|
|
44
|
+
definition = storage.splits.getSplit(definitionName);
|
|
39
45
|
} catch (e) {
|
|
40
46
|
// Exception on sync `getSplit` storage. Not possible ATM with InMemory and InLocal storages.
|
|
41
|
-
return
|
|
47
|
+
return EVALUATION_EXCEPTION;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
if (thenable(
|
|
45
|
-
return
|
|
50
|
+
if (thenable(definition)) {
|
|
51
|
+
return definition.then((definition) => getEvaluation(
|
|
46
52
|
log,
|
|
47
53
|
key,
|
|
48
|
-
|
|
54
|
+
definition,
|
|
49
55
|
attributes,
|
|
50
56
|
storage,
|
|
51
57
|
options,
|
|
52
58
|
)).catch(
|
|
53
59
|
// Exception on async `getSplit` storage. For example, when the storage is redis or
|
|
54
60
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
55
|
-
() =>
|
|
61
|
+
() => EVALUATION_EXCEPTION
|
|
56
62
|
);
|
|
57
63
|
}
|
|
58
64
|
|
|
59
65
|
return getEvaluation(
|
|
60
66
|
log,
|
|
61
67
|
key,
|
|
62
|
-
|
|
68
|
+
definition,
|
|
63
69
|
attributes,
|
|
64
70
|
storage,
|
|
65
71
|
options,
|
|
@@ -69,28 +75,28 @@ export function evaluateFeature(
|
|
|
69
75
|
export function evaluateFeatures(
|
|
70
76
|
log: ILogger,
|
|
71
77
|
key: SplitIO.SplitKey,
|
|
72
|
-
|
|
78
|
+
definitionNames: string[],
|
|
73
79
|
attributes: SplitIO.Attributes | undefined,
|
|
74
80
|
storage: IStorageSync | IStorageAsync,
|
|
75
81
|
options?: SplitIO.EvaluationOptions,
|
|
76
82
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
77
|
-
let
|
|
83
|
+
let definitions;
|
|
78
84
|
|
|
79
85
|
try {
|
|
80
|
-
|
|
86
|
+
definitions = storage.splits.getSplits(definitionNames);
|
|
81
87
|
} catch (e) {
|
|
82
88
|
// Exception on sync `getSplits` storage. Not possible ATM with InMemory and InLocal storages.
|
|
83
|
-
return treatmentsException(
|
|
89
|
+
return treatmentsException(definitionNames);
|
|
84
90
|
}
|
|
85
91
|
|
|
86
|
-
return thenable(
|
|
87
|
-
|
|
92
|
+
return thenable(definitions) ?
|
|
93
|
+
definitions.then(definitions => getEvaluations(log, key, definitionNames, definitions, attributes, storage, options))
|
|
88
94
|
.catch(() => {
|
|
89
95
|
// Exception on async `getSplits` storage. For example, when the storage is redis or
|
|
90
96
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
91
|
-
return treatmentsException(
|
|
97
|
+
return treatmentsException(definitionNames);
|
|
92
98
|
}) :
|
|
93
|
-
getEvaluations(log, key,
|
|
99
|
+
getEvaluations(log, key, definitionNames, definitions, attributes, storage, options);
|
|
94
100
|
}
|
|
95
101
|
|
|
96
102
|
export function evaluateFeaturesByFlagSets(
|
|
@@ -140,70 +146,99 @@ export function evaluateFeaturesByFlagSets(
|
|
|
140
146
|
function getEvaluation(
|
|
141
147
|
log: ILogger,
|
|
142
148
|
key: SplitIO.SplitKey,
|
|
143
|
-
|
|
149
|
+
definition: IDefinition | null,
|
|
144
150
|
attributes: SplitIO.Attributes | undefined,
|
|
145
151
|
storage: IStorageSync | IStorageAsync,
|
|
146
152
|
options?: SplitIO.EvaluationOptions,
|
|
147
153
|
): MaybeThenable<IEvaluationResult> {
|
|
148
|
-
let evaluation: MaybeThenable<IEvaluationResult> = {
|
|
149
|
-
treatment: CONTROL,
|
|
150
|
-
label: SPLIT_NOT_FOUND,
|
|
151
|
-
config: null
|
|
152
|
-
};
|
|
153
154
|
|
|
154
|
-
if (
|
|
155
|
-
const split = engineParser(log,
|
|
156
|
-
evaluation = split.getTreatment(key, attributes, evaluateFeature);
|
|
155
|
+
if (definition) {
|
|
156
|
+
const split = engineParser(log, definition, storage);
|
|
157
|
+
const evaluation = split.getTreatment(key, attributes, evaluateFeature);
|
|
157
158
|
|
|
158
159
|
// If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
|
|
159
160
|
if (thenable(evaluation)) {
|
|
160
161
|
return evaluation.then(result => {
|
|
161
|
-
result.changeNumber =
|
|
162
|
-
result.config =
|
|
162
|
+
result.changeNumber = definition.changeNumber;
|
|
163
|
+
result.config = definition.configurations && definition.configurations[result.treatment] || null;
|
|
163
164
|
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
164
|
-
result.impressionsDisabled = options?.impressionsDisabled ||
|
|
165
|
+
result.impressionsDisabled = options?.impressionsDisabled || definition.impressionsDisabled;
|
|
165
166
|
|
|
166
167
|
return result;
|
|
167
168
|
});
|
|
168
169
|
} else {
|
|
169
|
-
evaluation.changeNumber =
|
|
170
|
-
evaluation.config =
|
|
170
|
+
evaluation.changeNumber = definition.changeNumber;
|
|
171
|
+
evaluation.config = definition.configurations && definition.configurations[evaluation.treatment] || null;
|
|
171
172
|
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
172
|
-
evaluation.impressionsDisabled = options?.impressionsDisabled ||
|
|
173
|
+
evaluation.impressionsDisabled = options?.impressionsDisabled || definition.impressionsDisabled;
|
|
173
174
|
}
|
|
175
|
+
|
|
176
|
+
return evaluation;
|
|
174
177
|
}
|
|
175
178
|
|
|
176
|
-
return
|
|
179
|
+
return EVALUATION_DEFINITION_NOT_FOUND;
|
|
177
180
|
}
|
|
178
181
|
|
|
179
182
|
function getEvaluations(
|
|
180
183
|
log: ILogger,
|
|
181
184
|
key: SplitIO.SplitKey,
|
|
182
|
-
|
|
183
|
-
splits: Record<string,
|
|
185
|
+
definitionNames: string[],
|
|
186
|
+
splits: Record<string, IDefinition | null>,
|
|
184
187
|
attributes: SplitIO.Attributes | undefined,
|
|
185
188
|
storage: IStorageSync | IStorageAsync,
|
|
186
189
|
options?: SplitIO.EvaluationOptions,
|
|
187
190
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
188
191
|
const result: Record<string, IEvaluationResult> = {};
|
|
189
192
|
const thenables: Promise<void>[] = [];
|
|
190
|
-
|
|
193
|
+
definitionNames.forEach(definitionName => {
|
|
191
194
|
const evaluation = getEvaluation(
|
|
192
195
|
log,
|
|
193
196
|
key,
|
|
194
|
-
splits[
|
|
197
|
+
splits[definitionName],
|
|
195
198
|
attributes,
|
|
196
199
|
storage,
|
|
197
200
|
options
|
|
198
201
|
);
|
|
199
202
|
if (thenable(evaluation)) {
|
|
200
203
|
thenables.push(evaluation.then(res => {
|
|
201
|
-
result[
|
|
204
|
+
result[definitionName] = res;
|
|
202
205
|
}));
|
|
203
206
|
} else {
|
|
204
|
-
result[
|
|
207
|
+
result[definitionName] = evaluation;
|
|
205
208
|
}
|
|
206
209
|
});
|
|
207
210
|
|
|
208
211
|
return thenables.length > 0 ? Promise.all(thenables).then(() => result) : result;
|
|
209
212
|
}
|
|
213
|
+
|
|
214
|
+
export function evaluateDefaultTreatment(
|
|
215
|
+
definitionName: string,
|
|
216
|
+
storage: IStorageSync | IStorageAsync,
|
|
217
|
+
): MaybeThenable<IEvaluationResult> {
|
|
218
|
+
let definition;
|
|
219
|
+
|
|
220
|
+
try {
|
|
221
|
+
definition = storage.splits.getSplit(definitionName);
|
|
222
|
+
} catch (e) {
|
|
223
|
+
return EVALUATION_EXCEPTION;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return thenable(definition) ?
|
|
227
|
+
definition.then(getDefaultTreatment).catch(() => EVALUATION_EXCEPTION) :
|
|
228
|
+
getDefaultTreatment(definition);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function getDefaultTreatment(
|
|
232
|
+
definition: IDefinition | null,
|
|
233
|
+
): MaybeThenable<IEvaluationResult> {
|
|
234
|
+
if (definition) {
|
|
235
|
+
return {
|
|
236
|
+
treatment: definition.defaultTreatment,
|
|
237
|
+
label: NO_CONDITION_MATCH, // "default rule"
|
|
238
|
+
config: definition.configurations && definition.configurations[definition.defaultTreatment] || null,
|
|
239
|
+
changeNumber: definition.changeNumber
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return EVALUATION_DEFINITION_NOT_FOUND;
|
|
244
|
+
}
|
|
@@ -2,7 +2,7 @@ import { IDependencyMatcherData, MaybeThenable } from '../../dtos/types';
|
|
|
2
2
|
import { IStorageAsync, IStorageSync } from '../../storages/types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
import { thenable } from '../../utils/promise/thenable';
|
|
5
|
-
import { IDependencyMatcherValue, IEvaluation,
|
|
5
|
+
import { IDependencyMatcherValue, IEvaluation, IDefinitionEvaluator } from '../types';
|
|
6
6
|
import { ENGINE_MATCHER_DEPENDENCY, ENGINE_MATCHER_DEPENDENCY_PRE } from '../../logger/constants';
|
|
7
7
|
|
|
8
8
|
export function dependencyMatcherContext({ split, treatments }: IDependencyMatcherData, storage: IStorageSync | IStorageAsync, log: ILogger) {
|
|
@@ -19,7 +19,7 @@ export function dependencyMatcherContext({ split, treatments }: IDependencyMatch
|
|
|
19
19
|
return matches;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
return function dependencyMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator:
|
|
22
|
+
return function dependencyMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator: IDefinitionEvaluator): MaybeThenable<boolean> {
|
|
23
23
|
log.debug(ENGINE_MATCHER_DEPENDENCY_PRE, [split, JSON.stringify(key), attributes ? '\n attributes: ' + JSON.stringify(attributes) : '']);
|
|
24
24
|
const evaluation = splitEvaluator(log, key, split, attributes, storage);
|
|
25
25
|
|
|
@@ -14,7 +14,7 @@ export const matcherTypes: Record<string, number> = {
|
|
|
14
14
|
ENDS_WITH: 12,
|
|
15
15
|
STARTS_WITH: 13,
|
|
16
16
|
CONTAINS_STRING: 14,
|
|
17
|
-
IN_SPLIT_TREATMENT: 15,
|
|
17
|
+
IN_SPLIT_TREATMENT: 15, // For flags only
|
|
18
18
|
EQUAL_TO_BOOLEAN: 16,
|
|
19
19
|
MATCHES_STRING: 17,
|
|
20
20
|
EQUAL_TO_SEMVER: 18,
|
|
@@ -22,7 +22,7 @@ export const matcherTypes: Record<string, number> = {
|
|
|
22
22
|
LESS_THAN_OR_EQUAL_TO_SEMVER: 20,
|
|
23
23
|
BETWEEN_SEMVER: 21,
|
|
24
24
|
IN_LIST_SEMVER: 22,
|
|
25
|
-
IN_LARGE_SEGMENT: 23,
|
|
25
|
+
IN_LARGE_SEGMENT: 23, // For client-side only
|
|
26
26
|
IN_RULE_BASED_SEGMENT: 24,
|
|
27
27
|
};
|
|
28
28
|
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinition, MaybeThenable } from '../../dtos/types';
|
|
2
2
|
import { IStorageAsync, IStorageSync } from '../../storages/types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
4
|
import { thenable } from '../../utils/promise/thenable';
|
|
5
|
-
import { IDependencyMatcherValue,
|
|
5
|
+
import { IDependencyMatcherValue, IDefinitionEvaluator } from '../types';
|
|
6
6
|
|
|
7
|
-
export function prerequisitesMatcherContext(prerequisites:
|
|
7
|
+
export function prerequisitesMatcherContext(prerequisites: IDefinition['prerequisites'], storage: IStorageSync | IStorageAsync, log: ILogger) {
|
|
8
8
|
|
|
9
|
-
return function prerequisitesMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator:
|
|
9
|
+
return function prerequisitesMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator: IDefinitionEvaluator): MaybeThenable<boolean> {
|
|
10
10
|
|
|
11
11
|
prerequisites = prerequisites == null ? [] : prerequisites;
|
|
12
12
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IExcludedSegment, IRBSegment, MaybeThenable } from '../../dtos/types';
|
|
2
2
|
import { IStorageAsync, IStorageSync } from '../../storages/types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
|
-
import { IDependencyMatcherValue,
|
|
4
|
+
import { IDependencyMatcherValue, IDefinitionEvaluator } from '../types';
|
|
5
5
|
import { thenable } from '../../utils/promise/thenable';
|
|
6
6
|
import { getMatching, keyParser } from '../../utils/key';
|
|
7
7
|
import { parser } from '../parser';
|
|
@@ -10,7 +10,7 @@ import { STANDARD_SEGMENT, RULE_BASED_SEGMENT, LARGE_SEGMENT } from '../../utils
|
|
|
10
10
|
|
|
11
11
|
export function ruleBasedSegmentMatcherContext(segmentName: string, storage: IStorageSync | IStorageAsync, log: ILogger) {
|
|
12
12
|
|
|
13
|
-
return function ruleBasedSegmentMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator:
|
|
13
|
+
return function ruleBasedSegmentMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator: IDefinitionEvaluator): MaybeThenable<boolean> {
|
|
14
14
|
const matchingKey = getMatching(key);
|
|
15
15
|
|
|
16
16
|
function matchConditions(rbsegment: IRBSegment) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export function whitelistMatcherContext(ruleAttr
|
|
2
|
-
const whitelistSet = new Set(ruleAttr);
|
|
1
|
+
export function whitelistMatcherContext(ruleAttr?: string[] | null) {
|
|
2
|
+
const whitelistSet = new Set(ruleAttr || []);
|
|
3
3
|
|
|
4
4
|
return function whitelistMatcher(runtimeAttr: string): boolean {
|
|
5
5
|
const isInWhitelist = whitelistSet.has(runtimeAttr);
|
|
@@ -4,13 +4,13 @@ import { segmentTransform } from './segment';
|
|
|
4
4
|
import { whitelistTransform } from './whitelist';
|
|
5
5
|
import { numericTransform } from './unaryNumeric';
|
|
6
6
|
import { zeroSinceHH, zeroSinceSS, betweenDateTimeTransform } from '../convertions';
|
|
7
|
-
import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData,
|
|
7
|
+
import { IBetweenMatcherData, IInLargeSegmentMatcherData, IInSegmentMatcherData, IDefinitionMatcher, IUnaryNumericMatcherData } from '../../dtos/types';
|
|
8
8
|
import { IMatcherDto } from '../types';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Flat the complex matcherGroup structure into something handy.
|
|
12
12
|
*/
|
|
13
|
-
export function matchersTransform(matchers:
|
|
13
|
+
export function matchersTransform(matchers: IDefinitionMatcher[]): IMatcherDto[] {
|
|
14
14
|
|
|
15
15
|
let parsedMatchers = matchers.map(matcher => {
|
|
16
16
|
let {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinitionMatcher } from '../../dtos/types';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Extract whitelist array.
|
|
5
5
|
*/
|
|
6
|
-
export function whitelistTransform(whitelistObject:
|
|
6
|
+
export function whitelistTransform(whitelistObject: IDefinitionMatcher['whitelistMatcherData']) {
|
|
7
7
|
return whitelistObject && whitelistObject.whitelist;
|
|
8
8
|
}
|
|
@@ -6,14 +6,14 @@ import { conditionContext } from '../condition';
|
|
|
6
6
|
import { ifElseIfCombinerContext } from '../combiners/ifelseif';
|
|
7
7
|
import { andCombinerContext } from '../combiners/and';
|
|
8
8
|
import { thenable } from '../../utils/promise/thenable';
|
|
9
|
-
import { IEvaluator, IMatcherDto,
|
|
10
|
-
import {
|
|
9
|
+
import { IEvaluator, IMatcherDto, IDefinitionEvaluator } from '../types';
|
|
10
|
+
import { IDefinitionCondition, MaybeThenable } from '../../dtos/types';
|
|
11
11
|
import { IStorageAsync, IStorageSync } from '../../storages/types';
|
|
12
12
|
import SplitIO from '../../../types/splitio';
|
|
13
13
|
import { ILogger } from '../../logger/types';
|
|
14
14
|
import { ENGINE_MATCHER_ERROR, ENGINE_MATCHER_RESULT } from '../../logger/constants';
|
|
15
15
|
|
|
16
|
-
export function parser(log: ILogger, conditions:
|
|
16
|
+
export function parser(log: ILogger, conditions: IDefinitionCondition[], storage: IStorageSync | IStorageAsync): IEvaluator {
|
|
17
17
|
let predicates = [];
|
|
18
18
|
|
|
19
19
|
for (let i = 0; i < conditions.length; i++) {
|
|
@@ -37,7 +37,7 @@ export function parser(log: ILogger, conditions: ISplitCondition[], storage: ISt
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
// Evaluator function.
|
|
40
|
-
return (key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?:
|
|
40
|
+
return (key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) => {
|
|
41
41
|
const value = sanitizeValue(log, key, matcherDto, attributes);
|
|
42
42
|
let result: MaybeThenable<boolean> = false;
|
|
43
43
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IDefinitionPartition } from '../../dtos/types';
|
|
2
2
|
import { findIndex } from '../../utils/lang';
|
|
3
3
|
|
|
4
4
|
export class Treatments {
|
|
@@ -15,7 +15,7 @@ export class Treatments {
|
|
|
15
15
|
this._treatments = treatments;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
static parse(data:
|
|
18
|
+
static parse(data: IDefinitionPartition[]) {
|
|
19
19
|
let { ranges, treatments } = data.reduce((accum, value) => {
|
|
20
20
|
let { size, treatment } = value;
|
|
21
21
|
|
package/src/evaluator/types.ts
CHANGED
|
@@ -13,8 +13,8 @@ export interface IMatcherDto {
|
|
|
13
13
|
name: string
|
|
14
14
|
value?: string | number | boolean | string[] | IDependencyMatcherData | IBetweenMatcherData | IBetweenStringMatcherData | null
|
|
15
15
|
|
|
16
|
-
attribute
|
|
17
|
-
negate
|
|
16
|
+
attribute?: string | null
|
|
17
|
+
negate?: boolean
|
|
18
18
|
dataType: string
|
|
19
19
|
}
|
|
20
20
|
|
|
@@ -22,13 +22,13 @@ export interface IEvaluation {
|
|
|
22
22
|
treatment?: string,
|
|
23
23
|
label: string,
|
|
24
24
|
changeNumber?: number,
|
|
25
|
-
config?: string | null
|
|
25
|
+
config?: string | null | SplitIO.JsonObject
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export type IEvaluationResult = IEvaluation & { treatment: string; impressionsDisabled?: boolean }
|
|
29
29
|
|
|
30
|
-
export type
|
|
30
|
+
export type IDefinitionEvaluator = (log: ILogger, key: SplitIO.SplitKey, definitionName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>
|
|
31
31
|
|
|
32
|
-
export type IEvaluator = (key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?:
|
|
32
|
+
export type IEvaluator = (key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) => MaybeThenable<IEvaluation | boolean | undefined>
|
|
33
33
|
|
|
34
|
-
export type IMatcher = (value: string | number | boolean | string[] | IDependencyMatcherValue,
|
|
34
|
+
export type IMatcher = (value: string | number | boolean | string[] | IDependencyMatcherValue, definitionEvaluator?: IDefinitionEvaluator) => MaybeThenable<boolean>
|
|
@@ -4,7 +4,7 @@ import { ILogger } from '../../logger/types';
|
|
|
4
4
|
import { sanitize } from './sanitize';
|
|
5
5
|
import { ENGINE_VALUE, ENGINE_VALUE_NO_ATTRIBUTES, ENGINE_VALUE_INVALID } from '../../logger/constants';
|
|
6
6
|
|
|
7
|
-
function parseValue(log: ILogger, key: SplitIO.SplitKey, attributeName
|
|
7
|
+
function parseValue(log: ILogger, key: SplitIO.SplitKey, attributeName?: string | null, attributes?: SplitIO.Attributes) {
|
|
8
8
|
let value = undefined;
|
|
9
9
|
if (attributeName) {
|
|
10
10
|
if (attributes) {
|
|
@@ -21,7 +21,7 @@ export function pluggableIntegrationsManagerFactory(
|
|
|
21
21
|
// No need to check if `settings.integrations` is an array of functions. It was already validated
|
|
22
22
|
integrations.forEach(integrationFactory => {
|
|
23
23
|
let integration = integrationFactory(params);
|
|
24
|
-
if (integration
|
|
24
|
+
if (integration) listeners.push(integration);
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
// If `listeners` is empty, not return a integration manager
|
package/src/listeners/browser.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
/* eslint-disable no-undef */
|
|
2
|
-
// @TODO eventually migrate to JS-Browser-SDK package.
|
|
3
2
|
import { ISignalListener } from './types';
|
|
4
3
|
import { IRecorderCacheSync, IStorageSync } from '../storages/types';
|
|
5
4
|
import { fromImpressionsCollector } from '../sync/submitters/impressionsSubmitter';
|
|
@@ -12,6 +11,7 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
12
11
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING, SUBMITTERS_PUSH_PAGE_HIDDEN } from '../logger/constants';
|
|
13
12
|
import { ISyncManager } from '../sync/types';
|
|
14
13
|
import { isConsentGranted } from '../consent';
|
|
14
|
+
import { ISdkFactoryContextSync } from '../sdkFactory/types';
|
|
15
15
|
|
|
16
16
|
const VISIBILITYCHANGE_EVENT = 'visibilitychange';
|
|
17
17
|
const PAGEHIDE_EVENT = 'pagehide';
|
|
@@ -22,17 +22,20 @@ const EVENT_NAME = 'for visibilitychange and pagehide events.';
|
|
|
22
22
|
*/
|
|
23
23
|
export class BrowserSignalListener implements ISignalListener {
|
|
24
24
|
|
|
25
|
+
private syncManager: ISyncManager | undefined;
|
|
26
|
+
private settings: ISettings;
|
|
27
|
+
private storage: IStorageSync;
|
|
28
|
+
private serviceApi: ISplitApi;
|
|
25
29
|
private fromImpressionsCollector: (data: SplitIO.ImpressionDTO[]) => ImpressionsPayload;
|
|
26
30
|
|
|
27
|
-
constructor(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
) {
|
|
31
|
+
constructor({ syncManager, settings, storage, splitApi, entityType }: ISdkFactoryContextSync) {
|
|
32
|
+
this.syncManager = syncManager;
|
|
33
|
+
this.settings = settings;
|
|
34
|
+
this.storage = storage;
|
|
35
|
+
this.serviceApi = splitApi;
|
|
33
36
|
this.flushData = this.flushData.bind(this);
|
|
34
37
|
this.flushDataIfHidden = this.flushDataIfHidden.bind(this);
|
|
35
|
-
this.fromImpressionsCollector = fromImpressionsCollector.bind(undefined, settings.core.labelsEnabled);
|
|
38
|
+
this.fromImpressionsCollector = fromImpressionsCollector.bind(undefined, settings.core.labelsEnabled, entityType);
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
/**
|
package/src/listeners/node.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { thenable } from '../utils/promise/thenable';
|
|
|
4
4
|
import { MaybeThenable } from '../dtos/types';
|
|
5
5
|
import { ISettings } from '../types';
|
|
6
6
|
import { LOG_PREFIX_CLEANUP, CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
7
|
-
import {
|
|
7
|
+
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
8
8
|
|
|
9
9
|
const SIGTERM = 'SIGTERM';
|
|
10
10
|
const EVENT_NAME = 'for SIGTERM signal.';
|
|
@@ -21,10 +21,7 @@ export class NodeSignalListener implements ISignalListener {
|
|
|
21
21
|
private handler: () => MaybeThenable<any>;
|
|
22
22
|
private settings: ISettings;
|
|
23
23
|
|
|
24
|
-
constructor(
|
|
25
|
-
syncManager: ISyncManager | undefined, // private handler: () => MaybeThenable<void>,
|
|
26
|
-
settings: ISettings
|
|
27
|
-
) {
|
|
24
|
+
constructor({ syncManager, settings }: ISdkFactoryContext) {
|
|
28
25
|
// @TODO review handler logic when implementing Node.js SDK
|
|
29
26
|
this.handler = function () {
|
|
30
27
|
if (syncManager) {
|