@splitsoftware/splitio-commons 1.9.1-rc.0 → 1.9.2-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 +5 -2
- package/cjs/evaluator/index.js +18 -1
- package/cjs/integrations/ga/GaToSplit.js +1 -1
- package/cjs/listeners/browser.js +3 -13
- package/cjs/logger/constants.js +7 -2
- package/cjs/logger/messages/error.js +2 -0
- package/cjs/logger/messages/warn.js +3 -1
- package/cjs/myLogger.js +34 -0
- package/cjs/sdkClient/client.js +33 -0
- package/cjs/sdkClient/clientAttributesDecoration.js +20 -0
- package/cjs/sdkClient/clientCS.js +5 -4
- package/cjs/sdkClient/clientInputValidation.js +52 -3
- package/cjs/sdkManager/index.js +2 -1
- package/cjs/services/splitApi.js +7 -1
- package/cjs/storages/KeyBuilder.js +3 -0
- package/cjs/storages/KeyBuilderSS.js +4 -0
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
- package/cjs/storages/inLocalStorage/index.js +2 -2
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -3
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +47 -2
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +11 -0
- package/cjs/storages/pluggable/SplitsCachePluggable.js +11 -0
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +24 -4
- package/cjs/sync/streaming/parseUtils.js +1 -0
- package/cjs/sync/submitters/telemetrySubmitter.js +15 -1
- package/cjs/utils/constants/index.js +6 -2
- package/cjs/utils/lang/sets.js +9 -1
- package/cjs/utils/settingsValidation/splitFilters.js +77 -2
- package/esm/evaluator/index.js +16 -0
- package/esm/integrations/ga/GaToSplit.js +1 -1
- package/esm/listeners/browser.js +3 -13
- package/esm/logger/constants.js +5 -0
- package/esm/logger/messages/error.js +2 -0
- package/esm/logger/messages/warn.js +3 -1
- package/esm/myLogger.js +31 -0
- package/esm/sdkClient/client.js +35 -2
- package/esm/sdkClient/clientAttributesDecoration.js +20 -0
- package/esm/sdkClient/clientCS.js +5 -4
- package/esm/sdkClient/clientInputValidation.js +52 -3
- package/esm/sdkManager/index.js +2 -1
- package/esm/services/splitApi.js +7 -1
- package/esm/storages/KeyBuilder.js +3 -0
- package/esm/storages/KeyBuilderSS.js +4 -0
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +63 -27
- package/esm/storages/inLocalStorage/index.js +2 -2
- package/esm/storages/inMemory/InMemoryStorage.js +2 -2
- package/esm/storages/inMemory/InMemoryStorageCS.js +3 -3
- package/esm/storages/inMemory/SplitsCacheInMemory.js +47 -2
- package/esm/storages/inRedis/SplitsCacheInRedis.js +11 -0
- package/esm/storages/pluggable/SplitsCachePluggable.js +11 -0
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +24 -4
- package/esm/sync/streaming/parseUtils.js +1 -0
- package/esm/sync/submitters/telemetrySubmitter.js +15 -1
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/lang/sets.js +7 -0
- package/esm/utils/settingsValidation/splitFilters.js +76 -2
- package/package.json +6 -6
- package/src/dtos/types.ts +3 -2
- package/src/evaluator/index.ts +24 -0
- package/src/integrations/ga/GaToSplit.ts +1 -1
- package/src/listeners/browser.ts +3 -13
- package/src/logger/constants.ts +5 -0
- package/src/logger/messages/error.ts +2 -0
- package/src/logger/messages/warn.ts +3 -1
- package/src/myLogger.ts +36 -0
- package/src/sdkClient/client.ts +42 -2
- package/src/sdkClient/clientAttributesDecoration.ts +24 -0
- package/src/sdkClient/clientCS.ts +5 -4
- package/src/sdkClient/clientInputValidation.ts +56 -4
- package/src/sdkManager/index.ts +2 -1
- package/src/services/splitApi.ts +6 -1
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -0
- package/src/storages/AbstractSplitsCacheSync.ts +3 -0
- package/src/storages/KeyBuilder.ts +4 -0
- package/src/storages/KeyBuilderSS.ts +4 -0
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +74 -28
- package/src/storages/inLocalStorage/index.ts +2 -2
- package/src/storages/inMemory/InMemoryStorage.ts +2 -2
- package/src/storages/inMemory/InMemoryStorageCS.ts +3 -3
- package/src/storages/inMemory/SplitsCacheInMemory.ts +50 -1
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +1 -1
- package/src/storages/inRedis/RedisAdapter.ts +1 -1
- package/src/storages/inRedis/SplitsCacheInRedis.ts +12 -0
- package/src/storages/pluggable/SplitsCachePluggable.ts +12 -0
- package/src/storages/types.ts +7 -3
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -0
- package/src/sync/polling/updaters/splitChangesUpdater.ts +27 -4
- package/src/sync/streaming/parseUtils.ts +1 -0
- package/src/sync/submitters/telemetrySubmitter.ts +19 -2
- package/src/sync/submitters/types.ts +7 -1
- package/src/types.ts +118 -1
- package/src/utils/constants/index.ts +4 -0
- package/src/utils/lang/sets.ts +8 -0
- package/src/utils/redis/RedisMock.ts +1 -1
- package/src/utils/settingsValidation/splitFilters.ts +82 -2
- package/types/dtos/types.d.ts +1 -0
- package/types/evaluator/index.d.ts +1 -0
- package/types/listeners/browser.d.ts +0 -1
- package/types/logger/constants.d.ts +5 -0
- package/types/myLogger.d.ts +5 -0
- package/types/sdkClient/clientAttributesDecoration.d.ts +4 -0
- package/types/sdkClient/types.d.ts +18 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +2 -0
- package/types/storages/AbstractSplitsCacheSync.d.ts +2 -0
- package/types/storages/KeyBuilder.d.ts +1 -0
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +6 -1
- package/types/storages/inMemory/CountsCacheInMemory.d.ts +20 -0
- package/types/storages/inMemory/LatenciesCacheInMemory.d.ts +20 -0
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +9 -1
- package/types/storages/inRedis/CountsCacheInRedis.d.ts +9 -0
- package/types/storages/inRedis/LatenciesCacheInRedis.d.ts +9 -0
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +8 -0
- package/types/storages/metadataBuilder.d.ts +3 -0
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +8 -0
- package/types/storages/types.d.ts +4 -0
- package/types/sync/offline/LocalhostFromFile.d.ts +2 -0
- package/types/sync/offline/splitsParser/splitsParserFromFile.d.ts +2 -0
- package/types/sync/offline/updaters/splitChangesUpdater.d.ts +0 -0
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +3 -3
- package/types/sync/submitters/eventsSyncTask.d.ts +8 -0
- package/types/sync/submitters/impressionCountsSubmitterInRedis.d.ts +5 -0
- package/types/sync/submitters/impressionCountsSyncTask.d.ts +13 -0
- package/types/sync/submitters/impressionsSyncTask.d.ts +14 -0
- package/types/sync/submitters/metricsSyncTask.d.ts +12 -0
- package/types/sync/submitters/submitterSyncTask.d.ts +10 -0
- package/types/sync/submitters/types.d.ts +7 -1
- package/types/sync/submitters/uniqueKeysSubmitterInRedis.d.ts +5 -0
- package/types/sync/syncTaskComposite.d.ts +5 -0
- package/types/trackers/filter/bloomFilter.d.ts +10 -0
- package/types/trackers/filter/dictionaryFilter.d.ts +8 -0
- package/types/trackers/filter/types.d.ts +5 -0
- package/types/types.d.ts +118 -1
- package/types/utils/constants/index.d.ts +4 -0
- package/types/utils/lang/sets.d.ts +1 -0
- package/types/utils/settingsValidation/splitFilters.d.ts +1 -0
- package/types/utils/timeTracker/index.d.ts +70 -0
- package/types/sdkClient/identity.d.ts +0 -6
- package/types/utils/inputValidation/sdkKey.d.ts +0 -7
- /package/types/storages/inMemory/{UniqueKeysCacheInMemory.d.ts → uniqueKeysCacheInMemory.d.ts} +0 -0
- /package/types/storages/inMemory/{UniqueKeysCacheInMemoryCS.d.ts → uniqueKeysCacheInMemoryCS.d.ts} +0 -0
- /package/types/storages/inRedis/{UniqueKeysCacheInRedis.d.ts → uniqueKeysCacheInRedis.d.ts} +0 -0
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { _Set, setToArray, ISet } from '../../../utils/lang/sets';
|
|
2
2
|
import { ISegmentsCacheBase, ISplitsCacheBase } from '../../../storages/types';
|
|
3
3
|
import { ISplitChangesFetcher } from '../fetchers/types';
|
|
4
|
-
import { ISplit, ISplitChangesResponse } from '../../../dtos/types';
|
|
4
|
+
import { ISplit, ISplitChangesResponse, ISplitFiltersValidation } from '../../../dtos/types';
|
|
5
5
|
import { ISplitsEventEmitter } from '../../../readiness/types';
|
|
6
6
|
import { timeout } from '../../../utils/promise/timeout';
|
|
7
7
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED } from '../../../readiness/constants';
|
|
8
8
|
import { ILogger } from '../../../logger/types';
|
|
9
9
|
import { SYNC_SPLITS_FETCH, SYNC_SPLITS_NEW, SYNC_SPLITS_REMOVED, SYNC_SPLITS_SEGMENTS, SYNC_SPLITS_FETCH_FAILS, SYNC_SPLITS_FETCH_RETRY } from '../../../logger/constants';
|
|
10
|
+
import { startsWith } from '../../../utils/lang';
|
|
10
11
|
|
|
11
12
|
type ISplitChangesUpdater = (noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }) => Promise<boolean>
|
|
12
13
|
|
|
@@ -45,15 +46,36 @@ interface ISplitMutations {
|
|
|
45
46
|
segments: string[]
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
/**
|
|
50
|
+
* If there are defined filters and one feature flag doesn't match with them, its status is changed to 'ARCHIVE' to avoid storing it
|
|
51
|
+
* If there are set filter defined, names filter is ignored
|
|
52
|
+
*
|
|
53
|
+
* @param featureFlag feature flag to be evaluated
|
|
54
|
+
* @param filters splitFiltersValidation bySet | byName
|
|
55
|
+
*/
|
|
56
|
+
function matchFilters(featureFlag: ISplit, filters: ISplitFiltersValidation) {
|
|
57
|
+
const { bySet: setsFilter, byName: namesFilter, byPrefix: prefixFilter} = filters.groupedFilters;
|
|
58
|
+
if (setsFilter.length > 0) return featureFlag.sets && featureFlag.sets.some((featureFlagSet: string) => setsFilter.indexOf(featureFlagSet) > -1);
|
|
59
|
+
|
|
60
|
+
const namesFilterConfigured = namesFilter.length > 0;
|
|
61
|
+
const prefixFilterConfigured = prefixFilter.length > 0;
|
|
62
|
+
|
|
63
|
+
if (!namesFilterConfigured && !prefixFilterConfigured) return true;
|
|
64
|
+
|
|
65
|
+
const matchNames = namesFilterConfigured && namesFilter.indexOf(featureFlag.name) > -1;
|
|
66
|
+
const matchPrefix = prefixFilterConfigured && prefixFilter.some(prefix => startsWith(featureFlag.name, prefix));
|
|
67
|
+
return matchNames || matchPrefix;
|
|
68
|
+
}
|
|
69
|
+
|
|
48
70
|
/**
|
|
49
71
|
* Given the list of splits from /splitChanges endpoint, it returns the mutations,
|
|
50
72
|
* i.e., an object with added splits, removed splits and used segments.
|
|
51
73
|
* Exported for testing purposes.
|
|
52
74
|
*/
|
|
53
|
-
export function computeSplitsMutation(entries: ISplit[]): ISplitMutations {
|
|
75
|
+
export function computeSplitsMutation(entries: ISplit[], filters: ISplitFiltersValidation): ISplitMutations {
|
|
54
76
|
const segments = new _Set<string>();
|
|
55
77
|
const computed = entries.reduce((accum, split) => {
|
|
56
|
-
if (split.status === 'ACTIVE') {
|
|
78
|
+
if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
|
|
57
79
|
accum.added.push([split.name, split]);
|
|
58
80
|
|
|
59
81
|
parseSegments(split).forEach((segmentName: string) => {
|
|
@@ -90,6 +112,7 @@ export function splitChangesUpdaterFactory(
|
|
|
90
112
|
splitChangesFetcher: ISplitChangesFetcher,
|
|
91
113
|
splits: ISplitsCacheBase,
|
|
92
114
|
segments: ISegmentsCacheBase,
|
|
115
|
+
splitFiltersValidation: ISplitFiltersValidation,
|
|
93
116
|
splitsEventEmitter?: ISplitsEventEmitter,
|
|
94
117
|
requestTimeoutBeforeReady: number = 0,
|
|
95
118
|
retriesOnFailureBeforeReady: number = 0,
|
|
@@ -126,7 +149,7 @@ export function splitChangesUpdaterFactory(
|
|
|
126
149
|
.then((splitChanges: ISplitChangesResponse) => {
|
|
127
150
|
startingUp = false;
|
|
128
151
|
|
|
129
|
-
const mutation = computeSplitsMutation(splitChanges.splits);
|
|
152
|
+
const mutation = computeSplitsMutation(splitChanges.splits, splitFiltersValidation);
|
|
130
153
|
|
|
131
154
|
log.debug(SYNC_SPLITS_NEW, [mutation.added.length]);
|
|
132
155
|
log.debug(SYNC_SPLITS_REMOVED, [mutation.removed.length]);
|
|
@@ -11,6 +11,7 @@ function Uint8ArrayToString(myUint8Arr: Uint8Array) { // @ts-ignore
|
|
|
11
11
|
|
|
12
12
|
function StringToUint8Array(myString: string) {
|
|
13
13
|
const charCodes = myString.split('').map((e) => e.charCodeAt(0));
|
|
14
|
+
// eslint-disable-next-line compat/compat
|
|
14
15
|
return new Uint8Array(charCodes);
|
|
15
16
|
}
|
|
16
17
|
|
|
@@ -3,12 +3,13 @@ import { submitterFactory, firstPushWindowDecorator } from './submitter';
|
|
|
3
3
|
import { TelemetryConfigStatsPayload, TelemetryConfigStats } from './types';
|
|
4
4
|
import { CONSUMER_MODE, CONSUMER_ENUM, STANDALONE_MODE, CONSUMER_PARTIAL_MODE, STANDALONE_ENUM, CONSUMER_PARTIAL_ENUM, OPTIMIZED, DEBUG, NONE, DEBUG_ENUM, OPTIMIZED_ENUM, NONE_ENUM, CONSENT_GRANTED, CONSENT_DECLINED, CONSENT_UNKNOWN } from '../../utils/constants';
|
|
5
5
|
import { SDK_READY, SDK_READY_FROM_CACHE } from '../../readiness/constants';
|
|
6
|
-
import { ConsentStatus, ISettings, SDKMode } from '../../types';
|
|
6
|
+
import { ConsentStatus, ISettings, SDKMode, SplitIO } from '../../types';
|
|
7
7
|
import { base } from '../../utils/settingsValidation';
|
|
8
8
|
import { usedKeysMap } from '../../utils/inputValidation/apiKey';
|
|
9
9
|
import { timer } from '../../utils/timeTracker/timer';
|
|
10
10
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
11
11
|
import { objectAssign } from '../../utils/lang/objectAssign';
|
|
12
|
+
import { ISplitFiltersValidation } from '../../dtos/types';
|
|
12
13
|
|
|
13
14
|
const OPERATION_MODE_MAP = {
|
|
14
15
|
[STANDALONE_MODE]: STANDALONE_ENUM,
|
|
@@ -38,6 +39,18 @@ function getRedundantActiveFactories() {
|
|
|
38
39
|
}, 0);
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
function getTelemetryFlagSetsStats(splitFiltersValidation: ISplitFiltersValidation) {
|
|
43
|
+
// Group every configured flag set in an unique array called originalSets
|
|
44
|
+
let flagSetsTotal = 0;
|
|
45
|
+
splitFiltersValidation.validFilters.forEach((filter: SplitIO.SplitFilter) => {
|
|
46
|
+
if (filter.type === 'bySet') flagSetsTotal += filter.values.length;
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const flagSetsValid = splitFiltersValidation.groupedFilters.bySet.length;
|
|
50
|
+
const flagSetsIgnored = flagSetsTotal - flagSetsValid;
|
|
51
|
+
return { flagSetsTotal, flagSetsIgnored };
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
export function getTelemetryConfigStats(mode: SDKMode, storageType: string): TelemetryConfigStats {
|
|
42
55
|
return {
|
|
43
56
|
oM: OPERATION_MODE_MAP[mode], // @ts-ignore lower case of storage type
|
|
@@ -59,6 +72,8 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
|
|
|
59
72
|
const { urls, scheduler } = settings;
|
|
60
73
|
const isClientSide = settings.core.key !== undefined;
|
|
61
74
|
|
|
75
|
+
const { flagSetsTotal, flagSetsIgnored } = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation);
|
|
76
|
+
|
|
62
77
|
return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
|
63
78
|
sE: settings.streamingEnabled,
|
|
64
79
|
rR: {
|
|
@@ -86,7 +101,9 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
|
|
|
86
101
|
nR: telemetry.getNonReadyUsage(),
|
|
87
102
|
t: telemetry.popTags(),
|
|
88
103
|
i: settings.integrations && settings.integrations.map(int => int.type),
|
|
89
|
-
uC: settings.userConsent ? USER_CONSENT_MAP[settings.userConsent] : 0
|
|
104
|
+
uC: settings.userConsent ? USER_CONSENT_MAP[settings.userConsent] : 0,
|
|
105
|
+
fsT: flagSetsTotal,
|
|
106
|
+
fsI: flagSetsIgnored
|
|
90
107
|
});
|
|
91
108
|
}
|
|
92
109
|
};
|
|
@@ -124,7 +124,11 @@ export type TREATMENTS = 'ts';
|
|
|
124
124
|
export type TREATMENT_WITH_CONFIG = 'tc';
|
|
125
125
|
export type TREATMENTS_WITH_CONFIG = 'tcs';
|
|
126
126
|
export type TRACK = 'tr';
|
|
127
|
-
export type
|
|
127
|
+
export type TREATMENTS_BY_FLAGSET = 'tf'
|
|
128
|
+
export type TREATMENTS_BY_FLAGSETS = 'tfs'
|
|
129
|
+
export type TREATMENTS_WITH_CONFIG_BY_FLAGSET = 'tcf'
|
|
130
|
+
export type TREATMENTS_WITH_CONFIG_BY_FLAGSETS = 'tcfs'
|
|
131
|
+
export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK | TREATMENTS_BY_FLAGSET | TREATMENTS_BY_FLAGSETS | TREATMENTS_WITH_CONFIG_BY_FLAGSET | TREATMENTS_WITH_CONFIG_BY_FLAGSETS;
|
|
128
132
|
|
|
129
133
|
export type MethodLatencies = Partial<Record<Method, Array<number>>>;
|
|
130
134
|
|
|
@@ -234,6 +238,8 @@ export type TelemetryConfigStatsPayload = TelemetryConfigStats & {
|
|
|
234
238
|
nR: number, // SDKNotReadyUsage
|
|
235
239
|
i?: Array<string>, // integrations
|
|
236
240
|
uC: number, // userConsent
|
|
241
|
+
fsT: number, // flagSetsTotal
|
|
242
|
+
fsI: number, // flagSetsInvalid
|
|
237
243
|
}
|
|
238
244
|
|
|
239
245
|
export interface ISubmitterManager extends ISyncTask {
|
package/src/types.ts
CHANGED
|
@@ -610,6 +610,11 @@ export namespace SplitIO {
|
|
|
610
610
|
configs: {
|
|
611
611
|
[treatmentName: string]: string
|
|
612
612
|
}
|
|
613
|
+
/**
|
|
614
|
+
* list of sets per feature flag
|
|
615
|
+
* @property {string[]} sets
|
|
616
|
+
*/
|
|
617
|
+
sets?: string[]
|
|
613
618
|
};
|
|
614
619
|
/**
|
|
615
620
|
* A promise that resolves to a feature flag view.
|
|
@@ -709,7 +714,7 @@ export namespace SplitIO {
|
|
|
709
714
|
* SplitFilter type.
|
|
710
715
|
* @typedef {string} SplitFilterType
|
|
711
716
|
*/
|
|
712
|
-
export type SplitFilterType = 'byName' | 'byPrefix';
|
|
717
|
+
export type SplitFilterType = 'byName' | 'byPrefix' | 'bySet';
|
|
713
718
|
/**
|
|
714
719
|
* Defines a feature flag filter, described by a type and list of values.
|
|
715
720
|
*/
|
|
@@ -1059,6 +1064,42 @@ export namespace SplitIO {
|
|
|
1059
1064
|
* @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects
|
|
1060
1065
|
*/
|
|
1061
1066
|
getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig,
|
|
1067
|
+
/**
|
|
1068
|
+
* Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flagSet.
|
|
1069
|
+
* @function getTreatmentsByFlagSet
|
|
1070
|
+
* @param {string} key - The string key representing the consumer.
|
|
1071
|
+
* @param {string} flagSet - The flagSet name we want to get the treatments.
|
|
1072
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1073
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1074
|
+
*/
|
|
1075
|
+
getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments,
|
|
1076
|
+
/**
|
|
1077
|
+
* 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 flagSets.
|
|
1078
|
+
* @function getTreatmentsWithConfigByFlagSet
|
|
1079
|
+
* @param {string} key - The string key representing the consumer.
|
|
1080
|
+
* @param {string} flagSet - The flagSet name we want to get the treatments.
|
|
1081
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1082
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1083
|
+
*/
|
|
1084
|
+
getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig,
|
|
1085
|
+
/**
|
|
1086
|
+
* 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 flagSets.
|
|
1087
|
+
* @function getTreatmentsByFlagSets
|
|
1088
|
+
* @param {string} key - The string key representing the consumer.
|
|
1089
|
+
* @param {Array<string>} flagSets - An array of the flagSet names we want to get the treatments.
|
|
1090
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1091
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1092
|
+
*/
|
|
1093
|
+
getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments,
|
|
1094
|
+
/**
|
|
1095
|
+
* 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 flagSets.
|
|
1096
|
+
* @function getTreatmentsWithConfigByFlagSets
|
|
1097
|
+
* @param {string} key - The string key representing the consumer.
|
|
1098
|
+
* @param {Array<string>} flagSets - An array of the flagSet names we want to get the treatments.
|
|
1099
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1100
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1101
|
+
*/
|
|
1102
|
+
getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig,
|
|
1062
1103
|
/**
|
|
1063
1104
|
* Tracks an event to be fed to the results product on Split user interface.
|
|
1064
1105
|
* @function track
|
|
@@ -1119,6 +1160,46 @@ export namespace SplitIO {
|
|
|
1119
1160
|
* @returns {AsyncTreatmentsWithConfig} TreatmentsWithConfig promise that resolves to the map of TreatmentsWithConfig objects.
|
|
1120
1161
|
*/
|
|
1121
1162
|
getTreatmentsWithConfig(key: SplitKey, featureFlagNames: string[], attributes?: Attributes): AsyncTreatmentsWithConfig,
|
|
1163
|
+
/**
|
|
1164
|
+
* Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the features related to the given flag set.
|
|
1165
|
+
* For usage on NodeJS as we don't have only one key.
|
|
1166
|
+
* @function getTreatmentsByFlagSet
|
|
1167
|
+
* @param {string} key - The string key representing the consumer.
|
|
1168
|
+
* @param {string} flagSet - The flag set name we want to get the treatments.
|
|
1169
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1170
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1171
|
+
*/
|
|
1172
|
+
getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatments,
|
|
1173
|
+
/**
|
|
1174
|
+
* Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for features related to the given flag set.
|
|
1175
|
+
* For usage on NodeJS as we don't have only one key.
|
|
1176
|
+
* @function getTreatmentsWithConfigByFlagSet
|
|
1177
|
+
* @param {string} key - The string key representing the consumer.
|
|
1178
|
+
* @param {string} flagSet - The flag set name we want to get the treatments.
|
|
1179
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1180
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1181
|
+
*/
|
|
1182
|
+
getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): AsyncTreatmentsWithConfig,
|
|
1183
|
+
/**
|
|
1184
|
+
* Returns a Treatments value, which will be (or eventually be) an object map with the treatments for the feature flags related to the given flag sets.
|
|
1185
|
+
* For usage on NodeJS as we don't have only one key.
|
|
1186
|
+
* @function getTreatmentsByFlagSets
|
|
1187
|
+
* @param {string} key - The string key representing the consumer.
|
|
1188
|
+
* @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
|
|
1189
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1190
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1191
|
+
*/
|
|
1192
|
+
getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatments,
|
|
1193
|
+
/**
|
|
1194
|
+
* Returns a TreatmentWithConfig value, which will be (or eventually be) an object with both treatment and config string for the feature flags related to the given flag sets.
|
|
1195
|
+
* For usage on NodeJS as we don't have only one key.
|
|
1196
|
+
* @function getTreatmentsWithConfigByFlagSets
|
|
1197
|
+
* @param {string} key - The string key representing the consumer.
|
|
1198
|
+
* @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
|
|
1199
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1200
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1201
|
+
*/
|
|
1202
|
+
getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): AsyncTreatmentsWithConfig,
|
|
1122
1203
|
/**
|
|
1123
1204
|
* 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).
|
|
1124
1205
|
* @function track
|
|
@@ -1169,6 +1250,42 @@ export namespace SplitIO {
|
|
|
1169
1250
|
* @returns {TreatmentsWithConfig} The map with all the TreatmentWithConfig objects
|
|
1170
1251
|
*/
|
|
1171
1252
|
getTreatmentsWithConfig(featureFlagNames: string[], attributes?: Attributes): TreatmentsWithConfig,
|
|
1253
|
+
/**
|
|
1254
|
+
* Returns a Treatments value, which is an object map with the treatments for the feature flags related to the given flag set.
|
|
1255
|
+
* @function getTreatmentsByFlagSet
|
|
1256
|
+
* @param {string} key - The string key representing the consumer.
|
|
1257
|
+
* @param {string} flagSet - The flag set name we want to get the treatments.
|
|
1258
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1259
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1260
|
+
*/
|
|
1261
|
+
getTreatmentsByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): Treatments,
|
|
1262
|
+
/**
|
|
1263
|
+
* 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.
|
|
1264
|
+
* @function getTreatmentsWithConfigByFlagSet
|
|
1265
|
+
* @param {string} key - The string key representing the consumer.
|
|
1266
|
+
* @param {string} flagSet - The flag set name we want to get the treatments.
|
|
1267
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1268
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1269
|
+
*/
|
|
1270
|
+
getTreatmentsWithConfigByFlagSet(key: SplitKey, flagSet: string, attributes?: Attributes): TreatmentsWithConfig,
|
|
1271
|
+
/**
|
|
1272
|
+
* 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.
|
|
1273
|
+
* @function getTreatmentsByFlagSets
|
|
1274
|
+
* @param {string} key - The string key representing the consumer.
|
|
1275
|
+
* @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
|
|
1276
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1277
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1278
|
+
*/
|
|
1279
|
+
getTreatmentsByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): Treatments,
|
|
1280
|
+
/**
|
|
1281
|
+
* 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.
|
|
1282
|
+
* @function getTreatmentsWithConfigByFlagSets
|
|
1283
|
+
* @param {string} key - The string key representing the consumer.
|
|
1284
|
+
* @param {Array<string>} flagSets - An array of the flag set names we want to get the treatments.
|
|
1285
|
+
* @param {Attributes=} attributes - An object of type Attributes defining the attributes for the given key.
|
|
1286
|
+
* @returns {Treatments} The map with all the TreatmentWithConfig objects
|
|
1287
|
+
*/
|
|
1288
|
+
getTreatmentsWithConfigByFlagSets(key: SplitKey, flagSets: string[], attributes?: Attributes): TreatmentsWithConfig,
|
|
1172
1289
|
/**
|
|
1173
1290
|
* Tracks an event to be fed to the results product on Split user interface.
|
|
1174
1291
|
* @function track
|
|
@@ -65,6 +65,10 @@ export const TREATMENT = 't';
|
|
|
65
65
|
export const TREATMENTS = 'ts';
|
|
66
66
|
export const TREATMENT_WITH_CONFIG = 'tc';
|
|
67
67
|
export const TREATMENTS_WITH_CONFIG = 'tcs';
|
|
68
|
+
export const TREATMENTS_BY_FLAGSET = 'tf';
|
|
69
|
+
export const TREATMENTS_BY_FLAGSETS = 'tfs';
|
|
70
|
+
export const TREATMENTS_WITH_CONFIG_BY_FLAGSET = 'tcf';
|
|
71
|
+
export const TREATMENTS_WITH_CONFIG_BY_FLAGSETS = 'tcfs';
|
|
68
72
|
export const TRACK = 'tr';
|
|
69
73
|
|
|
70
74
|
export const CONNECTION_ESTABLISHED = 0;
|
package/src/utils/lang/sets.ts
CHANGED
|
@@ -111,3 +111,11 @@ export function __getSetConstructor(): ISetConstructor {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
export const _Set = __getSetConstructor();
|
|
114
|
+
|
|
115
|
+
export function returnSetsUnion<T>(set: ISet<T>, set2: ISet<T>): ISet<T> {
|
|
116
|
+
const result = new _Set(setToArray(set));
|
|
117
|
+
set2.forEach( value => {
|
|
118
|
+
result.add(value);
|
|
119
|
+
});
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
@@ -13,7 +13,7 @@ const PIPELINE_METHODS = ['rpush', 'hincrby'];
|
|
|
13
13
|
|
|
14
14
|
export class RedisMock {
|
|
15
15
|
|
|
16
|
-
private pipelineMethods: any = { exec: jest.fn(asyncFunction) }
|
|
16
|
+
private pipelineMethods: any = { exec: jest.fn(asyncFunction) };
|
|
17
17
|
|
|
18
18
|
constructor() {
|
|
19
19
|
IDENTITY_METHODS.forEach(method => {
|
|
@@ -3,11 +3,18 @@ import { validateSplits } from '../inputValidation/splits';
|
|
|
3
3
|
import { ISplitFiltersValidation } from '../../dtos/types';
|
|
4
4
|
import { SplitIO } from '../../types';
|
|
5
5
|
import { ILogger } from '../../logger/types';
|
|
6
|
-
import { WARN_SPLITS_FILTER_IGNORED, WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS } from '../../logger/constants';
|
|
6
|
+
import { WARN_SPLITS_FILTER_IGNORED, WARN_SPLITS_FILTER_EMPTY, WARN_SPLITS_FILTER_INVALID, SETTINGS_SPLITS_FILTER, LOG_PREFIX_SETTINGS, ERROR_SETS_FILTER_EXCLUSIVE, WARN_SPLITS_FILTER_LOWERCASE_SET, WARN_SPLITS_FILTER_INVALID_SET, ERROR_EMPTY_ARRAY, WARN_FLAGSET_NOT_CONFIGURED } from '../../logger/constants';
|
|
7
|
+
import { objectAssign } from '../lang/objectAssign';
|
|
8
|
+
import { find, uniq } from '../lang';
|
|
7
9
|
|
|
8
10
|
// Split filters metadata.
|
|
9
11
|
// Ordered according to their precedency when forming the filter query string: `&names=<values>&prefixes=<values>`
|
|
10
12
|
const FILTERS_METADATA = [
|
|
13
|
+
{
|
|
14
|
+
type: 'bySet' as SplitIO.SplitFilterType,
|
|
15
|
+
maxLength: 50,
|
|
16
|
+
queryParam: 'sets='
|
|
17
|
+
},
|
|
11
18
|
{
|
|
12
19
|
type: 'byName' as SplitIO.SplitFilterType,
|
|
13
20
|
maxLength: 400,
|
|
@@ -20,6 +27,9 @@ const FILTERS_METADATA = [
|
|
|
20
27
|
}
|
|
21
28
|
];
|
|
22
29
|
|
|
30
|
+
const VALID_FLAGSET_REGEX = /^[a-z0-9][_a-z0-9]{0,49}$/;
|
|
31
|
+
const CAPITAL_LETTERS_REGEX = /[A-Z]/;
|
|
32
|
+
|
|
23
33
|
/**
|
|
24
34
|
* Validates that the given value is a valid filter type
|
|
25
35
|
*/
|
|
@@ -42,6 +52,11 @@ function validateSplitFilter(log: ILogger, type: SplitIO.SplitFilterType, values
|
|
|
42
52
|
let result = validateSplits(log, values, LOG_PREFIX_SETTINGS, `${type} filter`, `${type} filter value`);
|
|
43
53
|
|
|
44
54
|
if (result) {
|
|
55
|
+
|
|
56
|
+
if (type === 'bySet') {
|
|
57
|
+
result = sanitizeFlagSets(log, result);
|
|
58
|
+
}
|
|
59
|
+
|
|
45
60
|
// check max length
|
|
46
61
|
if (result.length > maxLength) throw new Error(`${maxLength} unique values can be specified at most for '${type}' filter. You passed ${result.length}. Please consider reducing the amount or using other filter.`);
|
|
47
62
|
|
|
@@ -72,6 +87,43 @@ function queryStringBuilder(groupedFilters: Record<SplitIO.SplitFilterType, stri
|
|
|
72
87
|
return queryParams.length > 0 ? '&' + queryParams.join('&') : null;
|
|
73
88
|
}
|
|
74
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Sanitizes set names list taking in account:
|
|
92
|
+
* - It should be lowercase
|
|
93
|
+
* - Must adhere the following regular expression /^[a-z0-9][_a-z0-9]{0,49}$/ that means
|
|
94
|
+
* - must start with a letter or number
|
|
95
|
+
* - Be in lowercase
|
|
96
|
+
* - Be alphanumeric
|
|
97
|
+
* - have a max length of 50 characters
|
|
98
|
+
*
|
|
99
|
+
* @param {ILogger} log
|
|
100
|
+
* @param {string[]} flagSets
|
|
101
|
+
* @returns sanitized list of set names
|
|
102
|
+
*/
|
|
103
|
+
function sanitizeFlagSets(log: ILogger, flagSets: string[]) {
|
|
104
|
+
let sanitizedSets = flagSets
|
|
105
|
+
.map(flagSet => {
|
|
106
|
+
if (CAPITAL_LETTERS_REGEX.test(flagSet)){
|
|
107
|
+
log.warn(WARN_SPLITS_FILTER_LOWERCASE_SET,[flagSet]);
|
|
108
|
+
flagSet = flagSet.toLowerCase();
|
|
109
|
+
}
|
|
110
|
+
return flagSet;
|
|
111
|
+
})
|
|
112
|
+
.filter(flagSet => {
|
|
113
|
+
if (!VALID_FLAGSET_REGEX.test(flagSet)){
|
|
114
|
+
log.warn(WARN_SPLITS_FILTER_INVALID_SET, [flagSet,VALID_FLAGSET_REGEX,flagSet]);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
if (typeof flagSet !== 'string') return false;
|
|
118
|
+
return true;
|
|
119
|
+
});
|
|
120
|
+
return uniq(sanitizedSets);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function configuredFilter(validFilters: SplitIO.SplitFilter[], filterType: SplitIO.SplitFilterType) {
|
|
124
|
+
return find(validFilters, (filter: SplitIO.SplitFilter) => filter.type === filterType && filter.values.length > 0);
|
|
125
|
+
}
|
|
126
|
+
|
|
75
127
|
/**
|
|
76
128
|
* Validates `splitFilters` configuration object and parses it into a query string for filtering splits on `/splitChanges` fetch.
|
|
77
129
|
*
|
|
@@ -90,7 +142,7 @@ export function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode:
|
|
|
90
142
|
const res = {
|
|
91
143
|
validFilters: [],
|
|
92
144
|
queryString: null,
|
|
93
|
-
groupedFilters: { byName: [], byPrefix: [] }
|
|
145
|
+
groupedFilters: { bySet: [], byName: [], byPrefix: [] },
|
|
94
146
|
} as ISplitFiltersValidation;
|
|
95
147
|
|
|
96
148
|
// do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
|
|
@@ -122,9 +174,37 @@ export function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode:
|
|
|
122
174
|
if (res.groupedFilters[type].length > 0) res.groupedFilters[type] = validateSplitFilter(log, type, res.groupedFilters[type], maxLength);
|
|
123
175
|
});
|
|
124
176
|
|
|
177
|
+
const setFilter = configuredFilter(res.validFilters, 'bySet');
|
|
178
|
+
// Clean all filters if set filter is present
|
|
179
|
+
if (setFilter) {
|
|
180
|
+
if (configuredFilter(res.validFilters, 'byName') || configuredFilter(res.validFilters, 'byPrefix')) log.error(ERROR_SETS_FILTER_EXCLUSIVE);
|
|
181
|
+
objectAssign(res.groupedFilters, { byName: [], byPrefix: [] });
|
|
182
|
+
}
|
|
183
|
+
|
|
125
184
|
// build query string
|
|
126
185
|
res.queryString = queryStringBuilder(res.groupedFilters);
|
|
127
186
|
log.debug(SETTINGS_SPLITS_FILTER, [res.queryString]);
|
|
128
187
|
|
|
129
188
|
return res;
|
|
130
189
|
}
|
|
190
|
+
|
|
191
|
+
export function flagSetsAreValid(log: ILogger, method: string, flagSets: string[], flagSetsInConfig: string[]): string[] {
|
|
192
|
+
let toReturn: string[] = [];
|
|
193
|
+
if (flagSets.length === 0) {
|
|
194
|
+
log.error(ERROR_EMPTY_ARRAY, [method, 'flagSets']);
|
|
195
|
+
return toReturn;
|
|
196
|
+
}
|
|
197
|
+
const sets = validateSplits(log, flagSets, method, 'flag sets', 'flag set');
|
|
198
|
+
toReturn = sets ? sanitizeFlagSets(log, sets) : [];
|
|
199
|
+
if (flagSetsInConfig.length > 0) {
|
|
200
|
+
toReturn = toReturn.filter(flagSet => {
|
|
201
|
+
if (flagSetsInConfig.indexOf(flagSet) > -1) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
log.warn(WARN_FLAGSET_NOT_CONFIGURED, [flagSet]);
|
|
205
|
+
return false;
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return toReturn;
|
|
210
|
+
}
|
package/types/dtos/types.d.ts
CHANGED
|
@@ -132,6 +132,7 @@ export interface ISplit {
|
|
|
132
132
|
configurations?: {
|
|
133
133
|
[treatmentName: string]: string;
|
|
134
134
|
};
|
|
135
|
+
sets?: string[];
|
|
135
136
|
}
|
|
136
137
|
export declare type ISplitPartial = Pick<ISplit, 'conditions' | 'configurations' | 'trafficTypeName'>;
|
|
137
138
|
/** Interface of the parsed JSON response of `/splitChanges` */
|
|
@@ -5,3 +5,4 @@ import { SplitIO } from '../types';
|
|
|
5
5
|
import { ILogger } from '../logger/types';
|
|
6
6
|
export declare function evaluateFeature(log: ILogger, key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<IEvaluationResult>;
|
|
7
7
|
export declare function evaluateFeatures(log: ILogger, key: SplitIO.SplitKey, splitNames: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<Record<string, IEvaluationResult>>;
|
|
8
|
+
export declare function evaluateFeaturesByFlagSets(log: ILogger, key: SplitIO.SplitKey, flagSets: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync): MaybeThenable<Record<string, IEvaluationResult>>;
|
|
@@ -23,7 +23,6 @@ export declare class BrowserSignalListener implements ISignalListener {
|
|
|
23
23
|
* Called when client is destroyed, it removes event listeners.
|
|
24
24
|
*/
|
|
25
25
|
stop(): void;
|
|
26
|
-
stopSync(): void;
|
|
27
26
|
/**
|
|
28
27
|
* flushData method.
|
|
29
28
|
* Called when pagehide event is triggered. It flushed remaining impressions and events to the backend,
|
|
@@ -95,6 +95,9 @@ export declare const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
|
95
95
|
export declare const WARN_SDK_KEY = 222;
|
|
96
96
|
export declare const STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
97
97
|
export declare const STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
98
|
+
export declare const WARN_SPLITS_FILTER_INVALID_SET = 225;
|
|
99
|
+
export declare const WARN_SPLITS_FILTER_LOWERCASE_SET = 226;
|
|
100
|
+
export declare const WARN_FLAGSET_NOT_CONFIGURED = 227;
|
|
98
101
|
export declare const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
99
102
|
export declare const ERROR_LOGLEVEL_INVALID = 301;
|
|
100
103
|
export declare const ERROR_CLIENT_LISTENER = 302;
|
|
@@ -122,6 +125,8 @@ export declare const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
|
122
125
|
export declare const ERROR_STORAGE_INVALID = 324;
|
|
123
126
|
export declare const ERROR_NOT_BOOLEAN = 325;
|
|
124
127
|
export declare const ERROR_MIN_CONFIG_PARAM = 326;
|
|
128
|
+
export declare const ERROR_TOO_MANY_SETS = 327;
|
|
129
|
+
export declare const ERROR_SETS_FILTER_EXCLUSIVE = 328;
|
|
125
130
|
export declare const LOG_PREFIX_SETTINGS = "settings";
|
|
126
131
|
export declare const LOG_PREFIX_INSTANTIATION = "Factory instantiation";
|
|
127
132
|
export declare const LOG_PREFIX_ENGINE = "engine";
|
|
@@ -8,6 +8,10 @@ export declare function clientAttributesDecoration<TClient extends SplitIO.IClie
|
|
|
8
8
|
getTreatmentWithConfig: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagName: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentWithConfig | SplitIO.AsyncTreatmentWithConfig;
|
|
9
9
|
getTreatments: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
|
|
10
10
|
getTreatmentsWithConfig: (maybeKey: SplitIO.SplitKey, maybeFeatureFlagNames: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
|
|
11
|
+
getTreatmentsByFlagSets: (maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
|
|
12
|
+
getTreatmentsWithConfigByFlagSets: (maybeKey: SplitIO.SplitKey, maybeFlagSets: string[], maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
|
|
13
|
+
getTreatmentsByFlagSet: (maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.Treatments | SplitIO.AsyncTreatments;
|
|
14
|
+
getTreatmentsWithConfigByFlagSet: (maybeKey: SplitIO.SplitKey, maybeFlagSet: string, maybeAttributes?: SplitIO.Attributes | undefined) => SplitIO.TreatmentsWithConfig | SplitIO.AsyncTreatmentsWithConfig;
|
|
11
15
|
track: (maybeKey: SplitIO.SplitKey, maybeTT: string, maybeEvent: string, maybeEventValue?: number | undefined, maybeProperties?: SplitIO.Properties | undefined) => boolean | Promise<boolean>;
|
|
12
16
|
/**
|
|
13
17
|
* Add an attribute to client's in memory attributes storage
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { ISignalListener } from '../listeners/types';
|
|
2
|
+
import { ISdkReadinessManager } from '../readiness/types';
|
|
3
|
+
import { IStorageAsync, IStorageSync } from '../storages/types';
|
|
4
|
+
import { ISyncManager } from '../sync/types';
|
|
5
|
+
import { IEventTracker, IImpressionsTracker } from '../trackers/types';
|
|
6
|
+
import { ISettings } from '../types';
|
|
7
|
+
export interface IClientFactoryParams {
|
|
8
|
+
storage: IStorageSync | IStorageAsync;
|
|
9
|
+
sdkReadinessManager: ISdkReadinessManager;
|
|
10
|
+
settings: ISettings;
|
|
11
|
+
impressionsTracker: IImpressionsTracker;
|
|
12
|
+
eventTracker: IEventTracker;
|
|
13
|
+
}
|
|
14
|
+
export interface ISdkClientFactoryParams extends IClientFactoryParams {
|
|
15
|
+
signalListener?: ISignalListener;
|
|
16
|
+
syncManager?: ISyncManager;
|
|
17
|
+
sharedClient?: boolean;
|
|
18
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ISplitsCacheAsync } from './types';
|
|
2
2
|
import { ISplit } from '../dtos/types';
|
|
3
|
+
import { ISet } from '../utils/lang/sets';
|
|
3
4
|
/**
|
|
4
5
|
* This class provides a skeletal implementation of the ISplitsCacheAsync interface
|
|
5
6
|
* to minimize the effort required to implement this interface.
|
|
@@ -14,6 +15,7 @@ export declare abstract class AbstractSplitsCacheAsync implements ISplitsCacheAs
|
|
|
14
15
|
abstract getChangeNumber(): Promise<number>;
|
|
15
16
|
abstract getAll(): Promise<ISplit[]>;
|
|
16
17
|
abstract getSplitNames(): Promise<string[]>;
|
|
18
|
+
abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>>;
|
|
17
19
|
abstract trafficTypeExists(trafficType: string): Promise<boolean>;
|
|
18
20
|
abstract clear(): Promise<boolean | void>;
|
|
19
21
|
usesSegments(): Promise<boolean>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ISplitsCacheSync } from './types';
|
|
2
2
|
import { ISplit } from '../dtos/types';
|
|
3
|
+
import { ISet } from '../utils/lang/sets';
|
|
3
4
|
/**
|
|
4
5
|
* This class provides a skeletal implementation of the ISplitsCacheSync interface
|
|
5
6
|
* to minimize the effort required to implement this interface.
|
|
@@ -34,6 +35,7 @@ export declare abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
|
|
|
34
35
|
* for instance, if the `changeNumber` is old, or if the split is not found (e.g., `/splitchanges` hasn't been fetched yet), or if the storage fails to apply the update.
|
|
35
36
|
*/
|
|
36
37
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean;
|
|
38
|
+
abstract getNamesByFlagSets(flagSets: string[]): ISet<string>;
|
|
37
39
|
}
|
|
38
40
|
/**
|
|
39
41
|
* Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
@@ -3,6 +3,7 @@ export declare class KeyBuilder {
|
|
|
3
3
|
protected readonly prefix: string;
|
|
4
4
|
constructor(prefix?: string);
|
|
5
5
|
buildTrafficTypeKey(trafficType: string): string;
|
|
6
|
+
buildFlagSetKey(flagSet: string): string;
|
|
6
7
|
buildSplitKey(splitName: string): string;
|
|
7
8
|
buildSplitsTillKey(): string;
|
|
8
9
|
isSplitKey(key: string): boolean;
|
|
@@ -2,6 +2,7 @@ import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
|
2
2
|
import { AbstractSplitsCacheSync } from '../AbstractSplitsCacheSync';
|
|
3
3
|
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
4
4
|
import { ILogger } from '../../logger/types';
|
|
5
|
+
import { ISet } from '../../utils/lang/sets';
|
|
5
6
|
/**
|
|
6
7
|
* ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
|
|
7
8
|
*/
|
|
@@ -9,8 +10,8 @@ export declare class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
9
10
|
private readonly log;
|
|
10
11
|
private readonly keys;
|
|
11
12
|
private readonly splitFiltersValidation;
|
|
13
|
+
private readonly flagSetsFilter;
|
|
12
14
|
private hasSync?;
|
|
13
|
-
private cacheReadyButNeedsToFlush;
|
|
14
15
|
private updateNewFilter?;
|
|
15
16
|
/**
|
|
16
17
|
* @param {KeyBuilderCS} keys
|
|
@@ -47,4 +48,8 @@ export declare class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
47
48
|
*/
|
|
48
49
|
private _checkExpiration;
|
|
49
50
|
private _checkFilterQuery;
|
|
51
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>;
|
|
52
|
+
private addToFlagSets;
|
|
53
|
+
private removeFromFlagSets;
|
|
54
|
+
private removeNames;
|
|
50
55
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { ICountsCacheSync } from '../types';
|
|
2
|
+
export declare class CountsCacheInMemory implements ICountsCacheSync {
|
|
3
|
+
private counters;
|
|
4
|
+
/**
|
|
5
|
+
* Add counts.
|
|
6
|
+
*/
|
|
7
|
+
track(metricName: string): boolean;
|
|
8
|
+
/**
|
|
9
|
+
* Clear the collector
|
|
10
|
+
*/
|
|
11
|
+
clear(): void;
|
|
12
|
+
/**
|
|
13
|
+
* Get the collected data, used as payload for posting.
|
|
14
|
+
*/
|
|
15
|
+
state(): Record<string, number>;
|
|
16
|
+
/**
|
|
17
|
+
* Check if the cache is empty.
|
|
18
|
+
*/
|
|
19
|
+
isEmpty(): boolean;
|
|
20
|
+
}
|