@featurevisor/sdk 1.20.0 → 1.27.2
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/.eslintcache +1 -1
- package/CHANGELOG.md +11 -0
- package/coverage/clover.xml +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 +1 -1
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/instance.ts.html +1 -1
- package/coverage/lcov-report/logger.ts.html +1 -1
- package/coverage/lcov-report/segments.ts.html +1 -1
- package/dist/bucket.d.ts +2 -0
- package/dist/conditions.d.ts +4 -0
- package/dist/datafileReader.d.ts +16 -0
- package/dist/emitter.d.ts +12 -0
- package/dist/feature.d.ts +16 -0
- package/{lib/index.js → dist/index.d.ts} +0 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/index.mjs.map +1 -0
- package/dist/instance.d.ts +140 -0
- package/dist/logger.d.ts +25 -0
- package/dist/segments.d.ts +5 -0
- package/package.json +15 -7
- package/webpack.config.js +77 -10
- package/dist/index.js.gz +0 -0
- package/lib/bucket.js +0 -10
- package/lib/bucket.js.map +0 -1
- package/lib/bucket.spec.d.ts +0 -1
- package/lib/conditions.js +0 -115
- package/lib/conditions.js.map +0 -1
- package/lib/conditions.spec.d.ts +0 -1
- package/lib/datafileReader.js +0 -49
- package/lib/datafileReader.js.map +0 -1
- package/lib/datafileReader.spec.d.ts +0 -1
- package/lib/emitter.js +0 -46
- package/lib/emitter.js.map +0 -1
- package/lib/emitter.spec.d.ts +0 -1
- package/lib/feature.js +0 -68
- package/lib/feature.js.map +0 -1
- package/lib/index.js.map +0 -1
- package/lib/index.spec.d.ts +0 -0
- package/lib/instance.js +0 -926
- package/lib/instance.js.map +0 -1
- package/lib/instance.spec.d.ts +0 -1
- package/lib/logger.js +0 -61
- package/lib/logger.js.map +0 -1
- package/lib/logger.spec.d.ts +0 -1
- package/lib/segments.js +0 -40
- package/lib/segments.js.map +0 -1
- package/lib/segments.spec.d.ts +0 -1
package/lib/instance.js
DELETED
|
@@ -1,926 +0,0 @@
|
|
|
1
|
-
import { createLogger } from "./logger";
|
|
2
|
-
import { DatafileReader } from "./datafileReader";
|
|
3
|
-
import { Emitter } from "./emitter";
|
|
4
|
-
import { getBucketedNumber } from "./bucket";
|
|
5
|
-
import { findForceFromFeature, getMatchedTraffic, getMatchedTrafficAndAllocation, parseFromStringifiedSegments, } from "./feature";
|
|
6
|
-
import { allConditionsAreMatched } from "./conditions";
|
|
7
|
-
import { allGroupSegmentsAreMatched } from "./segments";
|
|
8
|
-
var DEFAULT_BUCKET_KEY_SEPARATOR = ".";
|
|
9
|
-
var emptyDatafile = {
|
|
10
|
-
schemaVersion: "1",
|
|
11
|
-
revision: "unknown",
|
|
12
|
-
attributes: [],
|
|
13
|
-
segments: [],
|
|
14
|
-
features: [],
|
|
15
|
-
};
|
|
16
|
-
export var EvaluationReason;
|
|
17
|
-
(function (EvaluationReason) {
|
|
18
|
-
EvaluationReason["NOT_FOUND"] = "not_found";
|
|
19
|
-
EvaluationReason["NO_VARIATIONS"] = "no_variations";
|
|
20
|
-
EvaluationReason["NO_MATCH"] = "no_match";
|
|
21
|
-
EvaluationReason["DISABLED"] = "disabled";
|
|
22
|
-
EvaluationReason["REQUIRED"] = "required";
|
|
23
|
-
EvaluationReason["OUT_OF_RANGE"] = "out_of_range";
|
|
24
|
-
EvaluationReason["FORCED"] = "forced";
|
|
25
|
-
EvaluationReason["INITIAL"] = "initial";
|
|
26
|
-
EvaluationReason["STICKY"] = "sticky";
|
|
27
|
-
EvaluationReason["RULE"] = "rule";
|
|
28
|
-
EvaluationReason["ALLOCATED"] = "allocated";
|
|
29
|
-
EvaluationReason["DEFAULTED"] = "defaulted";
|
|
30
|
-
EvaluationReason["OVERRIDE"] = "override";
|
|
31
|
-
EvaluationReason["ERROR"] = "error";
|
|
32
|
-
})(EvaluationReason || (EvaluationReason = {}));
|
|
33
|
-
function fetchDatafileContent(datafileUrl, handleDatafileFetch) {
|
|
34
|
-
if (handleDatafileFetch) {
|
|
35
|
-
return handleDatafileFetch(datafileUrl);
|
|
36
|
-
}
|
|
37
|
-
return fetch(datafileUrl).then(function (res) { return res.json(); });
|
|
38
|
-
}
|
|
39
|
-
export function getValueByType(value, fieldType) {
|
|
40
|
-
try {
|
|
41
|
-
if (value === undefined) {
|
|
42
|
-
return undefined;
|
|
43
|
-
}
|
|
44
|
-
switch (fieldType) {
|
|
45
|
-
case "string":
|
|
46
|
-
return typeof value === "string" ? value : undefined;
|
|
47
|
-
case "integer":
|
|
48
|
-
return parseInt(value, 10);
|
|
49
|
-
case "double":
|
|
50
|
-
return parseFloat(value);
|
|
51
|
-
case "boolean":
|
|
52
|
-
return value === true;
|
|
53
|
-
case "array":
|
|
54
|
-
return Array.isArray(value) ? value : undefined;
|
|
55
|
-
case "object":
|
|
56
|
-
return typeof value === "object" ? value : undefined;
|
|
57
|
-
// @NOTE: `json` is not handled here intentionally
|
|
58
|
-
default:
|
|
59
|
-
return value;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
catch (e) {
|
|
63
|
-
return undefined;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
var FeaturevisorInstance = /** @class */ (function () {
|
|
67
|
-
function FeaturevisorInstance(options) {
|
|
68
|
-
var _this = this;
|
|
69
|
-
// from options
|
|
70
|
-
this.bucketKeySeparator = options.bucketKeySeparator || DEFAULT_BUCKET_KEY_SEPARATOR;
|
|
71
|
-
this.configureBucketKey = options.configureBucketKey;
|
|
72
|
-
this.configureBucketValue = options.configureBucketValue;
|
|
73
|
-
this.datafileUrl = options.datafileUrl;
|
|
74
|
-
this.handleDatafileFetch = options.handleDatafileFetch;
|
|
75
|
-
this.initialFeatures = options.initialFeatures;
|
|
76
|
-
this.interceptContext = options.interceptContext;
|
|
77
|
-
this.logger = options.logger || createLogger();
|
|
78
|
-
this.refreshInterval = options.refreshInterval;
|
|
79
|
-
this.stickyFeatures = options.stickyFeatures;
|
|
80
|
-
// internal
|
|
81
|
-
this.emitter = new Emitter();
|
|
82
|
-
this.statuses = {
|
|
83
|
-
ready: false,
|
|
84
|
-
refreshInProgress: false,
|
|
85
|
-
};
|
|
86
|
-
// register events
|
|
87
|
-
if (options.onReady) {
|
|
88
|
-
this.emitter.addListener("ready", options.onReady);
|
|
89
|
-
}
|
|
90
|
-
if (options.onRefresh) {
|
|
91
|
-
this.emitter.addListener("refresh", options.onRefresh);
|
|
92
|
-
}
|
|
93
|
-
if (options.onUpdate) {
|
|
94
|
-
this.emitter.addListener("update", options.onUpdate);
|
|
95
|
-
}
|
|
96
|
-
if (options.onActivation) {
|
|
97
|
-
this.emitter.addListener("activation", options.onActivation);
|
|
98
|
-
}
|
|
99
|
-
// expose emitter methods
|
|
100
|
-
var on = this.emitter.addListener.bind(this.emitter);
|
|
101
|
-
this.on = on;
|
|
102
|
-
this.addListener = on;
|
|
103
|
-
var off = this.emitter.removeListener.bind(this.emitter);
|
|
104
|
-
this.off = off;
|
|
105
|
-
this.removeListener = off;
|
|
106
|
-
this.removeAllListeners = this.emitter.removeAllListeners.bind(this.emitter);
|
|
107
|
-
// datafile
|
|
108
|
-
if (options.datafileUrl) {
|
|
109
|
-
this.setDatafile(options.datafile || emptyDatafile);
|
|
110
|
-
fetchDatafileContent(options.datafileUrl, options.handleDatafileFetch)
|
|
111
|
-
.then(function (datafile) {
|
|
112
|
-
_this.setDatafile(datafile);
|
|
113
|
-
_this.statuses.ready = true;
|
|
114
|
-
_this.emitter.emit("ready");
|
|
115
|
-
if (_this.refreshInterval) {
|
|
116
|
-
_this.startRefreshing();
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
.catch(function (e) {
|
|
120
|
-
_this.logger.error("failed to fetch datafile", { error: e });
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
else if (options.datafile) {
|
|
124
|
-
this.setDatafile(options.datafile);
|
|
125
|
-
this.statuses.ready = true;
|
|
126
|
-
setTimeout(function () {
|
|
127
|
-
_this.emitter.emit("ready");
|
|
128
|
-
}, 0);
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
throw new Error("Featurevisor SDK instance cannot be created without both `datafile` and `datafileUrl` options");
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
FeaturevisorInstance.prototype.setLogLevels = function (levels) {
|
|
135
|
-
this.logger.setLevels(levels);
|
|
136
|
-
};
|
|
137
|
-
FeaturevisorInstance.prototype.onReady = function () {
|
|
138
|
-
var _this = this;
|
|
139
|
-
return new Promise(function (resolve) {
|
|
140
|
-
if (_this.statuses.ready) {
|
|
141
|
-
return resolve(_this);
|
|
142
|
-
}
|
|
143
|
-
var cb = function () {
|
|
144
|
-
_this.emitter.removeListener("ready", cb);
|
|
145
|
-
resolve(_this);
|
|
146
|
-
};
|
|
147
|
-
_this.emitter.addListener("ready", cb);
|
|
148
|
-
});
|
|
149
|
-
};
|
|
150
|
-
FeaturevisorInstance.prototype.setDatafile = function (datafile) {
|
|
151
|
-
try {
|
|
152
|
-
this.datafileReader = new DatafileReader(typeof datafile === "string" ? JSON.parse(datafile) : datafile);
|
|
153
|
-
}
|
|
154
|
-
catch (e) {
|
|
155
|
-
this.logger.error("could not parse datafile", { error: e });
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
FeaturevisorInstance.prototype.setStickyFeatures = function (stickyFeatures) {
|
|
159
|
-
this.stickyFeatures = stickyFeatures;
|
|
160
|
-
};
|
|
161
|
-
FeaturevisorInstance.prototype.getRevision = function () {
|
|
162
|
-
return this.datafileReader.getRevision();
|
|
163
|
-
};
|
|
164
|
-
FeaturevisorInstance.prototype.getFeature = function (featureKey) {
|
|
165
|
-
return typeof featureKey === "string"
|
|
166
|
-
? this.datafileReader.getFeature(featureKey) // only key provided
|
|
167
|
-
: featureKey; // full feature provided
|
|
168
|
-
};
|
|
169
|
-
/**
|
|
170
|
-
* Bucketing
|
|
171
|
-
*/
|
|
172
|
-
FeaturevisorInstance.prototype.getBucketKey = function (feature, context) {
|
|
173
|
-
var featureKey = feature.key;
|
|
174
|
-
var type;
|
|
175
|
-
var attributeKeys;
|
|
176
|
-
if (typeof feature.bucketBy === "string") {
|
|
177
|
-
type = "plain";
|
|
178
|
-
attributeKeys = [feature.bucketBy];
|
|
179
|
-
}
|
|
180
|
-
else if (Array.isArray(feature.bucketBy)) {
|
|
181
|
-
type = "and";
|
|
182
|
-
attributeKeys = feature.bucketBy;
|
|
183
|
-
}
|
|
184
|
-
else if (typeof feature.bucketBy === "object" && Array.isArray(feature.bucketBy.or)) {
|
|
185
|
-
type = "or";
|
|
186
|
-
attributeKeys = feature.bucketBy.or;
|
|
187
|
-
}
|
|
188
|
-
else {
|
|
189
|
-
this.logger.error("invalid bucketBy", { featureKey: featureKey, bucketBy: feature.bucketBy });
|
|
190
|
-
throw new Error("invalid bucketBy");
|
|
191
|
-
}
|
|
192
|
-
var bucketKey = [];
|
|
193
|
-
attributeKeys.forEach(function (attributeKey) {
|
|
194
|
-
var attributeValue = context[attributeKey];
|
|
195
|
-
if (typeof attributeValue === "undefined") {
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
if (type === "plain" || type === "and") {
|
|
199
|
-
bucketKey.push(attributeValue);
|
|
200
|
-
}
|
|
201
|
-
else {
|
|
202
|
-
// or
|
|
203
|
-
if (bucketKey.length === 0) {
|
|
204
|
-
bucketKey.push(attributeValue);
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
});
|
|
208
|
-
bucketKey.push(featureKey);
|
|
209
|
-
var result = bucketKey.join(this.bucketKeySeparator);
|
|
210
|
-
if (this.configureBucketKey) {
|
|
211
|
-
return this.configureBucketKey(feature, context, result);
|
|
212
|
-
}
|
|
213
|
-
return result;
|
|
214
|
-
};
|
|
215
|
-
FeaturevisorInstance.prototype.getBucketValue = function (feature, context) {
|
|
216
|
-
var bucketKey = this.getBucketKey(feature, context);
|
|
217
|
-
var value = getBucketedNumber(bucketKey);
|
|
218
|
-
if (this.configureBucketValue) {
|
|
219
|
-
var configuredValue = this.configureBucketValue(feature, context, value);
|
|
220
|
-
return {
|
|
221
|
-
bucketKey: bucketKey,
|
|
222
|
-
bucketValue: configuredValue,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
return {
|
|
226
|
-
bucketKey: bucketKey,
|
|
227
|
-
bucketValue: value,
|
|
228
|
-
};
|
|
229
|
-
};
|
|
230
|
-
/**
|
|
231
|
-
* Statuses
|
|
232
|
-
*/
|
|
233
|
-
FeaturevisorInstance.prototype.isReady = function () {
|
|
234
|
-
return this.statuses.ready;
|
|
235
|
-
};
|
|
236
|
-
/**
|
|
237
|
-
* Refresh
|
|
238
|
-
*/
|
|
239
|
-
FeaturevisorInstance.prototype.refresh = function () {
|
|
240
|
-
var _this = this;
|
|
241
|
-
this.logger.debug("refreshing datafile");
|
|
242
|
-
if (this.statuses.refreshInProgress) {
|
|
243
|
-
return this.logger.warn("refresh in progress, skipping");
|
|
244
|
-
}
|
|
245
|
-
if (!this.datafileUrl) {
|
|
246
|
-
return this.logger.error("cannot refresh since `datafileUrl` is not provided");
|
|
247
|
-
}
|
|
248
|
-
this.statuses.refreshInProgress = true;
|
|
249
|
-
fetchDatafileContent(this.datafileUrl, this.handleDatafileFetch)
|
|
250
|
-
.then(function (datafile) {
|
|
251
|
-
var currentRevision = _this.getRevision();
|
|
252
|
-
var newRevision = datafile.revision;
|
|
253
|
-
var isNotSameRevision = currentRevision !== newRevision;
|
|
254
|
-
_this.setDatafile(datafile);
|
|
255
|
-
_this.logger.info("refreshed datafile");
|
|
256
|
-
_this.emitter.emit("refresh");
|
|
257
|
-
if (isNotSameRevision) {
|
|
258
|
-
_this.emitter.emit("update");
|
|
259
|
-
}
|
|
260
|
-
_this.statuses.refreshInProgress = false;
|
|
261
|
-
})
|
|
262
|
-
.catch(function (e) {
|
|
263
|
-
_this.logger.error("failed to refresh datafile", { error: e });
|
|
264
|
-
_this.statuses.refreshInProgress = false;
|
|
265
|
-
});
|
|
266
|
-
};
|
|
267
|
-
FeaturevisorInstance.prototype.startRefreshing = function () {
|
|
268
|
-
var _this = this;
|
|
269
|
-
if (!this.datafileUrl) {
|
|
270
|
-
return this.logger.error("cannot start refreshing since `datafileUrl` is not provided");
|
|
271
|
-
}
|
|
272
|
-
if (this.intervalId) {
|
|
273
|
-
return this.logger.warn("refreshing has already started");
|
|
274
|
-
}
|
|
275
|
-
if (!this.refreshInterval) {
|
|
276
|
-
return this.logger.warn("no `refreshInterval` option provided");
|
|
277
|
-
}
|
|
278
|
-
this.intervalId = setInterval(function () {
|
|
279
|
-
_this.refresh();
|
|
280
|
-
}, this.refreshInterval * 1000);
|
|
281
|
-
};
|
|
282
|
-
FeaturevisorInstance.prototype.stopRefreshing = function () {
|
|
283
|
-
if (!this.intervalId) {
|
|
284
|
-
return this.logger.warn("refreshing has not started yet");
|
|
285
|
-
}
|
|
286
|
-
clearInterval(this.intervalId);
|
|
287
|
-
};
|
|
288
|
-
/**
|
|
289
|
-
* Flag
|
|
290
|
-
*/
|
|
291
|
-
FeaturevisorInstance.prototype.evaluateFlag = function (featureKey, context) {
|
|
292
|
-
var _this = this;
|
|
293
|
-
if (context === void 0) { context = {}; }
|
|
294
|
-
var evaluation;
|
|
295
|
-
try {
|
|
296
|
-
var key = typeof featureKey === "string" ? featureKey : featureKey.key;
|
|
297
|
-
// sticky
|
|
298
|
-
if (this.stickyFeatures &&
|
|
299
|
-
this.stickyFeatures[key] &&
|
|
300
|
-
typeof this.stickyFeatures[key].enabled !== "undefined") {
|
|
301
|
-
evaluation = {
|
|
302
|
-
featureKey: key,
|
|
303
|
-
reason: EvaluationReason.STICKY,
|
|
304
|
-
sticky: this.stickyFeatures[key],
|
|
305
|
-
enabled: this.stickyFeatures[key].enabled,
|
|
306
|
-
};
|
|
307
|
-
this.logger.debug("using sticky enabled", evaluation);
|
|
308
|
-
return evaluation;
|
|
309
|
-
}
|
|
310
|
-
// initial
|
|
311
|
-
if (this.statuses &&
|
|
312
|
-
!this.statuses.ready &&
|
|
313
|
-
this.initialFeatures &&
|
|
314
|
-
this.initialFeatures[key] &&
|
|
315
|
-
typeof this.initialFeatures[key].enabled !== "undefined") {
|
|
316
|
-
evaluation = {
|
|
317
|
-
featureKey: key,
|
|
318
|
-
reason: EvaluationReason.INITIAL,
|
|
319
|
-
initial: this.initialFeatures[key],
|
|
320
|
-
enabled: this.initialFeatures[key].enabled,
|
|
321
|
-
};
|
|
322
|
-
this.logger.debug("using initial enabled", evaluation);
|
|
323
|
-
return evaluation;
|
|
324
|
-
}
|
|
325
|
-
var feature = this.getFeature(featureKey);
|
|
326
|
-
// not found
|
|
327
|
-
if (!feature) {
|
|
328
|
-
evaluation = {
|
|
329
|
-
featureKey: key,
|
|
330
|
-
reason: EvaluationReason.NOT_FOUND,
|
|
331
|
-
};
|
|
332
|
-
this.logger.warn("feature not found", evaluation);
|
|
333
|
-
return evaluation;
|
|
334
|
-
}
|
|
335
|
-
// deprecated
|
|
336
|
-
if (feature.deprecated) {
|
|
337
|
-
this.logger.warn("feature is deprecated", { featureKey: feature.key });
|
|
338
|
-
}
|
|
339
|
-
var finalContext_1 = this.interceptContext ? this.interceptContext(context) : context;
|
|
340
|
-
// forced
|
|
341
|
-
var _a = findForceFromFeature(feature, context, this.datafileReader, this.logger), force = _a.force, forceIndex = _a.forceIndex;
|
|
342
|
-
if (force && typeof force.enabled !== "undefined") {
|
|
343
|
-
evaluation = {
|
|
344
|
-
featureKey: feature.key,
|
|
345
|
-
reason: EvaluationReason.FORCED,
|
|
346
|
-
forceIndex: forceIndex,
|
|
347
|
-
force: force,
|
|
348
|
-
enabled: force.enabled,
|
|
349
|
-
};
|
|
350
|
-
this.logger.debug("forced enabled found", evaluation);
|
|
351
|
-
return evaluation;
|
|
352
|
-
}
|
|
353
|
-
// required
|
|
354
|
-
if (feature.required && feature.required.length > 0) {
|
|
355
|
-
var requiredFeaturesAreEnabled = feature.required.every(function (required) {
|
|
356
|
-
var requiredKey;
|
|
357
|
-
var requiredVariation;
|
|
358
|
-
if (typeof required === "string") {
|
|
359
|
-
requiredKey = required;
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
requiredKey = required.key;
|
|
363
|
-
requiredVariation = required.variation;
|
|
364
|
-
}
|
|
365
|
-
var requiredIsEnabled = _this.isEnabled(requiredKey, finalContext_1);
|
|
366
|
-
if (!requiredIsEnabled) {
|
|
367
|
-
return false;
|
|
368
|
-
}
|
|
369
|
-
if (typeof requiredVariation !== "undefined") {
|
|
370
|
-
var requiredVariationValue = _this.getVariation(requiredKey, finalContext_1);
|
|
371
|
-
return requiredVariationValue === requiredVariation;
|
|
372
|
-
}
|
|
373
|
-
return true;
|
|
374
|
-
});
|
|
375
|
-
if (!requiredFeaturesAreEnabled) {
|
|
376
|
-
evaluation = {
|
|
377
|
-
featureKey: feature.key,
|
|
378
|
-
reason: EvaluationReason.REQUIRED,
|
|
379
|
-
required: feature.required,
|
|
380
|
-
enabled: requiredFeaturesAreEnabled,
|
|
381
|
-
};
|
|
382
|
-
this.logger.debug("required features not enabled", evaluation);
|
|
383
|
-
return evaluation;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
// bucketing
|
|
387
|
-
var _b = this.getBucketValue(feature, finalContext_1), bucketKey = _b.bucketKey, bucketValue_1 = _b.bucketValue;
|
|
388
|
-
var matchedTraffic = getMatchedTraffic(feature.traffic, finalContext_1, this.datafileReader, this.logger);
|
|
389
|
-
if (matchedTraffic) {
|
|
390
|
-
// check if mutually exclusive
|
|
391
|
-
if (feature.ranges && feature.ranges.length > 0) {
|
|
392
|
-
var matchedRange = feature.ranges.find(function (range) {
|
|
393
|
-
return bucketValue_1 >= range[0] && bucketValue_1 < range[1];
|
|
394
|
-
});
|
|
395
|
-
// matched
|
|
396
|
-
if (matchedRange) {
|
|
397
|
-
evaluation = {
|
|
398
|
-
featureKey: feature.key,
|
|
399
|
-
reason: EvaluationReason.ALLOCATED,
|
|
400
|
-
bucketKey: bucketKey,
|
|
401
|
-
bucketValue: bucketValue_1,
|
|
402
|
-
ruleKey: matchedTraffic.key,
|
|
403
|
-
traffic: matchedTraffic,
|
|
404
|
-
enabled: typeof matchedTraffic.enabled === "undefined" ? true : matchedTraffic.enabled,
|
|
405
|
-
};
|
|
406
|
-
this.logger.debug("matched", evaluation);
|
|
407
|
-
return evaluation;
|
|
408
|
-
}
|
|
409
|
-
// no match
|
|
410
|
-
evaluation = {
|
|
411
|
-
featureKey: feature.key,
|
|
412
|
-
reason: EvaluationReason.OUT_OF_RANGE,
|
|
413
|
-
bucketKey: bucketKey,
|
|
414
|
-
bucketValue: bucketValue_1,
|
|
415
|
-
enabled: false,
|
|
416
|
-
};
|
|
417
|
-
this.logger.debug("not matched", evaluation);
|
|
418
|
-
return evaluation;
|
|
419
|
-
}
|
|
420
|
-
// override from rule
|
|
421
|
-
if (typeof matchedTraffic.enabled !== "undefined") {
|
|
422
|
-
evaluation = {
|
|
423
|
-
featureKey: feature.key,
|
|
424
|
-
reason: EvaluationReason.OVERRIDE,
|
|
425
|
-
bucketKey: bucketKey,
|
|
426
|
-
bucketValue: bucketValue_1,
|
|
427
|
-
ruleKey: matchedTraffic.key,
|
|
428
|
-
traffic: matchedTraffic,
|
|
429
|
-
enabled: matchedTraffic.enabled,
|
|
430
|
-
};
|
|
431
|
-
this.logger.debug("override from rule", evaluation);
|
|
432
|
-
return evaluation;
|
|
433
|
-
}
|
|
434
|
-
// treated as enabled because of matched traffic
|
|
435
|
-
if (bucketValue_1 <= matchedTraffic.percentage) {
|
|
436
|
-
evaluation = {
|
|
437
|
-
featureKey: feature.key,
|
|
438
|
-
reason: EvaluationReason.RULE,
|
|
439
|
-
bucketKey: bucketKey,
|
|
440
|
-
bucketValue: bucketValue_1,
|
|
441
|
-
ruleKey: matchedTraffic.key,
|
|
442
|
-
traffic: matchedTraffic,
|
|
443
|
-
enabled: true,
|
|
444
|
-
};
|
|
445
|
-
this.logger.debug("matched traffic", evaluation);
|
|
446
|
-
return evaluation;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
// nothing matched
|
|
450
|
-
evaluation = {
|
|
451
|
-
featureKey: feature.key,
|
|
452
|
-
reason: EvaluationReason.NO_MATCH,
|
|
453
|
-
bucketKey: bucketKey,
|
|
454
|
-
bucketValue: bucketValue_1,
|
|
455
|
-
enabled: false,
|
|
456
|
-
};
|
|
457
|
-
this.logger.debug("nothing matched", evaluation);
|
|
458
|
-
return evaluation;
|
|
459
|
-
}
|
|
460
|
-
catch (e) {
|
|
461
|
-
evaluation = {
|
|
462
|
-
featureKey: typeof featureKey === "string" ? featureKey : featureKey.key,
|
|
463
|
-
reason: EvaluationReason.ERROR,
|
|
464
|
-
error: e,
|
|
465
|
-
};
|
|
466
|
-
this.logger.error("error", evaluation);
|
|
467
|
-
return evaluation;
|
|
468
|
-
}
|
|
469
|
-
};
|
|
470
|
-
FeaturevisorInstance.prototype.isEnabled = function (featureKey, context) {
|
|
471
|
-
if (context === void 0) { context = {}; }
|
|
472
|
-
try {
|
|
473
|
-
var evaluation = this.evaluateFlag(featureKey, context);
|
|
474
|
-
return evaluation.enabled === true;
|
|
475
|
-
}
|
|
476
|
-
catch (e) {
|
|
477
|
-
this.logger.error("isEnabled", { featureKey: featureKey, error: e });
|
|
478
|
-
return false;
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
|
-
/**
|
|
482
|
-
* Variation
|
|
483
|
-
*/
|
|
484
|
-
FeaturevisorInstance.prototype.evaluateVariation = function (featureKey, context) {
|
|
485
|
-
if (context === void 0) { context = {}; }
|
|
486
|
-
var evaluation;
|
|
487
|
-
try {
|
|
488
|
-
var key = typeof featureKey === "string" ? featureKey : featureKey.key;
|
|
489
|
-
var flag = this.evaluateFlag(featureKey, context);
|
|
490
|
-
if (flag.enabled === false) {
|
|
491
|
-
evaluation = {
|
|
492
|
-
featureKey: key,
|
|
493
|
-
reason: EvaluationReason.DISABLED,
|
|
494
|
-
};
|
|
495
|
-
this.logger.debug("feature is disabled", evaluation);
|
|
496
|
-
return evaluation;
|
|
497
|
-
}
|
|
498
|
-
// sticky
|
|
499
|
-
if (this.stickyFeatures && this.stickyFeatures[key]) {
|
|
500
|
-
var variationValue = this.stickyFeatures[key].variation;
|
|
501
|
-
if (typeof variationValue !== "undefined") {
|
|
502
|
-
evaluation = {
|
|
503
|
-
featureKey: key,
|
|
504
|
-
reason: EvaluationReason.STICKY,
|
|
505
|
-
variationValue: variationValue,
|
|
506
|
-
};
|
|
507
|
-
this.logger.debug("using sticky variation", evaluation);
|
|
508
|
-
return evaluation;
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
// initial
|
|
512
|
-
if (this.statuses &&
|
|
513
|
-
!this.statuses.ready &&
|
|
514
|
-
this.initialFeatures &&
|
|
515
|
-
this.initialFeatures[key] &&
|
|
516
|
-
typeof this.initialFeatures[key].variation !== "undefined") {
|
|
517
|
-
var variationValue = this.initialFeatures[key].variation;
|
|
518
|
-
evaluation = {
|
|
519
|
-
featureKey: key,
|
|
520
|
-
reason: EvaluationReason.INITIAL,
|
|
521
|
-
variationValue: variationValue,
|
|
522
|
-
};
|
|
523
|
-
this.logger.debug("using initial variation", evaluation);
|
|
524
|
-
return evaluation;
|
|
525
|
-
}
|
|
526
|
-
var feature = this.getFeature(featureKey);
|
|
527
|
-
// not found
|
|
528
|
-
if (!feature) {
|
|
529
|
-
evaluation = {
|
|
530
|
-
featureKey: key,
|
|
531
|
-
reason: EvaluationReason.NOT_FOUND,
|
|
532
|
-
};
|
|
533
|
-
this.logger.warn("feature not found", evaluation);
|
|
534
|
-
return evaluation;
|
|
535
|
-
}
|
|
536
|
-
// no variations
|
|
537
|
-
if (!feature.variations || feature.variations.length === 0) {
|
|
538
|
-
evaluation = {
|
|
539
|
-
featureKey: key,
|
|
540
|
-
reason: EvaluationReason.NO_VARIATIONS,
|
|
541
|
-
};
|
|
542
|
-
this.logger.warn("no variations", evaluation);
|
|
543
|
-
return evaluation;
|
|
544
|
-
}
|
|
545
|
-
var finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
546
|
-
// forced
|
|
547
|
-
var _a = findForceFromFeature(feature, context, this.datafileReader, this.logger), force_1 = _a.force, forceIndex = _a.forceIndex;
|
|
548
|
-
if (force_1 && force_1.variation) {
|
|
549
|
-
var variation = feature.variations.find(function (v) { return v.value === force_1.variation; });
|
|
550
|
-
if (variation) {
|
|
551
|
-
evaluation = {
|
|
552
|
-
featureKey: feature.key,
|
|
553
|
-
reason: EvaluationReason.FORCED,
|
|
554
|
-
forceIndex: forceIndex,
|
|
555
|
-
force: force_1,
|
|
556
|
-
variation: variation,
|
|
557
|
-
};
|
|
558
|
-
this.logger.debug("forced variation found", evaluation);
|
|
559
|
-
return evaluation;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
// bucketing
|
|
563
|
-
var _b = this.getBucketValue(feature, finalContext), bucketKey = _b.bucketKey, bucketValue = _b.bucketValue;
|
|
564
|
-
var _c = getMatchedTrafficAndAllocation(feature.traffic, finalContext, bucketValue, this.datafileReader, this.logger), matchedTraffic_1 = _c.matchedTraffic, matchedAllocation_1 = _c.matchedAllocation;
|
|
565
|
-
if (matchedTraffic_1) {
|
|
566
|
-
// override from rule
|
|
567
|
-
if (matchedTraffic_1.variation) {
|
|
568
|
-
var variation = feature.variations.find(function (v) { return v.value === matchedTraffic_1.variation; });
|
|
569
|
-
if (variation) {
|
|
570
|
-
evaluation = {
|
|
571
|
-
featureKey: feature.key,
|
|
572
|
-
reason: EvaluationReason.RULE,
|
|
573
|
-
bucketKey: bucketKey,
|
|
574
|
-
bucketValue: bucketValue,
|
|
575
|
-
ruleKey: matchedTraffic_1.key,
|
|
576
|
-
traffic: matchedTraffic_1,
|
|
577
|
-
variation: variation,
|
|
578
|
-
};
|
|
579
|
-
this.logger.debug("override from rule", evaluation);
|
|
580
|
-
return evaluation;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
// regular allocation
|
|
584
|
-
if (matchedAllocation_1 && matchedAllocation_1.variation) {
|
|
585
|
-
var variation = feature.variations.find(function (v) { return v.value === matchedAllocation_1.variation; });
|
|
586
|
-
if (variation) {
|
|
587
|
-
evaluation = {
|
|
588
|
-
featureKey: feature.key,
|
|
589
|
-
reason: EvaluationReason.ALLOCATED,
|
|
590
|
-
bucketKey: bucketKey,
|
|
591
|
-
bucketValue: bucketValue,
|
|
592
|
-
ruleKey: matchedTraffic_1.key,
|
|
593
|
-
traffic: matchedTraffic_1,
|
|
594
|
-
variation: variation,
|
|
595
|
-
};
|
|
596
|
-
this.logger.debug("allocated variation", evaluation);
|
|
597
|
-
return evaluation;
|
|
598
|
-
}
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
// nothing matched
|
|
602
|
-
evaluation = {
|
|
603
|
-
featureKey: feature.key,
|
|
604
|
-
reason: EvaluationReason.NO_MATCH,
|
|
605
|
-
bucketKey: bucketKey,
|
|
606
|
-
bucketValue: bucketValue,
|
|
607
|
-
};
|
|
608
|
-
this.logger.debug("no matched variation", evaluation);
|
|
609
|
-
return evaluation;
|
|
610
|
-
}
|
|
611
|
-
catch (e) {
|
|
612
|
-
evaluation = {
|
|
613
|
-
featureKey: typeof featureKey === "string" ? featureKey : featureKey.key,
|
|
614
|
-
reason: EvaluationReason.ERROR,
|
|
615
|
-
error: e,
|
|
616
|
-
};
|
|
617
|
-
this.logger.error("error", evaluation);
|
|
618
|
-
return evaluation;
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
FeaturevisorInstance.prototype.getVariation = function (featureKey, context) {
|
|
622
|
-
if (context === void 0) { context = {}; }
|
|
623
|
-
try {
|
|
624
|
-
var evaluation = this.evaluateVariation(featureKey, context);
|
|
625
|
-
if (typeof evaluation.variationValue !== "undefined") {
|
|
626
|
-
return evaluation.variationValue;
|
|
627
|
-
}
|
|
628
|
-
if (evaluation.variation) {
|
|
629
|
-
return evaluation.variation.value;
|
|
630
|
-
}
|
|
631
|
-
return undefined;
|
|
632
|
-
}
|
|
633
|
-
catch (e) {
|
|
634
|
-
this.logger.error("getVariation", { featureKey: featureKey, error: e });
|
|
635
|
-
return undefined;
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
/**
|
|
639
|
-
* Activate
|
|
640
|
-
*/
|
|
641
|
-
FeaturevisorInstance.prototype.activate = function (featureKey, context) {
|
|
642
|
-
if (context === void 0) { context = {}; }
|
|
643
|
-
try {
|
|
644
|
-
var evaluation = this.evaluateVariation(featureKey, context);
|
|
645
|
-
var variationValue = evaluation.variation
|
|
646
|
-
? evaluation.variation.value
|
|
647
|
-
: evaluation.variationValue;
|
|
648
|
-
if (typeof variationValue === "undefined") {
|
|
649
|
-
return undefined;
|
|
650
|
-
}
|
|
651
|
-
var finalContext_2 = this.interceptContext ? this.interceptContext(context) : context;
|
|
652
|
-
var captureContext_1 = {};
|
|
653
|
-
var attributesForCapturing = this.datafileReader
|
|
654
|
-
.getAllAttributes()
|
|
655
|
-
.filter(function (a) { return a.capture === true; });
|
|
656
|
-
attributesForCapturing.forEach(function (a) {
|
|
657
|
-
if (typeof finalContext_2[a.key] !== "undefined") {
|
|
658
|
-
captureContext_1[a.key] = context[a.key];
|
|
659
|
-
}
|
|
660
|
-
});
|
|
661
|
-
this.emitter.emit("activation", featureKey, variationValue, finalContext_2, captureContext_1, evaluation);
|
|
662
|
-
return variationValue;
|
|
663
|
-
}
|
|
664
|
-
catch (e) {
|
|
665
|
-
this.logger.error("activate", { featureKey: featureKey, error: e });
|
|
666
|
-
return undefined;
|
|
667
|
-
}
|
|
668
|
-
};
|
|
669
|
-
/**
|
|
670
|
-
* Variable
|
|
671
|
-
*/
|
|
672
|
-
FeaturevisorInstance.prototype.evaluateVariable = function (featureKey, variableKey, context) {
|
|
673
|
-
var _this = this;
|
|
674
|
-
if (context === void 0) { context = {}; }
|
|
675
|
-
var evaluation;
|
|
676
|
-
try {
|
|
677
|
-
var key = typeof featureKey === "string" ? featureKey : featureKey.key;
|
|
678
|
-
var flag = this.evaluateFlag(featureKey, context);
|
|
679
|
-
if (flag.enabled === false) {
|
|
680
|
-
evaluation = {
|
|
681
|
-
featureKey: key,
|
|
682
|
-
reason: EvaluationReason.DISABLED,
|
|
683
|
-
};
|
|
684
|
-
this.logger.debug("feature is disabled", evaluation);
|
|
685
|
-
return evaluation;
|
|
686
|
-
}
|
|
687
|
-
// sticky
|
|
688
|
-
if (this.stickyFeatures && this.stickyFeatures[key]) {
|
|
689
|
-
var variables = this.stickyFeatures[key].variables;
|
|
690
|
-
if (variables) {
|
|
691
|
-
var result = variables[variableKey];
|
|
692
|
-
if (typeof result !== "undefined") {
|
|
693
|
-
evaluation = {
|
|
694
|
-
featureKey: key,
|
|
695
|
-
reason: EvaluationReason.STICKY,
|
|
696
|
-
variableKey: variableKey,
|
|
697
|
-
variableValue: result,
|
|
698
|
-
};
|
|
699
|
-
this.logger.debug("using sticky variable", evaluation);
|
|
700
|
-
return evaluation;
|
|
701
|
-
}
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
// initial
|
|
705
|
-
if (this.statuses &&
|
|
706
|
-
!this.statuses.ready &&
|
|
707
|
-
this.initialFeatures &&
|
|
708
|
-
this.initialFeatures[key]) {
|
|
709
|
-
var variables = this.initialFeatures[key].variables;
|
|
710
|
-
if (variables) {
|
|
711
|
-
if (typeof variables[variableKey] !== "undefined") {
|
|
712
|
-
evaluation = {
|
|
713
|
-
featureKey: key,
|
|
714
|
-
reason: EvaluationReason.INITIAL,
|
|
715
|
-
variableKey: variableKey,
|
|
716
|
-
variableValue: variables[variableKey],
|
|
717
|
-
};
|
|
718
|
-
this.logger.debug("using initial variable", evaluation);
|
|
719
|
-
return evaluation;
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
}
|
|
723
|
-
var feature = this.getFeature(featureKey);
|
|
724
|
-
// not found
|
|
725
|
-
if (!feature) {
|
|
726
|
-
evaluation = {
|
|
727
|
-
featureKey: key,
|
|
728
|
-
reason: EvaluationReason.NOT_FOUND,
|
|
729
|
-
variableKey: variableKey,
|
|
730
|
-
};
|
|
731
|
-
this.logger.warn("feature not found in datafile", evaluation);
|
|
732
|
-
return evaluation;
|
|
733
|
-
}
|
|
734
|
-
var variableSchema = Array.isArray(feature.variablesSchema)
|
|
735
|
-
? feature.variablesSchema.find(function (v) { return v.key === variableKey; })
|
|
736
|
-
: undefined;
|
|
737
|
-
// variable schema not found
|
|
738
|
-
if (!variableSchema) {
|
|
739
|
-
evaluation = {
|
|
740
|
-
featureKey: key,
|
|
741
|
-
reason: EvaluationReason.NOT_FOUND,
|
|
742
|
-
variableKey: variableKey,
|
|
743
|
-
};
|
|
744
|
-
this.logger.warn("variable schema not found", evaluation);
|
|
745
|
-
return evaluation;
|
|
746
|
-
}
|
|
747
|
-
var finalContext_3 = this.interceptContext ? this.interceptContext(context) : context;
|
|
748
|
-
// forced
|
|
749
|
-
var _a = findForceFromFeature(feature, context, this.datafileReader, this.logger), force = _a.force, forceIndex = _a.forceIndex;
|
|
750
|
-
if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {
|
|
751
|
-
evaluation = {
|
|
752
|
-
featureKey: feature.key,
|
|
753
|
-
reason: EvaluationReason.FORCED,
|
|
754
|
-
forceIndex: forceIndex,
|
|
755
|
-
force: force,
|
|
756
|
-
variableKey: variableKey,
|
|
757
|
-
variableSchema: variableSchema,
|
|
758
|
-
variableValue: force.variables[variableKey],
|
|
759
|
-
};
|
|
760
|
-
this.logger.debug("forced variable", evaluation);
|
|
761
|
-
return evaluation;
|
|
762
|
-
}
|
|
763
|
-
// bucketing
|
|
764
|
-
var _b = this.getBucketValue(feature, finalContext_3), bucketKey = _b.bucketKey, bucketValue = _b.bucketValue;
|
|
765
|
-
var _c = getMatchedTrafficAndAllocation(feature.traffic, finalContext_3, bucketValue, this.datafileReader, this.logger), matchedTraffic = _c.matchedTraffic, matchedAllocation = _c.matchedAllocation;
|
|
766
|
-
if (matchedTraffic) {
|
|
767
|
-
// override from rule
|
|
768
|
-
if (matchedTraffic.variables &&
|
|
769
|
-
typeof matchedTraffic.variables[variableKey] !== "undefined") {
|
|
770
|
-
evaluation = {
|
|
771
|
-
featureKey: feature.key,
|
|
772
|
-
reason: EvaluationReason.RULE,
|
|
773
|
-
bucketKey: bucketKey,
|
|
774
|
-
bucketValue: bucketValue,
|
|
775
|
-
ruleKey: matchedTraffic.key,
|
|
776
|
-
traffic: matchedTraffic,
|
|
777
|
-
variableKey: variableKey,
|
|
778
|
-
variableSchema: variableSchema,
|
|
779
|
-
variableValue: matchedTraffic.variables[variableKey],
|
|
780
|
-
};
|
|
781
|
-
this.logger.debug("override from rule", evaluation);
|
|
782
|
-
return evaluation;
|
|
783
|
-
}
|
|
784
|
-
// regular allocation
|
|
785
|
-
var variationValue_1;
|
|
786
|
-
if (force && force.variation) {
|
|
787
|
-
variationValue_1 = force.variation;
|
|
788
|
-
}
|
|
789
|
-
else if (matchedAllocation && matchedAllocation.variation) {
|
|
790
|
-
variationValue_1 = matchedAllocation.variation;
|
|
791
|
-
}
|
|
792
|
-
if (variationValue_1 && Array.isArray(feature.variations)) {
|
|
793
|
-
var variation = feature.variations.find(function (v) { return v.value === variationValue_1; });
|
|
794
|
-
if (variation && variation.variables) {
|
|
795
|
-
var variableFromVariation = variation.variables.find(function (v) { return v.key === variableKey; });
|
|
796
|
-
if (variableFromVariation) {
|
|
797
|
-
if (variableFromVariation.overrides) {
|
|
798
|
-
var override = variableFromVariation.overrides.find(function (o) {
|
|
799
|
-
if (o.conditions) {
|
|
800
|
-
return allConditionsAreMatched(typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions, finalContext_3, _this.logger);
|
|
801
|
-
}
|
|
802
|
-
if (o.segments) {
|
|
803
|
-
return allGroupSegmentsAreMatched(parseFromStringifiedSegments(o.segments), finalContext_3, _this.datafileReader, _this.logger);
|
|
804
|
-
}
|
|
805
|
-
return false;
|
|
806
|
-
});
|
|
807
|
-
if (override) {
|
|
808
|
-
evaluation = {
|
|
809
|
-
featureKey: feature.key,
|
|
810
|
-
reason: EvaluationReason.OVERRIDE,
|
|
811
|
-
bucketKey: bucketKey,
|
|
812
|
-
bucketValue: bucketValue,
|
|
813
|
-
ruleKey: matchedTraffic.key,
|
|
814
|
-
traffic: matchedTraffic,
|
|
815
|
-
variableKey: variableKey,
|
|
816
|
-
variableSchema: variableSchema,
|
|
817
|
-
variableValue: override.value,
|
|
818
|
-
};
|
|
819
|
-
this.logger.debug("variable override", evaluation);
|
|
820
|
-
return evaluation;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
if (typeof variableFromVariation.value !== "undefined") {
|
|
824
|
-
evaluation = {
|
|
825
|
-
featureKey: feature.key,
|
|
826
|
-
reason: EvaluationReason.ALLOCATED,
|
|
827
|
-
bucketKey: bucketKey,
|
|
828
|
-
bucketValue: bucketValue,
|
|
829
|
-
ruleKey: matchedTraffic.key,
|
|
830
|
-
traffic: matchedTraffic,
|
|
831
|
-
variableKey: variableKey,
|
|
832
|
-
variableSchema: variableSchema,
|
|
833
|
-
variableValue: variableFromVariation.value,
|
|
834
|
-
};
|
|
835
|
-
this.logger.debug("allocated variable", evaluation);
|
|
836
|
-
return evaluation;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
}
|
|
842
|
-
// fall back to default
|
|
843
|
-
evaluation = {
|
|
844
|
-
featureKey: feature.key,
|
|
845
|
-
reason: EvaluationReason.DEFAULTED,
|
|
846
|
-
bucketKey: bucketKey,
|
|
847
|
-
bucketValue: bucketValue,
|
|
848
|
-
variableKey: variableKey,
|
|
849
|
-
variableSchema: variableSchema,
|
|
850
|
-
variableValue: variableSchema.defaultValue,
|
|
851
|
-
};
|
|
852
|
-
this.logger.debug("using default value", evaluation);
|
|
853
|
-
return evaluation;
|
|
854
|
-
}
|
|
855
|
-
catch (e) {
|
|
856
|
-
evaluation = {
|
|
857
|
-
featureKey: typeof featureKey === "string" ? featureKey : featureKey.key,
|
|
858
|
-
reason: EvaluationReason.ERROR,
|
|
859
|
-
variableKey: variableKey,
|
|
860
|
-
error: e,
|
|
861
|
-
};
|
|
862
|
-
this.logger.error("error", evaluation);
|
|
863
|
-
return evaluation;
|
|
864
|
-
}
|
|
865
|
-
};
|
|
866
|
-
FeaturevisorInstance.prototype.getVariable = function (featureKey, variableKey, context) {
|
|
867
|
-
if (context === void 0) { context = {}; }
|
|
868
|
-
try {
|
|
869
|
-
var evaluation = this.evaluateVariable(featureKey, variableKey, context);
|
|
870
|
-
if (typeof evaluation.variableValue !== "undefined") {
|
|
871
|
-
if (evaluation.variableSchema &&
|
|
872
|
-
evaluation.variableSchema.type === "json" &&
|
|
873
|
-
typeof evaluation.variableValue === "string") {
|
|
874
|
-
return JSON.parse(evaluation.variableValue);
|
|
875
|
-
}
|
|
876
|
-
return evaluation.variableValue;
|
|
877
|
-
}
|
|
878
|
-
return undefined;
|
|
879
|
-
}
|
|
880
|
-
catch (e) {
|
|
881
|
-
this.logger.error("getVariable", { featureKey: featureKey, variableKey: variableKey, error: e });
|
|
882
|
-
return undefined;
|
|
883
|
-
}
|
|
884
|
-
};
|
|
885
|
-
FeaturevisorInstance.prototype.getVariableBoolean = function (featureKey, variableKey, context) {
|
|
886
|
-
if (context === void 0) { context = {}; }
|
|
887
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
888
|
-
return getValueByType(variableValue, "boolean");
|
|
889
|
-
};
|
|
890
|
-
FeaturevisorInstance.prototype.getVariableString = function (featureKey, variableKey, context) {
|
|
891
|
-
if (context === void 0) { context = {}; }
|
|
892
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
893
|
-
return getValueByType(variableValue, "string");
|
|
894
|
-
};
|
|
895
|
-
FeaturevisorInstance.prototype.getVariableInteger = function (featureKey, variableKey, context) {
|
|
896
|
-
if (context === void 0) { context = {}; }
|
|
897
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
898
|
-
return getValueByType(variableValue, "integer");
|
|
899
|
-
};
|
|
900
|
-
FeaturevisorInstance.prototype.getVariableDouble = function (featureKey, variableKey, context) {
|
|
901
|
-
if (context === void 0) { context = {}; }
|
|
902
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
903
|
-
return getValueByType(variableValue, "double");
|
|
904
|
-
};
|
|
905
|
-
FeaturevisorInstance.prototype.getVariableArray = function (featureKey, variableKey, context) {
|
|
906
|
-
if (context === void 0) { context = {}; }
|
|
907
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
908
|
-
return getValueByType(variableValue, "array");
|
|
909
|
-
};
|
|
910
|
-
FeaturevisorInstance.prototype.getVariableObject = function (featureKey, variableKey, context) {
|
|
911
|
-
if (context === void 0) { context = {}; }
|
|
912
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
913
|
-
return getValueByType(variableValue, "object");
|
|
914
|
-
};
|
|
915
|
-
FeaturevisorInstance.prototype.getVariableJSON = function (featureKey, variableKey, context) {
|
|
916
|
-
if (context === void 0) { context = {}; }
|
|
917
|
-
var variableValue = this.getVariable(featureKey, variableKey, context);
|
|
918
|
-
return getValueByType(variableValue, "json");
|
|
919
|
-
};
|
|
920
|
-
return FeaturevisorInstance;
|
|
921
|
-
}());
|
|
922
|
-
export { FeaturevisorInstance };
|
|
923
|
-
export function createInstance(options) {
|
|
924
|
-
return new FeaturevisorInstance(options);
|
|
925
|
-
}
|
|
926
|
-
//# sourceMappingURL=instance.js.map
|