@splitsoftware/splitio-commons 2.7.9-rc.2 → 2.8.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 +1 -1
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +48 -39
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +3 -8
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/utils/settingsValidation/index.js +3 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +44 -38
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +3 -8
- package/esm/sdkFactory/index.js +1 -1
- package/esm/utils/settingsValidation/index.js +3 -0
- package/package.json +1 -1
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +50 -44
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +2 -9
- package/src/sdkFactory/index.ts +1 -1
- package/src/utils/settingsValidation/index.ts +4 -0
- package/types/splitio.d.ts +13 -1
package/CHANGES.txt
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
2.8.0 (October
|
|
1
|
+
2.8.0 (October 30, 2025)
|
|
2
2
|
- Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.
|
|
3
3
|
- Added `client.getStatus()` method to retrieve the client readiness status properties (`isReady`, `isReadyFromCache`, etc).
|
|
4
4
|
- Added `client.whenReady()` and `client.whenReadyFromCache()` methods to replace the deprecated `client.ready()` method, which has an issue causing the returned promise to hang when using async/await syntax if it was rejected.
|
|
@@ -1,51 +1,60 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.sanitizeFallbacks = exports.isValidTreatment = exports.isValidFlagName = void 0;
|
|
4
4
|
var lang_1 = require("../../../utils/lang");
|
|
5
5
|
var FallbackDiscardReason;
|
|
6
6
|
(function (FallbackDiscardReason) {
|
|
7
7
|
FallbackDiscardReason["FlagName"] = "Invalid flag name (max 100 chars, no spaces)";
|
|
8
8
|
FallbackDiscardReason["Treatment"] = "Invalid treatment (max 100 chars and must match pattern)";
|
|
9
9
|
})(FallbackDiscardReason || (FallbackDiscardReason = {}));
|
|
10
|
-
var
|
|
11
|
-
|
|
10
|
+
var TREATMENT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
|
|
11
|
+
function isValidFlagName(name) {
|
|
12
|
+
return name.length <= 100 && !name.includes(' ');
|
|
13
|
+
}
|
|
14
|
+
exports.isValidFlagName = isValidFlagName;
|
|
15
|
+
function isValidTreatment(t) {
|
|
16
|
+
var treatment = (0, lang_1.isObject)(t) ? t.treatment : t;
|
|
17
|
+
if (!(0, lang_1.isString)(treatment) || treatment.length > 100) {
|
|
18
|
+
return false;
|
|
12
19
|
}
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
return TREATMENT_PATTERN.test(treatment);
|
|
21
|
+
}
|
|
22
|
+
exports.isValidTreatment = isValidTreatment;
|
|
23
|
+
function sanitizeGlobal(logger, treatment) {
|
|
24
|
+
if (treatment === undefined)
|
|
25
|
+
return undefined;
|
|
26
|
+
if (!isValidTreatment(treatment)) {
|
|
27
|
+
logger.error("Fallback treatments - Discarded fallback: " + FallbackDiscardReason.Treatment);
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
return treatment;
|
|
31
|
+
}
|
|
32
|
+
function sanitizeByFlag(logger, byFlagFallbacks) {
|
|
33
|
+
var sanitizedByFlag = {};
|
|
34
|
+
if (!(0, lang_1.isObject)(byFlagFallbacks))
|
|
35
|
+
return sanitizedByFlag;
|
|
36
|
+
Object.keys(byFlagFallbacks).forEach(function (flag) {
|
|
37
|
+
var t = byFlagFallbacks[flag];
|
|
38
|
+
if (!isValidFlagName(flag)) {
|
|
39
|
+
logger.error("Fallback treatments - Discarded flag '" + flag + "': " + FallbackDiscardReason.FlagName);
|
|
40
|
+
return;
|
|
20
41
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
if (!this.isValidTreatment(treatment)) {
|
|
25
|
-
logger.error("Fallback treatments - Discarded fallback: " + FallbackDiscardReason.Treatment);
|
|
26
|
-
return undefined;
|
|
42
|
+
if (!isValidTreatment(t)) {
|
|
43
|
+
logger.error("Fallback treatments - Discarded treatment for flag '" + flag + "': " + FallbackDiscardReason.Treatment);
|
|
44
|
+
return;
|
|
27
45
|
}
|
|
28
|
-
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (!_this.isValidTreatment(t)) {
|
|
41
|
-
logger.error("Fallback treatments - Discarded treatment for flag '" + flag + "': " + FallbackDiscardReason.Treatment);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
sanitizedByFlag[flag] = t;
|
|
45
|
-
});
|
|
46
|
-
return sanitizedByFlag;
|
|
46
|
+
sanitizedByFlag[flag] = t;
|
|
47
|
+
});
|
|
48
|
+
return sanitizedByFlag;
|
|
49
|
+
}
|
|
50
|
+
function sanitizeFallbacks(logger, fallbacks) {
|
|
51
|
+
if (!(0, lang_1.isObject)(fallbacks)) {
|
|
52
|
+
logger.error('Fallback treatments - Discarded configuration: it must be an object with optional `global` and `byFlag` properties');
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
global: sanitizeGlobal(logger, fallbacks.global),
|
|
57
|
+
byFlag: sanitizeByFlag(logger, fallbacks.byFlag)
|
|
47
58
|
};
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}());
|
|
51
|
-
exports.FallbacksSanitizer = FallbacksSanitizer;
|
|
59
|
+
}
|
|
60
|
+
exports.sanitizeFallbacks = sanitizeFallbacks;
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.FallbackTreatmentsCalculator = exports.FALLBACK_PREFIX = void 0;
|
|
4
|
-
var fallbackSanitizer_1 = require("./fallbackSanitizer");
|
|
5
4
|
var constants_1 = require("../../utils/constants");
|
|
6
5
|
var lang_1 = require("../../utils/lang");
|
|
7
6
|
exports.FALLBACK_PREFIX = 'fallback - ';
|
|
8
7
|
var FallbackTreatmentsCalculator = /** @class */ (function () {
|
|
9
|
-
function FallbackTreatmentsCalculator(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
this.fallbacks = {
|
|
13
|
-
global: sanitizedGlobal,
|
|
14
|
-
byFlag: sanitizedByFlag
|
|
15
|
-
};
|
|
8
|
+
function FallbackTreatmentsCalculator(fallbacks) {
|
|
9
|
+
if (fallbacks === void 0) { fallbacks = {}; }
|
|
10
|
+
this.fallbacks = fallbacks;
|
|
16
11
|
}
|
|
17
12
|
FallbackTreatmentsCalculator.prototype.resolve = function (flagName, label) {
|
|
18
13
|
var _a;
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -52,7 +52,7 @@ function sdkFactory(params) {
|
|
|
52
52
|
readiness.splits.emit(constants_2.SDK_SPLITS_CACHE_LOADED);
|
|
53
53
|
}
|
|
54
54
|
});
|
|
55
|
-
var fallbackTreatmentsCalculator = new fallbackTreatmentsCalculator_1.FallbackTreatmentsCalculator(settings.
|
|
55
|
+
var fallbackTreatmentsCalculator = new fallbackTreatmentsCalculator_1.FallbackTreatmentsCalculator(settings.fallbackTreatments);
|
|
56
56
|
if (initialRolloutPlan) {
|
|
57
57
|
(0, setRolloutPlan_1.setRolloutPlan)(log, initialRolloutPlan, storage, key && (0, key_1.getMatching)(key));
|
|
58
58
|
if (storage.splits.getChangeNumber() > -1)
|
|
@@ -9,6 +9,7 @@ var impressionsMode_1 = require("./impressionsMode");
|
|
|
9
9
|
var key_1 = require("../inputValidation/key");
|
|
10
10
|
var constants_2 = require("../../logger/constants");
|
|
11
11
|
var setRolloutPlan_1 = require("../../storages/setRolloutPlan");
|
|
12
|
+
var fallbackSanitizer_1 = require("../../evaluator/fallbackTreatmentsCalculator/fallbackSanitizer");
|
|
12
13
|
// Exported for telemetry
|
|
13
14
|
exports.base = {
|
|
14
15
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
@@ -183,6 +184,8 @@ function settingsValidation(config, validationParams) {
|
|
|
183
184
|
// ensure a valid user consent value
|
|
184
185
|
// @ts-ignore, modify readonly prop
|
|
185
186
|
withDefaults.userConsent = consent ? consent(withDefaults) : undefined;
|
|
187
|
+
// @ts-ignore, modify readonly prop
|
|
188
|
+
withDefaults.fallbackTreatments = withDefaults.fallbackTreatments ? (0, fallbackSanitizer_1.sanitizeFallbacks)(log, withDefaults.fallbackTreatments) : undefined;
|
|
186
189
|
return withDefaults;
|
|
187
190
|
}
|
|
188
191
|
exports.settingsValidation = settingsValidation;
|
|
@@ -4,45 +4,51 @@ var FallbackDiscardReason;
|
|
|
4
4
|
FallbackDiscardReason["FlagName"] = "Invalid flag name (max 100 chars, no spaces)";
|
|
5
5
|
FallbackDiscardReason["Treatment"] = "Invalid treatment (max 100 chars and must match pattern)";
|
|
6
6
|
})(FallbackDiscardReason || (FallbackDiscardReason = {}));
|
|
7
|
-
var
|
|
8
|
-
|
|
7
|
+
var TREATMENT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
|
|
8
|
+
export function isValidFlagName(name) {
|
|
9
|
+
return name.length <= 100 && !name.includes(' ');
|
|
10
|
+
}
|
|
11
|
+
export function isValidTreatment(t) {
|
|
12
|
+
var treatment = isObject(t) ? t.treatment : t;
|
|
13
|
+
if (!isString(treatment) || treatment.length > 100) {
|
|
14
|
+
return false;
|
|
9
15
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
16
|
+
return TREATMENT_PATTERN.test(treatment);
|
|
17
|
+
}
|
|
18
|
+
function sanitizeGlobal(logger, treatment) {
|
|
19
|
+
if (treatment === undefined)
|
|
20
|
+
return undefined;
|
|
21
|
+
if (!isValidTreatment(treatment)) {
|
|
22
|
+
logger.error("Fallback treatments - Discarded fallback: " + FallbackDiscardReason.Treatment);
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
return treatment;
|
|
26
|
+
}
|
|
27
|
+
function sanitizeByFlag(logger, byFlagFallbacks) {
|
|
28
|
+
var sanitizedByFlag = {};
|
|
29
|
+
if (!isObject(byFlagFallbacks))
|
|
30
|
+
return sanitizedByFlag;
|
|
31
|
+
Object.keys(byFlagFallbacks).forEach(function (flag) {
|
|
32
|
+
var t = byFlagFallbacks[flag];
|
|
33
|
+
if (!isValidFlagName(flag)) {
|
|
34
|
+
logger.error("Fallback treatments - Discarded flag '" + flag + "': " + FallbackDiscardReason.FlagName);
|
|
35
|
+
return;
|
|
17
36
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
if (!this.isValidTreatment(treatment)) {
|
|
22
|
-
logger.error("Fallback treatments - Discarded fallback: " + FallbackDiscardReason.Treatment);
|
|
23
|
-
return undefined;
|
|
37
|
+
if (!isValidTreatment(t)) {
|
|
38
|
+
logger.error("Fallback treatments - Discarded treatment for flag '" + flag + "': " + FallbackDiscardReason.Treatment);
|
|
39
|
+
return;
|
|
24
40
|
}
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (!_this.isValidTreatment(t)) {
|
|
38
|
-
logger.error("Fallback treatments - Discarded treatment for flag '" + flag + "': " + FallbackDiscardReason.Treatment);
|
|
39
|
-
return;
|
|
40
|
-
}
|
|
41
|
-
sanitizedByFlag[flag] = t;
|
|
42
|
-
});
|
|
43
|
-
return sanitizedByFlag;
|
|
41
|
+
sanitizedByFlag[flag] = t;
|
|
42
|
+
});
|
|
43
|
+
return sanitizedByFlag;
|
|
44
|
+
}
|
|
45
|
+
export function sanitizeFallbacks(logger, fallbacks) {
|
|
46
|
+
if (!isObject(fallbacks)) {
|
|
47
|
+
logger.error('Fallback treatments - Discarded configuration: it must be an object with optional `global` and `byFlag` properties');
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
global: sanitizeGlobal(logger, fallbacks.global),
|
|
52
|
+
byFlag: sanitizeByFlag(logger, fallbacks.byFlag)
|
|
44
53
|
};
|
|
45
|
-
|
|
46
|
-
return FallbacksSanitizer;
|
|
47
|
-
}());
|
|
48
|
-
export { FallbacksSanitizer };
|
|
54
|
+
}
|
|
@@ -1,15 +1,10 @@
|
|
|
1
|
-
import { FallbacksSanitizer } from './fallbackSanitizer';
|
|
2
1
|
import { CONTROL } from '../../utils/constants';
|
|
3
2
|
import { isString } from '../../utils/lang';
|
|
4
3
|
export var FALLBACK_PREFIX = 'fallback - ';
|
|
5
4
|
var FallbackTreatmentsCalculator = /** @class */ (function () {
|
|
6
|
-
function FallbackTreatmentsCalculator(
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
this.fallbacks = {
|
|
10
|
-
global: sanitizedGlobal,
|
|
11
|
-
byFlag: sanitizedByFlag
|
|
12
|
-
};
|
|
5
|
+
function FallbackTreatmentsCalculator(fallbacks) {
|
|
6
|
+
if (fallbacks === void 0) { fallbacks = {}; }
|
|
7
|
+
this.fallbacks = fallbacks;
|
|
13
8
|
}
|
|
14
9
|
FallbackTreatmentsCalculator.prototype.resolve = function (flagName, label) {
|
|
15
10
|
var _a;
|
package/esm/sdkFactory/index.js
CHANGED
|
@@ -49,7 +49,7 @@ export function sdkFactory(params) {
|
|
|
49
49
|
readiness.splits.emit(SDK_SPLITS_CACHE_LOADED);
|
|
50
50
|
}
|
|
51
51
|
});
|
|
52
|
-
var fallbackTreatmentsCalculator = new FallbackTreatmentsCalculator(settings.
|
|
52
|
+
var fallbackTreatmentsCalculator = new FallbackTreatmentsCalculator(settings.fallbackTreatments);
|
|
53
53
|
if (initialRolloutPlan) {
|
|
54
54
|
setRolloutPlan(log, initialRolloutPlan, storage, key && getMatching(key));
|
|
55
55
|
if (storage.splits.getChangeNumber() > -1)
|
|
@@ -6,6 +6,7 @@ import { validImpressionsMode } from './impressionsMode';
|
|
|
6
6
|
import { validateKey } from '../inputValidation/key';
|
|
7
7
|
import { ERROR_MIN_CONFIG_PARAM, LOG_PREFIX_CLIENT_INSTANTIATION } from '../../logger/constants';
|
|
8
8
|
import { validateRolloutPlan } from '../../storages/setRolloutPlan';
|
|
9
|
+
import { sanitizeFallbacks } from '../../evaluator/fallbackTreatmentsCalculator/fallbackSanitizer';
|
|
9
10
|
// Exported for telemetry
|
|
10
11
|
export var base = {
|
|
11
12
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
@@ -180,5 +181,7 @@ export function settingsValidation(config, validationParams) {
|
|
|
180
181
|
// ensure a valid user consent value
|
|
181
182
|
// @ts-ignore, modify readonly prop
|
|
182
183
|
withDefaults.userConsent = consent ? consent(withDefaults) : undefined;
|
|
184
|
+
// @ts-ignore, modify readonly prop
|
|
185
|
+
withDefaults.fallbackTreatments = withDefaults.fallbackTreatments ? sanitizeFallbacks(log, withDefaults.fallbackTreatments) : undefined;
|
|
183
186
|
return withDefaults;
|
|
184
187
|
}
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Treatment, TreatmentWithConfig } from '../../../../types/splitio';
|
|
1
|
+
import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '../../../../types/splitio';
|
|
2
2
|
import { ILogger } from '../../../logger/types';
|
|
3
3
|
import { isObject, isString } from '../../../utils/lang';
|
|
4
4
|
|
|
@@ -7,59 +7,65 @@ enum FallbackDiscardReason {
|
|
|
7
7
|
Treatment = 'Invalid treatment (max 100 chars and must match pattern)',
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
const TREATMENT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
return name.length <= 100 && !name.includes(' ');
|
|
16
|
-
}
|
|
12
|
+
export function isValidFlagName(name: string): boolean {
|
|
13
|
+
return name.length <= 100 && !name.includes(' ');
|
|
14
|
+
}
|
|
17
15
|
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
export function isValidTreatment(t?: Treatment | TreatmentWithConfig): boolean {
|
|
17
|
+
const treatment = isObject(t) ? (t as TreatmentWithConfig).treatment : t;
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
}
|
|
24
|
-
return FallbacksSanitizer.pattern.test(treatment);
|
|
19
|
+
if (!isString(treatment) || treatment.length > 100) {
|
|
20
|
+
return false;
|
|
25
21
|
}
|
|
22
|
+
return TREATMENT_PATTERN.test(treatment);
|
|
23
|
+
}
|
|
26
24
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
return undefined;
|
|
33
|
-
}
|
|
34
|
-
return treatment;
|
|
25
|
+
function sanitizeGlobal(logger: ILogger, treatment?: Treatment | TreatmentWithConfig): Treatment | TreatmentWithConfig | undefined {
|
|
26
|
+
if (treatment === undefined) return undefined;
|
|
27
|
+
if (!isValidTreatment(treatment)) {
|
|
28
|
+
logger.error(`Fallback treatments - Discarded fallback: ${FallbackDiscardReason.Treatment}`);
|
|
29
|
+
return undefined;
|
|
35
30
|
}
|
|
31
|
+
return treatment;
|
|
32
|
+
}
|
|
36
33
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
34
|
+
function sanitizeByFlag(
|
|
35
|
+
logger: ILogger,
|
|
36
|
+
byFlagFallbacks?: Record<string, Treatment | TreatmentWithConfig>
|
|
37
|
+
): Record<string, Treatment | TreatmentWithConfig> {
|
|
38
|
+
const sanitizedByFlag: Record<string, Treatment | TreatmentWithConfig> = {};
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
entries.forEach((flag) => {
|
|
45
|
-
const t = byFlagFallbacks[flag];
|
|
46
|
-
if (!this.isValidFlagName(flag)) {
|
|
47
|
-
logger.error(
|
|
48
|
-
`Fallback treatments - Discarded flag '${flag}': ${FallbackDiscardReason.FlagName}`
|
|
49
|
-
);
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
40
|
+
if (!isObject(byFlagFallbacks)) return sanitizedByFlag;
|
|
52
41
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
`Fallback treatments - Discarded treatment for flag '${flag}': ${FallbackDiscardReason.Treatment}`
|
|
56
|
-
);
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
42
|
+
Object.keys(byFlagFallbacks!).forEach((flag) => {
|
|
43
|
+
const t = byFlagFallbacks![flag];
|
|
59
44
|
|
|
60
|
-
|
|
61
|
-
|
|
45
|
+
if (!isValidFlagName(flag)) {
|
|
46
|
+
logger.error(`Fallback treatments - Discarded flag '${flag}': ${FallbackDiscardReason.FlagName}`);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (!isValidTreatment(t)) {
|
|
51
|
+
logger.error(`Fallback treatments - Discarded treatment for flag '${flag}': ${FallbackDiscardReason.Treatment}`);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
sanitizedByFlag[flag] = t;
|
|
56
|
+
});
|
|
62
57
|
|
|
63
|
-
|
|
58
|
+
return sanitizedByFlag;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function sanitizeFallbacks(logger: ILogger, fallbacks: FallbackTreatmentConfiguration): FallbackTreatmentConfiguration | undefined {
|
|
62
|
+
if (!isObject(fallbacks)) {
|
|
63
|
+
logger.error('Fallback treatments - Discarded configuration: it must be an object with optional `global` and `byFlag` properties');
|
|
64
|
+
return;
|
|
64
65
|
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
global: sanitizeGlobal(logger, fallbacks.global),
|
|
69
|
+
byFlag: sanitizeByFlag(logger, fallbacks.byFlag)
|
|
70
|
+
};
|
|
65
71
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '../../../types/splitio';
|
|
2
|
-
import { FallbacksSanitizer } from './fallbackSanitizer';
|
|
3
2
|
import { CONTROL } from '../../utils/constants';
|
|
4
3
|
import { isString } from '../../utils/lang';
|
|
5
|
-
import { ILogger } from '../../logger/types';
|
|
6
4
|
|
|
7
5
|
export type IFallbackTreatmentsCalculator = {
|
|
8
6
|
resolve(flagName: string, label: string): TreatmentWithConfig & { label: string };
|
|
@@ -13,13 +11,8 @@ export const FALLBACK_PREFIX = 'fallback - ';
|
|
|
13
11
|
export class FallbackTreatmentsCalculator implements IFallbackTreatmentsCalculator {
|
|
14
12
|
private readonly fallbacks: FallbackTreatmentConfiguration;
|
|
15
13
|
|
|
16
|
-
constructor(
|
|
17
|
-
|
|
18
|
-
const sanitizedByFlag = fallbacks?.byFlag ? FallbacksSanitizer.sanitizeByFlag(logger, fallbacks.byFlag) : {};
|
|
19
|
-
this.fallbacks = {
|
|
20
|
-
global: sanitizedGlobal,
|
|
21
|
-
byFlag: sanitizedByFlag
|
|
22
|
-
};
|
|
14
|
+
constructor(fallbacks: FallbackTreatmentConfiguration = {}) {
|
|
15
|
+
this.fallbacks = fallbacks;
|
|
23
16
|
}
|
|
24
17
|
|
|
25
18
|
resolve(flagName: string, label: string): TreatmentWithConfig & { label: string } {
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -61,7 +61,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ISDK | SplitIO.IA
|
|
|
61
61
|
}
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
const fallbackTreatmentsCalculator = new FallbackTreatmentsCalculator(settings.
|
|
64
|
+
const fallbackTreatmentsCalculator = new FallbackTreatmentsCalculator(settings.fallbackTreatments);
|
|
65
65
|
|
|
66
66
|
if (initialRolloutPlan) {
|
|
67
67
|
setRolloutPlan(log, initialRolloutPlan, storage as IStorageSync, key && getMatching(key));
|
|
@@ -8,6 +8,7 @@ import { ISettings } from '../../types';
|
|
|
8
8
|
import { validateKey } from '../inputValidation/key';
|
|
9
9
|
import { ERROR_MIN_CONFIG_PARAM, LOG_PREFIX_CLIENT_INSTANTIATION } from '../../logger/constants';
|
|
10
10
|
import { validateRolloutPlan } from '../../storages/setRolloutPlan';
|
|
11
|
+
import { sanitizeFallbacks } from '../../evaluator/fallbackTreatmentsCalculator/fallbackSanitizer';
|
|
11
12
|
|
|
12
13
|
// Exported for telemetry
|
|
13
14
|
export const base = {
|
|
@@ -207,5 +208,8 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
207
208
|
// @ts-ignore, modify readonly prop
|
|
208
209
|
withDefaults.userConsent = consent ? consent(withDefaults) : undefined;
|
|
209
210
|
|
|
211
|
+
// @ts-ignore, modify readonly prop
|
|
212
|
+
withDefaults.fallbackTreatments = withDefaults.fallbackTreatments ? sanitizeFallbacks(log, withDefaults.fallbackTreatments) : undefined;
|
|
213
|
+
|
|
210
214
|
return withDefaults;
|
|
211
215
|
}
|
package/types/splitio.d.ts
CHANGED
|
@@ -96,6 +96,12 @@ interface ISharedSettings {
|
|
|
96
96
|
* Set together with `debug` option to `true` or a log level string to enable logging.
|
|
97
97
|
*/
|
|
98
98
|
logger?: SplitIO.Logger;
|
|
99
|
+
/**
|
|
100
|
+
* Fallback treatments to be used when the SDK is not ready or the flag is not found.
|
|
101
|
+
*
|
|
102
|
+
* @defaultValue `undefined`
|
|
103
|
+
*/
|
|
104
|
+
fallbackTreatments?: SplitIO.FallbackTreatmentConfiguration;
|
|
99
105
|
}
|
|
100
106
|
/**
|
|
101
107
|
* Common settings properties for SDKs with synchronous API (standalone and localhost modes).
|
|
@@ -713,7 +719,7 @@ declare namespace SplitIO {
|
|
|
713
719
|
isReadyFromCache: boolean;
|
|
714
720
|
|
|
715
721
|
/**
|
|
716
|
-
* `isTimedout` indicates if the client has triggered an `SDK_READY_TIMED_OUT` event and is not ready
|
|
722
|
+
* `isTimedout` indicates if the client has triggered an `SDK_READY_TIMED_OUT` event and is not ready.
|
|
717
723
|
* In other words, `isTimedout` is equivalent to `hasTimedout && !isReady`.
|
|
718
724
|
*/
|
|
719
725
|
isTimedout: boolean;
|
|
@@ -1303,7 +1309,13 @@ declare namespace SplitIO {
|
|
|
1303
1309
|
* Fallback treatments to be used when the SDK is not ready or the flag is not found.
|
|
1304
1310
|
*/
|
|
1305
1311
|
type FallbackTreatmentConfiguration = {
|
|
1312
|
+
/**
|
|
1313
|
+
* Fallback treatment for all flags.
|
|
1314
|
+
*/
|
|
1306
1315
|
global?: Treatment | TreatmentWithConfig,
|
|
1316
|
+
/**
|
|
1317
|
+
* Fallback treatments for specific flags. It takes precedence over the global fallback treatment.
|
|
1318
|
+
*/
|
|
1307
1319
|
byFlag?: {
|
|
1308
1320
|
[featureFlagName: string]: Treatment | TreatmentWithConfig
|
|
1309
1321
|
}
|