-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.ts
More file actions
114 lines (99 loc) · 4.39 KB
/
Copy pathindex.ts
File metadata and controls
114 lines (99 loc) · 4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { objectAssign } from '../utils/lang/objectAssign';
import { thenable } from '../utils/promise/thenable';
import { find } from '../utils/lang';
import { validateSplit, validateSplitExistence, validateIfOperational } from '../utils/inputValidation';
import { ISplitsCacheAsync, ISplitsCacheSync } from '../storages/types';
import { ISdkReadinessManager } from '../readiness/types';
import { ISplit } from '../dtos/types';
import { ISettings } from '../types';
import SplitIO from '../../types/splitio';
import { isConsumerMode } from '../utils/settingsValidation/mode';
import { SPLIT_FN_LABEL, SPLITS_FN_LABEL, NAMES_FN_LABEL } from '../utils/constants';
function collectTreatments(splitObject: ISplit) {
const conditions = splitObject.conditions;
// Rollout conditions are supposed to have the entire partitions list, so we find the first one.
let allTreatmentsCondition = find(conditions, (cond) => cond.conditionType === 'ROLLOUT');
// Localstorage mode could fall into a no rollout conditions state. Take the first condition in that case.
if (!allTreatmentsCondition) allTreatmentsCondition = conditions[0];
// Then extract the treatments from the partitions
return allTreatmentsCondition ? allTreatmentsCondition.partitions!.map(v => v.treatment) : [];
}
function objectToView(splitObject: ISplit | null): SplitIO.SplitView | null {
if (!splitObject) return null;
return {
name: splitObject.name,
trafficType: splitObject.trafficTypeName,
killed: splitObject.killed,
changeNumber: splitObject.changeNumber || 0,
treatments: collectTreatments(splitObject),
configs: splitObject.configurations || {},
sets: splitObject.sets || [],
defaultTreatment: splitObject.defaultTreatment,
impressionsDisabled: splitObject.impressionsDisabled === true,
prerequisites: (splitObject.prerequisites || []).map(p => ({ flagName: p.n, treatments: p.ts })),
};
}
function objectsToViews(splitObjects: ISplit[]) {
let views: SplitIO.SplitView[] = [];
splitObjects.forEach(split => {
const view = objectToView(split);
if (view) views.push(view);
});
return views;
}
export function sdkManagerFactory<TSplitCache extends ISplitsCacheSync | ISplitsCacheAsync>(
settings: Pick<ISettings, 'log' | 'mode'>,
splits: TSplitCache,
{ readinessManager, sdkStatus }: ISdkReadinessManager,
): TSplitCache extends ISplitsCacheAsync ? SplitIO.IAsyncManager : SplitIO.IManager {
const { log, mode } = settings;
const isAsync = isConsumerMode(mode);
return objectAssign(
// Proto-linkage of the readiness Event Emitter
Object.create(sdkStatus),
{
/**
* Get the feature flag object corresponding to the given feature flag name if valid
*/
split(featureFlagName: string) {
const splitName = validateSplit(log, featureFlagName, SPLIT_FN_LABEL);
if (!validateIfOperational(log, readinessManager, SPLIT_FN_LABEL) || !splitName) {
return isAsync ? Promise.resolve(null) : null;
}
const split = splits.getSplit(splitName);
if (thenable(split)) {
return split.catch(() => null).then(result => { // handle possible rejections when using pluggable storage
validateSplitExistence(log, readinessManager, splitName, result, SPLIT_FN_LABEL);
return objectToView(result);
});
}
validateSplitExistence(log, readinessManager, splitName, split, SPLIT_FN_LABEL);
return objectToView(split);
},
/**
* Get the feature flag objects present on the factory storage
*/
splits() {
if (!validateIfOperational(log, readinessManager, SPLITS_FN_LABEL)) {
return isAsync ? Promise.resolve([]) : [];
}
const currentSplits = splits.getAll();
return thenable(currentSplits) ?
currentSplits.catch(() => []).then(objectsToViews) : // handle possible rejections when using pluggable storage
objectsToViews(currentSplits);
},
/**
* Get the feature flag names present on the factory storage
*/
names() {
if (!validateIfOperational(log, readinessManager, NAMES_FN_LABEL)) {
return isAsync ? Promise.resolve([]) : [];
}
const splitNames = splits.getSplitNames();
return thenable(splitNames) ?
splitNames.catch(() => []) : // handle possible rejections when using pluggable storage
splitNames;
}
}
);
}