@splitsoftware/splitio-commons 1.10.1-rc.4 → 1.12.1-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 -1
- package/cjs/evaluator/index.js +22 -3
- package/cjs/logger/constants.js +4 -2
- package/cjs/logger/messages/warn.js +3 -1
- package/cjs/sdkClient/client.js +1 -1
- package/cjs/storages/KeyBuilder.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +2 -7
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +2 -10
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +2 -3
- package/cjs/storages/pluggable/SplitsCachePluggable.js +24 -8
- package/cjs/storages/pluggable/index.js +1 -1
- package/cjs/utils/lang/sets.js +11 -1
- package/cjs/utils/settingsValidation/index.js +1 -1
- package/cjs/utils/settingsValidation/splitFilters.js +17 -10
- package/esm/evaluator/index.js +23 -4
- package/esm/logger/constants.js +2 -0
- package/esm/logger/messages/warn.js +3 -1
- package/esm/sdkClient/client.js +1 -1
- package/esm/storages/KeyBuilder.js +1 -1
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +3 -8
- package/esm/storages/inMemory/SplitsCacheInMemory.js +3 -11
- package/esm/storages/inRedis/SplitsCacheInRedis.js +2 -3
- package/esm/storages/pluggable/SplitsCachePluggable.js +26 -10
- package/esm/storages/pluggable/index.js +1 -1
- package/esm/utils/lang/sets.js +9 -0
- package/esm/utils/settingsValidation/index.js +1 -1
- package/esm/utils/settingsValidation/splitFilters.js +9 -2
- package/package.json +2 -2
- package/src/evaluator/index.ts +28 -5
- package/src/logger/constants.ts +2 -0
- package/src/logger/messages/warn.ts +9 -7
- package/src/sdkClient/client.ts +1 -1
- package/src/storages/AbstractSplitsCacheAsync.ts +1 -1
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/KeyBuilder.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +4 -10
- package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
- package/src/storages/inRedis/SplitsCacheInRedis.ts +4 -4
- package/src/storages/pluggable/SplitsCachePluggable.ts +32 -10
- package/src/storages/pluggable/index.ts +1 -1
- package/src/storages/types.ts +5 -5
- package/src/types.ts +0 -2
- package/src/utils/lang/sets.ts +9 -1
- package/src/utils/settingsValidation/index.ts +1 -1
- package/src/utils/settingsValidation/splitFilters.ts +13 -6
- package/types/evaluator/index.d.ts +1 -1
- package/types/logger/constants.d.ts +2 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
- package/types/storages/inRedis/SplitsCacheInRedis.d.ts +1 -1
- package/types/storages/pluggable/SplitsCachePluggable.d.ts +7 -6
- package/types/storages/types.d.ts +5 -5
- package/types/types.d.ts +0 -2
- package/types/utils/lang/sets.d.ts +1 -0
- package/types/utils/settingsValidation/splitFilters.d.ts +2 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE } from '../constants';
|
|
1
2
|
import { validateSplits } from '../inputValidation/splits';
|
|
2
3
|
import { ISplitFiltersValidation } from '../../dtos/types';
|
|
3
4
|
import { SplitIO } from '../../types';
|
|
4
5
|
import { ILogger } from '../../logger/types';
|
|
5
|
-
import { 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, WARN_FLAGSET_NOT_CONFIGURED } 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, WARN_FLAGSET_NOT_CONFIGURED } from '../../logger/constants';
|
|
6
7
|
import { objectAssign } from '../lang/objectAssign';
|
|
7
8
|
import { find, uniq } from '../lang';
|
|
8
9
|
|
|
@@ -102,15 +103,15 @@ function queryStringBuilder(groupedFilters: Record<SplitIO.SplitFilterType, stri
|
|
|
102
103
|
function sanitizeFlagSets(log: ILogger, flagSets: string[]) {
|
|
103
104
|
let sanitizedSets = flagSets
|
|
104
105
|
.map(flagSet => {
|
|
105
|
-
if (CAPITAL_LETTERS_REGEX.test(flagSet)){
|
|
106
|
-
log.warn(WARN_SPLITS_FILTER_LOWERCASE_SET,[flagSet]);
|
|
106
|
+
if (CAPITAL_LETTERS_REGEX.test(flagSet)) {
|
|
107
|
+
log.warn(WARN_SPLITS_FILTER_LOWERCASE_SET, [flagSet]);
|
|
107
108
|
flagSet = flagSet.toLowerCase();
|
|
108
109
|
}
|
|
109
110
|
return flagSet;
|
|
110
111
|
})
|
|
111
112
|
.filter(flagSet => {
|
|
112
|
-
if (!VALID_FLAGSET_REGEX.test(flagSet)){
|
|
113
|
-
log.warn(WARN_SPLITS_FILTER_INVALID_SET, [flagSet,VALID_FLAGSET_REGEX,flagSet]);
|
|
113
|
+
if (!VALID_FLAGSET_REGEX.test(flagSet)) {
|
|
114
|
+
log.warn(WARN_SPLITS_FILTER_INVALID_SET, [flagSet, VALID_FLAGSET_REGEX, flagSet]);
|
|
114
115
|
return false;
|
|
115
116
|
}
|
|
116
117
|
if (typeof flagSet !== 'string') return false;
|
|
@@ -128,6 +129,7 @@ function configuredFilter(validFilters: SplitIO.SplitFilter[], filterType: Split
|
|
|
128
129
|
*
|
|
129
130
|
* @param {ILogger} log logger
|
|
130
131
|
* @param {any} maybeSplitFilters split filters configuration param provided by the user
|
|
132
|
+
* @param {string} mode settings mode
|
|
131
133
|
* @returns it returns an object with the following properties:
|
|
132
134
|
* - `validFilters`: the validated `splitFilters` configuration object defined by the user.
|
|
133
135
|
* - `queryString`: the parsed split filter query. it is null if all filters are invalid or all values in filters are invalid.
|
|
@@ -135,7 +137,7 @@ function configuredFilter(validFilters: SplitIO.SplitFilter[], filterType: Split
|
|
|
135
137
|
*
|
|
136
138
|
* @throws Error if the some of the grouped list of values per filter exceeds the max allowed length
|
|
137
139
|
*/
|
|
138
|
-
export function validateSplitFilters(log: ILogger, maybeSplitFilters: any): ISplitFiltersValidation {
|
|
140
|
+
export function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode: string): ISplitFiltersValidation {
|
|
139
141
|
// Validation result schema
|
|
140
142
|
const res = {
|
|
141
143
|
validFilters: [],
|
|
@@ -145,6 +147,11 @@ export function validateSplitFilters(log: ILogger, maybeSplitFilters: any): ISpl
|
|
|
145
147
|
|
|
146
148
|
// do nothing if `splitFilters` param is not a non-empty array or mode is not STANDALONE
|
|
147
149
|
if (!maybeSplitFilters) return res;
|
|
150
|
+
// Warn depending on the mode
|
|
151
|
+
if (mode === CONSUMER_MODE || mode === CONSUMER_PARTIAL_MODE) {
|
|
152
|
+
log.warn(WARN_SPLITS_FILTER_IGNORED);
|
|
153
|
+
return res;
|
|
154
|
+
}
|
|
148
155
|
// Check collection type
|
|
149
156
|
if (!Array.isArray(maybeSplitFilters) || maybeSplitFilters.length === 0) {
|
|
150
157
|
log.warn(WARN_SPLITS_FILTER_EMPTY);
|
|
@@ -5,4 +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>>;
|
|
8
|
+
export declare function evaluateFeaturesByFlagSets(log: ILogger, key: SplitIO.SplitKey, flagSets: string[], attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync, method: string): MaybeThenable<Record<string, IEvaluationResult>>;
|
|
@@ -89,6 +89,7 @@ export declare const WARN_NOT_EXISTENT_SPLIT = 215;
|
|
|
89
89
|
export declare const WARN_LOWERCASE_TRAFFIC_TYPE = 216;
|
|
90
90
|
export declare const WARN_NOT_EXISTENT_TT = 217;
|
|
91
91
|
export declare const WARN_INTEGRATION_INVALID = 218;
|
|
92
|
+
export declare const WARN_SPLITS_FILTER_IGNORED = 219;
|
|
92
93
|
export declare const WARN_SPLITS_FILTER_INVALID = 220;
|
|
93
94
|
export declare const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
94
95
|
export declare const WARN_SDK_KEY = 222;
|
|
@@ -97,6 +98,7 @@ export declare const STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
|
97
98
|
export declare const WARN_SPLITS_FILTER_INVALID_SET = 225;
|
|
98
99
|
export declare const WARN_SPLITS_FILTER_LOWERCASE_SET = 226;
|
|
99
100
|
export declare const WARN_FLAGSET_NOT_CONFIGURED = 227;
|
|
101
|
+
export declare const WARN_FLAGSET_WITHOUT_FLAGS = 228;
|
|
100
102
|
export declare const ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
101
103
|
export declare const ERROR_LOGLEVEL_INVALID = 301;
|
|
102
104
|
export declare const ERROR_CLIENT_LISTENER = 302;
|
|
@@ -15,7 +15,7 @@ export declare abstract class AbstractSplitsCacheAsync implements ISplitsCacheAs
|
|
|
15
15
|
abstract getChangeNumber(): Promise<number>;
|
|
16
16
|
abstract getAll(): Promise<ISplit[]>;
|
|
17
17
|
abstract getSplitNames(): Promise<string[]>;
|
|
18
|
-
abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string
|
|
18
|
+
abstract getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>;
|
|
19
19
|
abstract trafficTypeExists(trafficType: string): Promise<boolean>;
|
|
20
20
|
abstract clear(): Promise<boolean | void>;
|
|
21
21
|
usesSegments(): Promise<boolean>;
|
|
@@ -35,7 +35,7 @@ export declare abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
|
|
|
35
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.
|
|
36
36
|
*/
|
|
37
37
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean;
|
|
38
|
-
abstract getNamesByFlagSets(flagSets: string[]): ISet<string
|
|
38
|
+
abstract getNamesByFlagSets(flagSets: string[]): ISet<string>[];
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
@@ -48,7 +48,7 @@ export declare class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
48
48
|
*/
|
|
49
49
|
private _checkExpiration;
|
|
50
50
|
private _checkFilterQuery;
|
|
51
|
-
getNamesByFlagSets(flagSets: string[]): ISet<string
|
|
51
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>[];
|
|
52
52
|
private addToFlagSets;
|
|
53
53
|
private removeFromFlagSets;
|
|
54
54
|
private removeNames;
|
|
@@ -22,7 +22,7 @@ export declare class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
22
22
|
getSplitNames(): string[];
|
|
23
23
|
trafficTypeExists(trafficType: string): boolean;
|
|
24
24
|
usesSegments(): boolean;
|
|
25
|
-
getNamesByFlagSets(flagSets: string[]): ISet<string
|
|
25
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>[];
|
|
26
26
|
private addToFlagSets;
|
|
27
27
|
private removeFromFlagSets;
|
|
28
28
|
private removeNames;
|
|
@@ -78,7 +78,7 @@ export declare class SplitsCacheInRedis extends AbstractSplitsCacheAsync {
|
|
|
78
78
|
* or rejected if wrapper operation fails.
|
|
79
79
|
* @todo this is a no-op method to be implemented
|
|
80
80
|
*/
|
|
81
|
-
getNamesByFlagSets(): Promise<ISet<string
|
|
81
|
+
getNamesByFlagSets(): Promise<ISet<string>[]>;
|
|
82
82
|
/**
|
|
83
83
|
* Check traffic type existence.
|
|
84
84
|
* The returned promise is resolved with a boolean indicating whether the TT exist or not.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { KeyBuilder } from '../KeyBuilder';
|
|
2
2
|
import { IPluggableStorageWrapper } from '../types';
|
|
3
3
|
import { ILogger } from '../../logger/types';
|
|
4
|
-
import { ISplit } from '../../dtos/types';
|
|
4
|
+
import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
5
5
|
import { AbstractSplitsCacheAsync } from '../AbstractSplitsCacheAsync';
|
|
6
6
|
import { ISet } from '../../utils/lang/sets';
|
|
7
7
|
/**
|
|
@@ -11,15 +11,17 @@ export declare class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
11
11
|
private readonly log;
|
|
12
12
|
private readonly keys;
|
|
13
13
|
private readonly wrapper;
|
|
14
|
+
private readonly flagSetsFilter;
|
|
14
15
|
/**
|
|
15
16
|
* Create a SplitsCache that uses a storage wrapper.
|
|
16
17
|
* @param log Logger instance.
|
|
17
18
|
* @param keys Key builder.
|
|
18
19
|
* @param wrapper Adapted wrapper storage.
|
|
19
20
|
*/
|
|
20
|
-
constructor(log: ILogger, keys: KeyBuilder, wrapper: IPluggableStorageWrapper);
|
|
21
|
+
constructor(log: ILogger, keys: KeyBuilder, wrapper: IPluggableStorageWrapper, splitFiltersValidation?: ISplitFiltersValidation);
|
|
21
22
|
private _decrementCounts;
|
|
22
23
|
private _incrementCounts;
|
|
24
|
+
private _updateFlagSets;
|
|
23
25
|
/**
|
|
24
26
|
* Add a given split.
|
|
25
27
|
* The returned promise is resolved when the operation success
|
|
@@ -37,7 +39,7 @@ export declare class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
37
39
|
* The returned promise is resolved when the operation success, with a boolean indicating if the split existed or not.
|
|
38
40
|
* or rejected if it fails (e.g., wrapper operation fails).
|
|
39
41
|
*/
|
|
40
|
-
removeSplit(name: string): Promise<boolean
|
|
42
|
+
removeSplit(name: string): Promise<boolean>;
|
|
41
43
|
/**
|
|
42
44
|
* Remove a list of splits.
|
|
43
45
|
* The returned promise is resolved when the operation success, with a boolean array indicating if the splits existed or not.
|
|
@@ -71,10 +73,9 @@ export declare class SplitsCachePluggable extends AbstractSplitsCacheAsync {
|
|
|
71
73
|
/**
|
|
72
74
|
* Get list of split names related to a given flag set names list.
|
|
73
75
|
* The returned promise is resolved with the list of split names,
|
|
74
|
-
* or rejected if wrapper operation fails.
|
|
75
|
-
* @todo this is a no-op method to be implemented
|
|
76
|
+
* or rejected if any wrapper operation fails.
|
|
76
77
|
*/
|
|
77
|
-
getNamesByFlagSets(): Promise<ISet<string
|
|
78
|
+
getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>;
|
|
78
79
|
/**
|
|
79
80
|
* Check traffic type existence.
|
|
80
81
|
* The returned promise is resolved with a boolean indicating whether the TT exist or not.
|
|
@@ -41,10 +41,10 @@ export interface IPluggableStorageWrapper {
|
|
|
41
41
|
*
|
|
42
42
|
* @function del
|
|
43
43
|
* @param {string} key Item to delete
|
|
44
|
-
* @returns {Promise<
|
|
44
|
+
* @returns {Promise<boolean>} A promise that resolves if the operation success, whether the key existed and was removed (resolves with true) or it didn't exist (resolves with false).
|
|
45
45
|
* The promise rejects if the operation fails, for example, if there is a connection error.
|
|
46
46
|
*/
|
|
47
|
-
del: (key: string) => Promise<boolean
|
|
47
|
+
del: (key: string) => Promise<boolean>;
|
|
48
48
|
/**
|
|
49
49
|
* Returns all keys matching the given prefix.
|
|
50
50
|
*
|
|
@@ -193,7 +193,7 @@ export interface ISplitsCacheBase {
|
|
|
193
193
|
clear(): MaybeThenable<boolean | void>;
|
|
194
194
|
checkCache(): MaybeThenable<boolean>;
|
|
195
195
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): MaybeThenable<boolean>;
|
|
196
|
-
getNamesByFlagSets(flagSets: string[]): MaybeThenable<ISet<string
|
|
196
|
+
getNamesByFlagSets(flagSets: string[]): MaybeThenable<ISet<string>[]>;
|
|
197
197
|
}
|
|
198
198
|
export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
199
199
|
addSplits(entries: [string, ISplit][]): boolean[];
|
|
@@ -209,7 +209,7 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
209
209
|
clear(): void;
|
|
210
210
|
checkCache(): boolean;
|
|
211
211
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean;
|
|
212
|
-
getNamesByFlagSets(flagSets: string[]): ISet<string
|
|
212
|
+
getNamesByFlagSets(flagSets: string[]): ISet<string>[];
|
|
213
213
|
}
|
|
214
214
|
export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
215
215
|
addSplits(entries: [string, ISplit][]): Promise<boolean[] | void>;
|
|
@@ -225,7 +225,7 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
225
225
|
clear(): Promise<boolean | void>;
|
|
226
226
|
checkCache(): Promise<boolean>;
|
|
227
227
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>;
|
|
228
|
-
getNamesByFlagSets(flagSets: string[]): Promise<ISet<string
|
|
228
|
+
getNamesByFlagSets(flagSets: string[]): Promise<ISet<string>[]>;
|
|
229
229
|
}
|
|
230
230
|
/** Segments cache */
|
|
231
231
|
export interface ISegmentsCacheBase {
|
package/types/types.d.ts
CHANGED
|
@@ -191,8 +191,6 @@ interface ISharedSettings {
|
|
|
191
191
|
* List of feature flag filters. These filters are used to fetch a subset of the feature flag definitions in your environment, in order to reduce the delay of the SDK to be ready.
|
|
192
192
|
* This configuration is only meaningful when the SDK is working in "standalone" mode.
|
|
193
193
|
*
|
|
194
|
-
* At the moment, only one type of feature flag filter is supported: by name.
|
|
195
|
-
*
|
|
196
194
|
* Example:
|
|
197
195
|
* `splitFilter: [
|
|
198
196
|
* { type: 'byName', values: ['my_feature_flag_1', 'my_feature_flag_2'] }, // will fetch feature flags named 'my_feature_flag_1' and 'my_feature_flag_2'
|
|
@@ -58,4 +58,5 @@ interface ISetConstructor {
|
|
|
58
58
|
export declare function __getSetConstructor(): ISetConstructor;
|
|
59
59
|
export declare const _Set: ISetConstructor;
|
|
60
60
|
export declare function returnSetsUnion<T>(set: ISet<T>, set2: ISet<T>): ISet<T>;
|
|
61
|
+
export declare function returnListDifference<T>(list?: T[], list2?: T[]): T[];
|
|
61
62
|
export {};
|
|
@@ -5,6 +5,7 @@ import { ILogger } from '../../logger/types';
|
|
|
5
5
|
*
|
|
6
6
|
* @param {ILogger} log logger
|
|
7
7
|
* @param {any} maybeSplitFilters split filters configuration param provided by the user
|
|
8
|
+
* @param {string} mode settings mode
|
|
8
9
|
* @returns it returns an object with the following properties:
|
|
9
10
|
* - `validFilters`: the validated `splitFilters` configuration object defined by the user.
|
|
10
11
|
* - `queryString`: the parsed split filter query. it is null if all filters are invalid or all values in filters are invalid.
|
|
@@ -12,5 +13,5 @@ import { ILogger } from '../../logger/types';
|
|
|
12
13
|
*
|
|
13
14
|
* @throws Error if the some of the grouped list of values per filter exceeds the max allowed length
|
|
14
15
|
*/
|
|
15
|
-
export declare function validateSplitFilters(log: ILogger, maybeSplitFilters: any): ISplitFiltersValidation;
|
|
16
|
+
export declare function validateSplitFilters(log: ILogger, maybeSplitFilters: any, mode: string): ISplitFiltersValidation;
|
|
16
17
|
export declare function flagSetsAreValid(log: ILogger, method: string, flagSets: string[], flagSetsInConfig: string[]): string[];
|