@featurevisor/sdk 0.36.0 → 0.37.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 +11 -0
- package/README.md +14 -14
- package/coverage/clover.xml +224 -224
- package/coverage/coverage-final.json +4 -4
- package/coverage/lcov-report/bucket.ts.html +1 -1
- package/coverage/lcov-report/conditions.ts.html +38 -38
- 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 +7 -7
- package/coverage/lcov-report/index.html +1 -1
- package/coverage/lcov-report/instance.ts.html +74 -113
- package/coverage/lcov-report/logger.ts.html +1 -1
- package/coverage/lcov-report/segments.ts.html +10 -10
- package/coverage/lcov.info +391 -391
- package/dist/index.js +1 -1
- package/dist/index.js.gz +0 -0
- package/dist/index.js.map +1 -1
- package/lib/conditions.d.ts +3 -3
- package/lib/conditions.js +35 -35
- package/lib/conditions.js.map +1 -1
- package/lib/feature.d.ts +3 -3
- package/lib/feature.js +5 -5
- package/lib/feature.js.map +1 -1
- package/lib/instance.d.ts +27 -26
- package/lib/instance.js +80 -86
- package/lib/instance.js.map +1 -1
- package/lib/segments.d.ts +3 -3
- package/lib/segments.js +8 -8
- package/lib/segments.js.map +1 -1
- package/package.json +3 -3
- package/src/conditions.ts +37 -37
- package/src/feature.ts +6 -6
- package/src/instance.spec.ts +6 -6
- package/src/instance.ts +70 -83
- package/src/segments.ts +9 -9
|
@@ -1100,20 +1100,7 @@
|
|
|
1100
1100
|
<a name='L1035'></a><a href='#L1035'>1035</a>
|
|
1101
1101
|
<a name='L1036'></a><a href='#L1036'>1036</a>
|
|
1102
1102
|
<a name='L1037'></a><a href='#L1037'>1037</a>
|
|
1103
|
-
<a name='L1038'></a><a href='#L1038'>1038</a>
|
|
1104
|
-
<a name='L1039'></a><a href='#L1039'>1039</a>
|
|
1105
|
-
<a name='L1040'></a><a href='#L1040'>1040</a>
|
|
1106
|
-
<a name='L1041'></a><a href='#L1041'>1041</a>
|
|
1107
|
-
<a name='L1042'></a><a href='#L1042'>1042</a>
|
|
1108
|
-
<a name='L1043'></a><a href='#L1043'>1043</a>
|
|
1109
|
-
<a name='L1044'></a><a href='#L1044'>1044</a>
|
|
1110
|
-
<a name='L1045'></a><a href='#L1045'>1045</a>
|
|
1111
|
-
<a name='L1046'></a><a href='#L1046'>1046</a>
|
|
1112
|
-
<a name='L1047'></a><a href='#L1047'>1047</a>
|
|
1113
|
-
<a name='L1048'></a><a href='#L1048'>1048</a>
|
|
1114
|
-
<a name='L1049'></a><a href='#L1049'>1049</a>
|
|
1115
|
-
<a name='L1050'></a><a href='#L1050'>1050</a>
|
|
1116
|
-
<a name='L1051'></a><a href='#L1051'>1051</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
1103
|
+
<a name='L1038'></a><a href='#L1038'>1038</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span>
|
|
1117
1104
|
<span class="cline-any cline-neutral"> </span>
|
|
1118
1105
|
<span class="cline-any cline-neutral"> </span>
|
|
1119
1106
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1179,6 +1166,8 @@
|
|
|
1179
1166
|
<span class="cline-any cline-neutral"> </span>
|
|
1180
1167
|
<span class="cline-any cline-neutral"> </span>
|
|
1181
1168
|
<span class="cline-any cline-neutral"> </span>
|
|
1169
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1170
|
+
<span class="cline-any cline-neutral"> </span>
|
|
1182
1171
|
<span class="cline-any cline-yes">1x</span>
|
|
1183
1172
|
<span class="cline-any cline-neutral"> </span>
|
|
1184
1173
|
<span class="cline-any cline-neutral"> </span>
|
|
@@ -1595,8 +1584,6 @@
|
|
|
1595
1584
|
<span class="cline-any cline-yes">9x</span>
|
|
1596
1585
|
<span class="cline-any cline-neutral"> </span>
|
|
1597
1586
|
<span class="cline-any cline-neutral"> </span>
|
|
1598
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1599
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1600
1587
|
<span class="cline-any cline-yes">9x</span>
|
|
1601
1588
|
<span class="cline-any cline-neutral"> </span>
|
|
1602
1589
|
<span class="cline-any cline-yes">9x</span>
|
|
@@ -1735,27 +1722,18 @@
|
|
|
1735
1722
|
<span class="cline-any cline-neutral"> </span>
|
|
1736
1723
|
<span class="cline-any cline-neutral"> </span>
|
|
1737
1724
|
<span class="cline-any cline-neutral"> </span>
|
|
1738
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1739
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1740
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1741
1725
|
<span class="cline-any cline-no"> </span>
|
|
1742
1726
|
<span class="cline-any cline-neutral"> </span>
|
|
1743
1727
|
<span class="cline-any cline-no"> </span>
|
|
1744
1728
|
<span class="cline-any cline-neutral"> </span>
|
|
1745
1729
|
<span class="cline-any cline-neutral"> </span>
|
|
1746
1730
|
<span class="cline-any cline-neutral"> </span>
|
|
1747
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1748
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1749
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1750
1731
|
<span class="cline-any cline-no"> </span>
|
|
1751
1732
|
<span class="cline-any cline-neutral"> </span>
|
|
1752
1733
|
<span class="cline-any cline-no"> </span>
|
|
1753
1734
|
<span class="cline-any cline-neutral"> </span>
|
|
1754
1735
|
<span class="cline-any cline-neutral"> </span>
|
|
1755
1736
|
<span class="cline-any cline-neutral"> </span>
|
|
1756
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1757
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1758
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1759
1737
|
<span class="cline-any cline-no"> </span>
|
|
1760
1738
|
<span class="cline-any cline-neutral"> </span>
|
|
1761
1739
|
<span class="cline-any cline-no"> </span>
|
|
@@ -1777,8 +1755,6 @@
|
|
|
1777
1755
|
<span class="cline-any cline-neutral"> </span>
|
|
1778
1756
|
<span class="cline-any cline-yes">1x</span>
|
|
1779
1757
|
<span class="cline-any cline-neutral"> </span>
|
|
1780
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1781
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1782
1758
|
<span class="cline-any cline-yes">1x</span>
|
|
1783
1759
|
<span class="cline-any cline-neutral"> </span>
|
|
1784
1760
|
<span class="cline-any cline-yes">1x</span>
|
|
@@ -1919,8 +1895,6 @@
|
|
|
1919
1895
|
<span class="cline-any cline-no"> </span>
|
|
1920
1896
|
<span class="cline-any cline-neutral"> </span>
|
|
1921
1897
|
<span class="cline-any cline-neutral"> </span>
|
|
1922
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1923
|
-
<span class="cline-any cline-neutral"> </span>
|
|
1924
1898
|
<span class="cline-any cline-no"> </span>
|
|
1925
1899
|
<span class="cline-any cline-neutral"> </span>
|
|
1926
1900
|
<span class="cline-any cline-no"> </span>
|
|
@@ -2164,7 +2138,7 @@
|
|
|
2164
2138
|
<span class="cline-any cline-yes">10x</span>
|
|
2165
2139
|
<span class="cline-any cline-neutral"> </span>
|
|
2166
2140
|
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {
|
|
2167
|
-
|
|
2141
|
+
Context,
|
|
2168
2142
|
AttributeValue,
|
|
2169
2143
|
BucketKey,
|
|
2170
2144
|
BucketValue,
|
|
@@ -2196,13 +2170,13 @@ export type ReadyCallback = () => void;
|
|
|
2196
2170
|
export type ActivationCallback = (
|
|
2197
2171
|
featureName: string,
|
|
2198
2172
|
variation: VariationValue,
|
|
2199
|
-
|
|
2200
|
-
|
|
2173
|
+
context: Context,
|
|
2174
|
+
captureContext: Context,
|
|
2201
2175
|
) => void;
|
|
2202
2176
|
|
|
2203
|
-
export type ConfigureBucketKey = (feature,
|
|
2177
|
+
export type ConfigureBucketKey = (feature, context, bucketKey: BucketKey) => BucketKey;
|
|
2204
2178
|
|
|
2205
|
-
export type ConfigureBucketValue = (feature,
|
|
2179
|
+
export type ConfigureBucketValue = (feature, context, bucketValue: BucketValue) => BucketValue;
|
|
2206
2180
|
|
|
2207
2181
|
export interface Statuses {
|
|
2208
2182
|
ready: boolean;
|
|
@@ -2211,6 +2185,8 @@ export interface Statuses {
|
|
|
2211
2185
|
|
|
2212
2186
|
const DEFAULT_BUCKET_KEY_SEPARATOR = ".";
|
|
2213
2187
|
|
|
2188
|
+
export type InterceptContext = (context: Context) => Context;
|
|
2189
|
+
|
|
2214
2190
|
export interface InstanceOptions {
|
|
2215
2191
|
bucketKeySeparator?: string;
|
|
2216
2192
|
configureBucketKey?: ConfigureBucketKey;
|
|
@@ -2219,7 +2195,7 @@ export interface InstanceOptions {
|
|
|
2219
2195
|
datafileUrl?: string;
|
|
2220
2196
|
handleDatafileFetch?: (datafileUrl: string) => Promise<DatafileContent>;
|
|
2221
2197
|
initialFeatures?: InitialFeatures;
|
|
2222
|
-
|
|
2198
|
+
interceptContext?: InterceptContext;
|
|
2223
2199
|
logger?: Logger;
|
|
2224
2200
|
onActivation?: ActivationCallback;
|
|
2225
2201
|
onReady?: ReadyCallback;
|
|
@@ -2321,7 +2297,7 @@ export class FeaturevisorInstance {
|
|
|
2321
2297
|
private datafileUrl?: string;
|
|
2322
2298
|
private handleDatafileFetch?: DatafileFetchHandler;
|
|
2323
2299
|
private initialFeatures?: InitialFeatures;
|
|
2324
|
-
private
|
|
2300
|
+
private interceptContext?: InterceptContext;
|
|
2325
2301
|
private logger: Logger;
|
|
2326
2302
|
private refreshInterval?: number; // seconds
|
|
2327
2303
|
private stickyFeatures?: StickyFeatures;
|
|
@@ -2347,7 +2323,7 @@ export class FeaturevisorInstance {
|
|
|
2347
2323
|
this.datafileUrl = options.datafileUrl;
|
|
2348
2324
|
this.handleDatafileFetch = options.handleDatafileFetch;
|
|
2349
2325
|
this.initialFeatures = options.initialFeatures;
|
|
2350
|
-
this.
|
|
2326
|
+
this.interceptContext = options.interceptContext;
|
|
2351
2327
|
this.logger = options.logger || createLogger();
|
|
2352
2328
|
this.refreshInterval = options.refreshInterval;
|
|
2353
2329
|
this.stickyFeatures = options.stickyFeatures;
|
|
@@ -2446,7 +2422,7 @@ export class FeaturevisorInstance {
|
|
|
2446
2422
|
/**
|
|
2447
2423
|
* Bucketing
|
|
2448
2424
|
*/
|
|
2449
|
-
private getBucketKey(feature: Feature,
|
|
2425
|
+
private getBucketKey(feature: Feature, context: Context): BucketKey {
|
|
2450
2426
|
const featureKey = feature.key;
|
|
2451
2427
|
|
|
2452
2428
|
let type;
|
|
@@ -2470,7 +2446,7 @@ export class FeaturevisorInstance {
|
|
|
2470
2446
|
const bucketKey: AttributeValue[] = [];
|
|
2471
2447
|
|
|
2472
2448
|
attributeKeys.forEach((attributeKey) => {
|
|
2473
|
-
const attributeValue =
|
|
2449
|
+
const attributeValue = context[attributeKey];
|
|
2474
2450
|
|
|
2475
2451
|
if (typeof attributeValue === "undefined") {
|
|
2476
2452
|
return;
|
|
@@ -2491,19 +2467,19 @@ export class FeaturevisorInstance {
|
|
|
2491
2467
|
const result = bucketKey.join(this.bucketKeySeparator);
|
|
2492
2468
|
|
|
2493
2469
|
if (this.configureBucketKey) {
|
|
2494
|
-
return this.configureBucketKey(feature,
|
|
2470
|
+
return this.configureBucketKey(feature, context, result);
|
|
2495
2471
|
}
|
|
2496
2472
|
|
|
2497
2473
|
return result;
|
|
2498
2474
|
}
|
|
2499
2475
|
|
|
2500
|
-
private getBucketValue(feature: Feature,
|
|
2501
|
-
const bucketKey = this.getBucketKey(feature,
|
|
2476
|
+
private getBucketValue(feature: Feature, context: Context): BucketValue {
|
|
2477
|
+
const bucketKey = this.getBucketKey(feature, context);
|
|
2502
2478
|
|
|
2503
2479
|
const value = getBucketedNumber(bucketKey);
|
|
2504
2480
|
|
|
2505
2481
|
<span class="missing-if-branch" title="if path not taken" >I</span>if (this.configureBucketValue) {
|
|
2506
|
-
<span class="cstat-no" title="statement not covered" > return this.configureBucketValue(feature,
|
|
2482
|
+
<span class="cstat-no" title="statement not covered" > return this.configureBucketValue(feature, context, value);</span>
|
|
2507
2483
|
}
|
|
2508
2484
|
|
|
2509
2485
|
return value;
|
|
@@ -2584,7 +2560,7 @@ export class FeaturevisorInstance {
|
|
|
2584
2560
|
/**
|
|
2585
2561
|
* Variation
|
|
2586
2562
|
*/
|
|
2587
|
-
evaluateVariation(featureKey: FeatureKey | Feature,
|
|
2563
|
+
evaluateVariation(featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: Evaluation {
|
|
2588
2564
|
let evaluation: Evaluation;
|
|
2589
2565
|
|
|
2590
2566
|
try {
|
|
@@ -2642,12 +2618,10 @@ export class FeaturevisorInstance {
|
|
|
2642
2618
|
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2643
2619
|
}
|
|
2644
2620
|
|
|
2645
|
-
const
|
|
2646
|
-
? this.interceptAttributes(attributes)
|
|
2647
|
-
: attributes;
|
|
2621
|
+
const finalContext = this.interceptContext ? this.interceptContext(context) : context;
|
|
2648
2622
|
|
|
2649
2623
|
// forced
|
|
2650
|
-
const force = findForceFromFeature(feature,
|
|
2624
|
+
const force = findForceFromFeature(feature, context, this.datafileReader);
|
|
2651
2625
|
|
|
2652
2626
|
<span class="missing-if-branch" title="if path not taken" >I</span>if (force && <span class="branch-1 cbranch-no" title="branch not covered" >force.variation)</span> {
|
|
2653
2627
|
const variation = <span class="cstat-no" title="statement not covered" >feature.variations.find(<span class="fstat-no" title="function not covered" >(v</span>) => <span class="cstat-no" title="statement not covered" >v.value === force.variation)</span>;</span>
|
|
@@ -2666,11 +2640,11 @@ export class FeaturevisorInstance {
|
|
|
2666
2640
|
}
|
|
2667
2641
|
|
|
2668
2642
|
// bucketing
|
|
2669
|
-
const bucketValue = this.getBucketValue(feature,
|
|
2643
|
+
const bucketValue = this.getBucketValue(feature, finalContext);
|
|
2670
2644
|
|
|
2671
2645
|
const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
|
|
2672
2646
|
feature.traffic,
|
|
2673
|
-
|
|
2647
|
+
finalContext,
|
|
2674
2648
|
bucketValue,
|
|
2675
2649
|
this.datafileReader,
|
|
2676
2650
|
this.logger,
|
|
@@ -2754,10 +2728,10 @@ export class FeaturevisorInstance {
|
|
|
2754
2728
|
|
|
2755
2729
|
getVariation(
|
|
2756
2730
|
featureKey: FeatureKey | Feature,
|
|
2757
|
-
|
|
2731
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2758
2732
|
): VariationValue | undefined {
|
|
2759
2733
|
try {
|
|
2760
|
-
const evaluation = this.evaluateVariation(featureKey,
|
|
2734
|
+
const evaluation = this.evaluateVariation(featureKey, context);
|
|
2761
2735
|
|
|
2762
2736
|
if (typeof evaluation.variationValue !== "undefined") {
|
|
2763
2737
|
return evaluation.variationValue;
|
|
@@ -2777,36 +2751,27 @@ export class FeaturevisorInstance {
|
|
|
2777
2751
|
|
|
2778
2752
|
<span class="fstat-no" title="function not covered" > getVariationBoolean(</span>
|
|
2779
2753
|
featureKey: FeatureKey | Feature,
|
|
2780
|
-
|
|
2754
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2781
2755
|
): boolean | undefined {
|
|
2782
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey,
|
|
2756
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, context);</span>
|
|
2783
2757
|
|
|
2784
2758
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "boolean") as boolean | undefined;</span>
|
|
2785
2759
|
}
|
|
2786
2760
|
|
|
2787
|
-
<span class="fstat-no" title="function not covered" > getVariationString(</span>
|
|
2788
|
-
|
|
2789
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2790
|
-
): string | undefined {
|
|
2791
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2761
|
+
<span class="fstat-no" title="function not covered" > getVariationString(</span>featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: string | undefined {
|
|
2762
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, context);</span>
|
|
2792
2763
|
|
|
2793
2764
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "string") as string | undefined;</span>
|
|
2794
2765
|
}
|
|
2795
2766
|
|
|
2796
|
-
<span class="fstat-no" title="function not covered" > getVariationInteger(</span>
|
|
2797
|
-
|
|
2798
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2799
|
-
): number | undefined {
|
|
2800
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2767
|
+
<span class="fstat-no" title="function not covered" > getVariationInteger(</span>featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
2768
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, context);</span>
|
|
2801
2769
|
|
|
2802
2770
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "integer") as number | undefined;</span>
|
|
2803
2771
|
}
|
|
2804
2772
|
|
|
2805
|
-
<span class="fstat-no" title="function not covered" > getVariationDouble(</span>
|
|
2806
|
-
|
|
2807
|
-
attributes: Attributes = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2808
|
-
): number | undefined {
|
|
2809
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, attributes);</span>
|
|
2773
|
+
<span class="fstat-no" title="function not covered" > getVariationDouble(</span>featureKey: FeatureKey | Feature, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
2774
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.getVariation(featureKey, context);</span>
|
|
2810
2775
|
|
|
2811
2776
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "double") as number | undefined;</span>
|
|
2812
2777
|
}
|
|
@@ -2814,9 +2779,9 @@ export class FeaturevisorInstance {
|
|
|
2814
2779
|
/**
|
|
2815
2780
|
* Activate
|
|
2816
2781
|
*/
|
|
2817
|
-
activate(featureKey: FeatureKey,
|
|
2782
|
+
activate(featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: VariationValue | undefined {
|
|
2818
2783
|
try {
|
|
2819
|
-
const evaluation = this.evaluateVariation(featureKey,
|
|
2784
|
+
const evaluation = this.evaluateVariation(featureKey, context);
|
|
2820
2785
|
const variationValue = evaluation.variation
|
|
2821
2786
|
? evaluation.variation.value
|
|
2822
2787
|
: <span class="branch-1 cbranch-no" title="branch not covered" >evaluation.variationValue;</span>
|
|
@@ -2825,19 +2790,17 @@ export class FeaturevisorInstance {
|
|
|
2825
2790
|
<span class="cstat-no" title="statement not covered" > return undefined;</span>
|
|
2826
2791
|
}
|
|
2827
2792
|
|
|
2828
|
-
const
|
|
2829
|
-
? <span class="branch-0 cbranch-no" title="branch not covered" >this.interceptAttributes(attributes)</span>
|
|
2830
|
-
: attributes;
|
|
2793
|
+
const finalContext = this.interceptContext ? <span class="branch-0 cbranch-no" title="branch not covered" >this.interceptContext(context) </span>: context;
|
|
2831
2794
|
|
|
2832
|
-
const
|
|
2795
|
+
const captureContext: Context = {};
|
|
2833
2796
|
|
|
2834
2797
|
const attributesForCapturing = this.datafileReader
|
|
2835
2798
|
.getAllAttributes()
|
|
2836
2799
|
.filter(<span class="fstat-no" title="function not covered" >(a</span>) => <span class="cstat-no" title="statement not covered" >a.capture === true)</span>;
|
|
2837
2800
|
|
|
2838
2801
|
attributesForCapturing.forEach(<span class="fstat-no" title="function not covered" >(a</span>) => {
|
|
2839
|
-
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof
|
|
2840
|
-
<span class="cstat-no" title="statement not covered" >
|
|
2802
|
+
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof finalContext[a.key] !== "undefined") {</span>
|
|
2803
|
+
<span class="cstat-no" title="statement not covered" > captureContext[a.key] = context[a.key];</span>
|
|
2841
2804
|
}
|
|
2842
2805
|
});
|
|
2843
2806
|
|
|
@@ -2845,8 +2808,8 @@ export class FeaturevisorInstance {
|
|
|
2845
2808
|
"activation",
|
|
2846
2809
|
featureKey,
|
|
2847
2810
|
variationValue,
|
|
2848
|
-
|
|
2849
|
-
|
|
2811
|
+
finalContext,
|
|
2812
|
+
captureContext,
|
|
2850
2813
|
evaluation,
|
|
2851
2814
|
);
|
|
2852
2815
|
|
|
@@ -2858,26 +2821,26 @@ export class FeaturevisorInstance {
|
|
|
2858
2821
|
}
|
|
2859
2822
|
}
|
|
2860
2823
|
|
|
2861
|
-
<span class="fstat-no" title="function not covered" > activateBoolean(</span>featureKey: FeatureKey,
|
|
2862
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
2824
|
+
<span class="fstat-no" title="function not covered" > activateBoolean(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: boolean | undefined {
|
|
2825
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2863
2826
|
|
|
2864
2827
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "boolean") as boolean | undefined;</span>
|
|
2865
2828
|
}
|
|
2866
2829
|
|
|
2867
|
-
<span class="fstat-no" title="function not covered" > activateString(</span>featureKey: FeatureKey,
|
|
2868
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
2830
|
+
<span class="fstat-no" title="function not covered" > activateString(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: string | undefined {
|
|
2831
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2869
2832
|
|
|
2870
2833
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "string") as string | undefined;</span>
|
|
2871
2834
|
}
|
|
2872
2835
|
|
|
2873
|
-
<span class="fstat-no" title="function not covered" > activateInteger(</span>featureKey: FeatureKey,
|
|
2874
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
2836
|
+
<span class="fstat-no" title="function not covered" > activateInteger(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
2837
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2875
2838
|
|
|
2876
2839
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "integer") as number | undefined;</span>
|
|
2877
2840
|
}
|
|
2878
2841
|
|
|
2879
|
-
<span class="fstat-no" title="function not covered" > activateDouble(</span>featureKey: FeatureKey,
|
|
2880
|
-
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey,
|
|
2842
|
+
<span class="fstat-no" title="function not covered" > activateDouble(</span>featureKey: FeatureKey, context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{})</span>: number | undefined {
|
|
2843
|
+
const variationValue = <span class="cstat-no" title="statement not covered" >this.activate(featureKey, context);</span>
|
|
2881
2844
|
|
|
2882
2845
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variationValue, "double") as number | undefined;</span>
|
|
2883
2846
|
}
|
|
@@ -2888,7 +2851,7 @@ export class FeaturevisorInstance {
|
|
|
2888
2851
|
<span class="fstat-no" title="function not covered" > evaluateVariable(</span>
|
|
2889
2852
|
featureKey: FeatureKey | Feature,
|
|
2890
2853
|
variableKey: VariableKey,
|
|
2891
|
-
|
|
2854
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
2892
2855
|
): Evaluation {
|
|
2893
2856
|
let evaluation: Evaluation;
|
|
2894
2857
|
|
|
@@ -2966,12 +2929,10 @@ export class FeaturevisorInstance {
|
|
|
2966
2929
|
<span class="cstat-no" title="statement not covered" > return evaluation;</span>
|
|
2967
2930
|
}
|
|
2968
2931
|
|
|
2969
|
-
const
|
|
2970
|
-
? this.interceptAttributes(attributes)
|
|
2971
|
-
: attributes;
|
|
2932
|
+
const finalContext = <span class="cstat-no" title="statement not covered" >this.interceptContext ? this.interceptContext(context) : context;</span>
|
|
2972
2933
|
|
|
2973
2934
|
// forced
|
|
2974
|
-
const force = <span class="cstat-no" title="statement not covered" >findForceFromFeature(feature,
|
|
2935
|
+
const force = <span class="cstat-no" title="statement not covered" >findForceFromFeature(feature, context, this.datafileReader);</span>
|
|
2975
2936
|
|
|
2976
2937
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {</span>
|
|
2977
2938
|
<span class="cstat-no" title="statement not covered" > evaluation = {</span>
|
|
@@ -2988,11 +2949,11 @@ export class FeaturevisorInstance {
|
|
|
2988
2949
|
}
|
|
2989
2950
|
|
|
2990
2951
|
// bucketing
|
|
2991
|
-
const bucketValue = <span class="cstat-no" title="statement not covered" >this.getBucketValue(feature,
|
|
2952
|
+
const bucketValue = <span class="cstat-no" title="statement not covered" >this.getBucketValue(feature, finalContext);</span>
|
|
2992
2953
|
|
|
2993
2954
|
const { matchedTraffic, matchedAllocation } = <span class="cstat-no" title="statement not covered" >getMatchedTrafficAndAllocation(</span>
|
|
2994
2955
|
feature.traffic,
|
|
2995
|
-
|
|
2956
|
+
finalContext,
|
|
2996
2957
|
bucketValue,
|
|
2997
2958
|
this.datafileReader,
|
|
2998
2959
|
this.logger,
|
|
@@ -3032,7 +2993,7 @@ export class FeaturevisorInstance {
|
|
|
3032
2993
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (o.conditions) {</span>
|
|
3033
2994
|
<span class="cstat-no" title="statement not covered" > return allConditionsAreMatched(</span>
|
|
3034
2995
|
typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
|
|
3035
|
-
|
|
2996
|
+
finalContext,
|
|
3036
2997
|
);
|
|
3037
2998
|
}
|
|
3038
2999
|
|
|
@@ -3041,7 +3002,7 @@ export class FeaturevisorInstance {
|
|
|
3041
3002
|
typeof o.segments === "string" && o.segments !== "*"
|
|
3042
3003
|
? JSON.parse(o.segments)
|
|
3043
3004
|
: o.segments,
|
|
3044
|
-
|
|
3005
|
+
finalContext,
|
|
3045
3006
|
this.datafileReader,
|
|
3046
3007
|
);
|
|
3047
3008
|
}
|
|
@@ -3114,10 +3075,10 @@ export class FeaturevisorInstance {
|
|
|
3114
3075
|
<span class="fstat-no" title="function not covered" > getVariable(</span>
|
|
3115
3076
|
featureKey: FeatureKey | Feature,
|
|
3116
3077
|
variableKey: string,
|
|
3117
|
-
|
|
3078
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3118
3079
|
): VariableValue | undefined {
|
|
3119
3080
|
<span class="cstat-no" title="statement not covered" > try {</span>
|
|
3120
|
-
const evaluation = <span class="cstat-no" title="statement not covered" >this.evaluateVariable(featureKey, variableKey,
|
|
3081
|
+
const evaluation = <span class="cstat-no" title="statement not covered" >this.evaluateVariable(featureKey, variableKey, context);</span>
|
|
3121
3082
|
|
|
3122
3083
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (typeof evaluation.variableValue !== "undefined") {</span>
|
|
3123
3084
|
<span class="cstat-no" title="statement not covered" > <span class="missing-if-branch" title="if path not taken" >I</span>if (</span>
|
|
@@ -3142,9 +3103,9 @@ export class FeaturevisorInstance {
|
|
|
3142
3103
|
<span class="fstat-no" title="function not covered" > getVariableBoolean(</span>
|
|
3143
3104
|
featureKey: FeatureKey | Feature,
|
|
3144
3105
|
variableKey: string,
|
|
3145
|
-
|
|
3106
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3146
3107
|
): boolean | undefined {
|
|
3147
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3108
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3148
3109
|
|
|
3149
3110
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "boolean") as boolean | undefined;</span>
|
|
3150
3111
|
}
|
|
@@ -3152,9 +3113,9 @@ export class FeaturevisorInstance {
|
|
|
3152
3113
|
<span class="fstat-no" title="function not covered" > getVariableString(</span>
|
|
3153
3114
|
featureKey: FeatureKey | Feature,
|
|
3154
3115
|
variableKey: string,
|
|
3155
|
-
|
|
3116
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3156
3117
|
): string | undefined {
|
|
3157
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3118
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3158
3119
|
|
|
3159
3120
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "string") as string | undefined;</span>
|
|
3160
3121
|
}
|
|
@@ -3162,9 +3123,9 @@ export class FeaturevisorInstance {
|
|
|
3162
3123
|
<span class="fstat-no" title="function not covered" > getVariableInteger(</span>
|
|
3163
3124
|
featureKey: FeatureKey | Feature,
|
|
3164
3125
|
variableKey: string,
|
|
3165
|
-
|
|
3126
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3166
3127
|
): number | undefined {
|
|
3167
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3128
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3168
3129
|
|
|
3169
3130
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "integer") as number | undefined;</span>
|
|
3170
3131
|
}
|
|
@@ -3172,9 +3133,9 @@ export class FeaturevisorInstance {
|
|
|
3172
3133
|
<span class="fstat-no" title="function not covered" > getVariableDouble(</span>
|
|
3173
3134
|
featureKey: FeatureKey | Feature,
|
|
3174
3135
|
variableKey: string,
|
|
3175
|
-
|
|
3136
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3176
3137
|
): number | undefined {
|
|
3177
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3138
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3178
3139
|
|
|
3179
3140
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "double") as number | undefined;</span>
|
|
3180
3141
|
}
|
|
@@ -3182,9 +3143,9 @@ export class FeaturevisorInstance {
|
|
|
3182
3143
|
<span class="fstat-no" title="function not covered" > getVariableArray(</span>
|
|
3183
3144
|
featureKey: FeatureKey | Feature,
|
|
3184
3145
|
variableKey: string,
|
|
3185
|
-
|
|
3146
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3186
3147
|
): string[] | undefined {
|
|
3187
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3148
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3188
3149
|
|
|
3189
3150
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "array") as string[] | undefined;</span>
|
|
3190
3151
|
}
|
|
@@ -3192,9 +3153,9 @@ export class FeaturevisorInstance {
|
|
|
3192
3153
|
<span class="fstat-no" title="function not covered" > getVariableObject<</span>T>(
|
|
3193
3154
|
featureKey: FeatureKey | Feature,
|
|
3194
3155
|
variableKey: string,
|
|
3195
|
-
|
|
3156
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3196
3157
|
): T | undefined {
|
|
3197
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3158
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3198
3159
|
|
|
3199
3160
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "object") as T | undefined;</span>
|
|
3200
3161
|
}
|
|
@@ -3202,9 +3163,9 @@ export class FeaturevisorInstance {
|
|
|
3202
3163
|
<span class="fstat-no" title="function not covered" > getVariableJSON<</span>T>(
|
|
3203
3164
|
featureKey: FeatureKey | Feature,
|
|
3204
3165
|
variableKey: string,
|
|
3205
|
-
|
|
3166
|
+
context: Context = <span class="branch-0 cbranch-no" title="branch not covered" >{},</span>
|
|
3206
3167
|
): T | undefined {
|
|
3207
|
-
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey,
|
|
3168
|
+
const variableValue = <span class="cstat-no" title="statement not covered" >this.getVariable(featureKey, variableKey, context);</span>
|
|
3208
3169
|
|
|
3209
3170
|
<span class="cstat-no" title="statement not covered" > return getValueByType(variableValue, "json") as T | undefined;</span>
|
|
3210
3171
|
}
|
|
@@ -3220,7 +3181,7 @@ export function createInstance(options: InstanceOptions): FeaturevisorInstance {
|
|
|
3220
3181
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
3221
3182
|
Code coverage generated by
|
|
3222
3183
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
3223
|
-
at 2023-07-
|
|
3184
|
+
at 2023-07-14T17:03:15.956Z
|
|
3224
3185
|
</div>
|
|
3225
3186
|
<script src="prettify.js"></script>
|
|
3226
3187
|
<script>
|
|
@@ -328,7 +328,7 @@ export function createLogger(options: CreateLoggerOptions = {}): Logger {
|
|
|
328
328
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
329
329
|
Code coverage generated by
|
|
330
330
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
331
|
-
at 2023-07-
|
|
331
|
+
at 2023-07-14T17:03:15.956Z
|
|
332
332
|
</div>
|
|
333
333
|
<script src="prettify.js"></script>
|
|
334
334
|
<script>
|
|
@@ -175,17 +175,17 @@
|
|
|
175
175
|
<span class="cline-any cline-neutral"> </span>
|
|
176
176
|
<span class="cline-any cline-no"> </span>
|
|
177
177
|
<span class="cline-any cline-neutral"> </span>
|
|
178
|
-
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import {
|
|
178
|
+
<span class="cline-any cline-neutral"> </span></td><td class="text"><pre class="prettyprint lang-js">import { Context, GroupSegment, Segment, Condition } from "@featurevisor/types";
|
|
179
179
|
import { allConditionsAreMatched } from "./conditions";
|
|
180
180
|
import { DatafileReader } from "./datafileReader";
|
|
181
181
|
|
|
182
|
-
export function segmentIsMatched(segment: Segment,
|
|
183
|
-
return allConditionsAreMatched(segment.conditions as Condition | Condition[],
|
|
182
|
+
export function segmentIsMatched(segment: Segment, context: Context): boolean {
|
|
183
|
+
return allConditionsAreMatched(segment.conditions as Condition | Condition[], context);
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
export function allGroupSegmentsAreMatched(
|
|
187
187
|
groupSegments: GroupSegment | GroupSegment[] | "*",
|
|
188
|
-
|
|
188
|
+
context: Context,
|
|
189
189
|
datafileReader: DatafileReader,
|
|
190
190
|
): boolean {
|
|
191
191
|
if (groupSegments === "*") {
|
|
@@ -196,7 +196,7 @@ export function allGroupSegmentsAreMatched(
|
|
|
196
196
|
const segment = datafileReader.getSegment(groupSegments);
|
|
197
197
|
|
|
198
198
|
if (segment) {
|
|
199
|
-
return segmentIsMatched(segment,
|
|
199
|
+
return segmentIsMatched(segment, context);
|
|
200
200
|
}
|
|
201
201
|
|
|
202
202
|
<span class="cstat-no" title="statement not covered" > return false;</span>
|
|
@@ -205,27 +205,27 @@ export function allGroupSegmentsAreMatched(
|
|
|
205
205
|
if (typeof groupSegments === "object") {
|
|
206
206
|
<span class="missing-if-branch" title="if path not taken" >I</span>if ("and" in groupSegments && <span class="branch-1 cbranch-no" title="branch not covered" >Array.isArray(groupSegments.and))</span> {
|
|
207
207
|
<span class="cstat-no" title="statement not covered" > return groupSegments.and.every(<span class="fstat-no" title="function not covered" >(g</span>roupSegment) =></span>
|
|
208
|
-
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment,
|
|
208
|
+
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment, context, datafileReader),</span>
|
|
209
209
|
);
|
|
210
210
|
}
|
|
211
211
|
|
|
212
212
|
<span class="missing-if-branch" title="if path not taken" >I</span>if ("or" in groupSegments && <span class="branch-1 cbranch-no" title="branch not covered" >Array.isArray(groupSegments.or))</span> {
|
|
213
213
|
<span class="cstat-no" title="statement not covered" > return groupSegments.or.some(<span class="fstat-no" title="function not covered" >(g</span>roupSegment) =></span>
|
|
214
|
-
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment,
|
|
214
|
+
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment, context, datafileReader),</span>
|
|
215
215
|
);
|
|
216
216
|
}
|
|
217
217
|
|
|
218
218
|
<span class="missing-if-branch" title="if path not taken" >I</span>if ("not" in groupSegments && <span class="branch-1 cbranch-no" title="branch not covered" >Array.isArray(groupSegments.not))</span> {
|
|
219
219
|
<span class="cstat-no" title="statement not covered" > return groupSegments.not.every(</span>
|
|
220
220
|
<span class="fstat-no" title="function not covered" > (g</span>roupSegment) =>
|
|
221
|
-
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment,
|
|
221
|
+
<span class="cstat-no" title="statement not covered" > allGroupSegmentsAreMatched(groupSegment, context, datafileReader) === false,</span>
|
|
222
222
|
);
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
|
|
226
226
|
if (Array.isArray(groupSegments)) {
|
|
227
227
|
return groupSegments.every((groupSegment) =>
|
|
228
|
-
allGroupSegmentsAreMatched(groupSegment,
|
|
228
|
+
allGroupSegmentsAreMatched(groupSegment, context, datafileReader),
|
|
229
229
|
);
|
|
230
230
|
}
|
|
231
231
|
|
|
@@ -238,7 +238,7 @@ export function allGroupSegmentsAreMatched(
|
|
|
238
238
|
<div class='footer quiet pad2 space-top1 center small'>
|
|
239
239
|
Code coverage generated by
|
|
240
240
|
<a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
|
|
241
|
-
at 2023-07-
|
|
241
|
+
at 2023-07-14T17:03:15.956Z
|
|
242
242
|
</div>
|
|
243
243
|
<script src="prettify.js"></script>
|
|
244
244
|
<script>
|