@featurevisor/sdk 0.33.0 → 0.35.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/CHANGELOG.md +19 -0
- package/coverage/clover.xml +333 -322
- package/coverage/coverage-final.json +2 -2
- package/coverage/lcov-report/bucket.ts.html +1 -1
- package/coverage/lcov-report/conditions.ts.html +1 -1
- package/coverage/lcov-report/datafileReader.ts.html +1 -1
- package/coverage/lcov-report/emitter.ts.html +1 -1
- package/coverage/lcov-report/feature.ts.html +13 -805
- package/coverage/lcov-report/index.html +28 -28
- package/coverage/lcov-report/instance.ts.html +1018 -109
- package/coverage/lcov-report/logger.ts.html +1 -1
- package/coverage/lcov-report/segments.ts.html +1 -1
- package/coverage/lcov.info +603 -578
- package/dist/index.js +1 -1
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/lib/feature.d.ts +2 -9
- package/lib/feature.js +1 -169
- package/lib/feature.js.map +1 -1
- package/lib/instance.d.ts +26 -1
- package/lib/instance.js +313 -81
- package/lib/instance.js.map +1 -1
- package/package.json +3 -3
- package/src/feature.ts +2 -266
- package/src/instance.ts +398 -95
package/src/feature.ts
CHANGED
|
@@ -1,21 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Allocation,
|
|
3
|
-
Attributes,
|
|
4
|
-
Traffic,
|
|
5
|
-
Feature,
|
|
6
|
-
Variation,
|
|
7
|
-
VariableValue,
|
|
8
|
-
Force,
|
|
9
|
-
} from "@featurevisor/types";
|
|
1
|
+
import { Allocation, Attributes, Traffic, Feature, Force } from "@featurevisor/types";
|
|
10
2
|
import { DatafileReader } from "./datafileReader";
|
|
11
3
|
import { allGroupSegmentsAreMatched } from "./segments";
|
|
12
4
|
import { allConditionsAreMatched } from "./conditions";
|
|
13
|
-
import { VariableSchema } from "@featurevisor/types/src";
|
|
14
5
|
import { Logger } from "./logger";
|
|
15
6
|
|
|
16
|
-
/**
|
|
17
|
-
* Traffic
|
|
18
|
-
*/
|
|
19
7
|
export function getMatchedAllocation(
|
|
20
8
|
traffic: Traffic,
|
|
21
9
|
bucketValue: number,
|
|
@@ -71,10 +59,7 @@ export function getMatchedTrafficAndAllocation(
|
|
|
71
59
|
};
|
|
72
60
|
}
|
|
73
61
|
|
|
74
|
-
|
|
75
|
-
* Variations and variables
|
|
76
|
-
*/
|
|
77
|
-
function findForceFromFeature(
|
|
62
|
+
export function findForceFromFeature(
|
|
78
63
|
feature: Feature,
|
|
79
64
|
attributes: Attributes,
|
|
80
65
|
datafileReader: DatafileReader,
|
|
@@ -95,252 +80,3 @@ function findForceFromFeature(
|
|
|
95
80
|
return false;
|
|
96
81
|
});
|
|
97
82
|
}
|
|
98
|
-
|
|
99
|
-
export function getForcedVariation(
|
|
100
|
-
feature: Feature,
|
|
101
|
-
attributes: Attributes,
|
|
102
|
-
datafileReader: DatafileReader,
|
|
103
|
-
): Variation | undefined {
|
|
104
|
-
const force = findForceFromFeature(feature, attributes, datafileReader);
|
|
105
|
-
|
|
106
|
-
if (!force || !force.variation) {
|
|
107
|
-
return undefined;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return feature.variations.find((v) => v.value === force.variation);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function getBucketedVariation(
|
|
114
|
-
feature: Feature,
|
|
115
|
-
attributes: Attributes,
|
|
116
|
-
bucketValue: number,
|
|
117
|
-
datafileReader: DatafileReader,
|
|
118
|
-
logger: Logger,
|
|
119
|
-
): Variation | undefined {
|
|
120
|
-
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
|
|
121
|
-
feature.traffic,
|
|
122
|
-
attributes,
|
|
123
|
-
bucketValue,
|
|
124
|
-
datafileReader,
|
|
125
|
-
logger,
|
|
126
|
-
);
|
|
127
|
-
|
|
128
|
-
if (!matchedTraffic) {
|
|
129
|
-
logger.debug("no matched rule found", {
|
|
130
|
-
featureKey: feature.key,
|
|
131
|
-
bucketValue,
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
return undefined;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
if (matchedTraffic.variation) {
|
|
138
|
-
const variation = feature.variations.find((v) => {
|
|
139
|
-
return v.value === matchedTraffic.variation;
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
if (variation) {
|
|
143
|
-
logger.debug("using variation from rule", {
|
|
144
|
-
featureKey: feature.key,
|
|
145
|
-
variation: variation.value,
|
|
146
|
-
ruleKey: matchedTraffic.key,
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
return variation;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (!matchedAllocation) {
|
|
154
|
-
logger.debug("no matched allocation found", {
|
|
155
|
-
featureKey: feature.key,
|
|
156
|
-
bucketValue,
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
return undefined;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const variationValue = matchedAllocation.variation;
|
|
163
|
-
|
|
164
|
-
const variation = feature.variations.find((v) => {
|
|
165
|
-
return v.value === variationValue;
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!variation) {
|
|
169
|
-
// this should never happen
|
|
170
|
-
logger.debug("no matched variation found", {
|
|
171
|
-
featureKey: feature.key,
|
|
172
|
-
variation: variationValue,
|
|
173
|
-
bucketValue,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
return undefined;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
logger.debug("matched variation", {
|
|
180
|
-
featureKey: feature.key,
|
|
181
|
-
variation: variation.value,
|
|
182
|
-
bucketValue,
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
return variation;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export function getForcedVariableValue(
|
|
189
|
-
feature: Feature,
|
|
190
|
-
variableSchema: VariableSchema,
|
|
191
|
-
attributes: Attributes,
|
|
192
|
-
datafileReader: DatafileReader,
|
|
193
|
-
): VariableValue | undefined {
|
|
194
|
-
const force = findForceFromFeature(feature, attributes, datafileReader);
|
|
195
|
-
|
|
196
|
-
if (!force || !force.variables) {
|
|
197
|
-
return undefined;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const value = force.variables[variableSchema.key];
|
|
201
|
-
|
|
202
|
-
if (typeof value === "string" && variableSchema.type === "json") {
|
|
203
|
-
return JSON.parse(value);
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
return value;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export function getBucketedVariableValue(
|
|
210
|
-
feature: Feature,
|
|
211
|
-
variableSchema: VariableSchema,
|
|
212
|
-
attributes: Attributes,
|
|
213
|
-
bucketValue: number,
|
|
214
|
-
datafileReader: DatafileReader,
|
|
215
|
-
logger: Logger,
|
|
216
|
-
): VariableValue | undefined {
|
|
217
|
-
// get traffic
|
|
218
|
-
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
|
|
219
|
-
feature.traffic,
|
|
220
|
-
attributes,
|
|
221
|
-
bucketValue,
|
|
222
|
-
datafileReader,
|
|
223
|
-
logger,
|
|
224
|
-
);
|
|
225
|
-
|
|
226
|
-
if (!matchedTraffic) {
|
|
227
|
-
logger.debug("no matched rule found", {
|
|
228
|
-
featureKey: feature.key,
|
|
229
|
-
variableKey: variableSchema.key,
|
|
230
|
-
bucketValue,
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
return undefined;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const variableKey = variableSchema.key;
|
|
237
|
-
|
|
238
|
-
// see if variable is set at traffic/rule level
|
|
239
|
-
if (matchedTraffic.variables && typeof matchedTraffic.variables[variableKey] !== "undefined") {
|
|
240
|
-
logger.debug("using variable from rule", {
|
|
241
|
-
featureKey: feature.key,
|
|
242
|
-
variableKey,
|
|
243
|
-
bucketValue,
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
return matchedTraffic.variables[variableKey];
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
if (!matchedAllocation) {
|
|
250
|
-
logger.debug("no matched allocation found", {
|
|
251
|
-
featureKey: feature.key,
|
|
252
|
-
variableKey,
|
|
253
|
-
bucketValue,
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
return undefined;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const variationValue = matchedAllocation.variation;
|
|
260
|
-
|
|
261
|
-
const variation = feature.variations.find((v) => {
|
|
262
|
-
return v.value === variationValue;
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
if (!variation) {
|
|
266
|
-
// this should never happen
|
|
267
|
-
logger.debug("no matched variation found", {
|
|
268
|
-
feature: feature.key,
|
|
269
|
-
variableKey,
|
|
270
|
-
variation: variationValue,
|
|
271
|
-
bucketValue,
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
return undefined;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
const variableFromVariation = variation.variables?.find((v) => {
|
|
278
|
-
return v.key === variableKey;
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
if (!variableFromVariation) {
|
|
282
|
-
logger.debug("using default value as variation has no variable", {
|
|
283
|
-
featureKey: feature.key,
|
|
284
|
-
variableKey,
|
|
285
|
-
variation: variationValue,
|
|
286
|
-
bucketValue,
|
|
287
|
-
});
|
|
288
|
-
|
|
289
|
-
if (variableSchema.type === "json") {
|
|
290
|
-
return JSON.parse(variableSchema.defaultValue as string);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
return variableSchema.defaultValue;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
if (variableFromVariation.overrides) {
|
|
297
|
-
const override = variableFromVariation.overrides.find((o) => {
|
|
298
|
-
if (o.conditions) {
|
|
299
|
-
return allConditionsAreMatched(
|
|
300
|
-
typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
|
|
301
|
-
attributes,
|
|
302
|
-
);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
if (o.segments) {
|
|
306
|
-
return allGroupSegmentsAreMatched(
|
|
307
|
-
typeof o.segments === "string" && o.segments !== "*"
|
|
308
|
-
? JSON.parse(o.segments)
|
|
309
|
-
: o.segments,
|
|
310
|
-
attributes,
|
|
311
|
-
datafileReader,
|
|
312
|
-
);
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
return false;
|
|
316
|
-
});
|
|
317
|
-
|
|
318
|
-
if (override) {
|
|
319
|
-
logger.debug("using override value from variation", {
|
|
320
|
-
feature: feature.key,
|
|
321
|
-
variableKey,
|
|
322
|
-
variation: variationValue,
|
|
323
|
-
bucketValue,
|
|
324
|
-
});
|
|
325
|
-
|
|
326
|
-
if (variableSchema.type === "json") {
|
|
327
|
-
return JSON.parse(override.value as string);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
return override.value;
|
|
331
|
-
}
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
logger.debug("using value from variation", {
|
|
335
|
-
feature: feature.key,
|
|
336
|
-
variableKey,
|
|
337
|
-
variation: variationValue,
|
|
338
|
-
bucketValue,
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
if (variableSchema.type === "json") {
|
|
342
|
-
return JSON.parse(variableFromVariation.value as string);
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
return variableFromVariation.value;
|
|
346
|
-
}
|