@featurevisor/sdk 0.35.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/src/conditions.ts CHANGED
@@ -1,71 +1,71 @@
1
1
  import { compareVersions } from "compare-versions";
2
2
 
3
- import { Attributes, Condition, PlainCondition } from "@featurevisor/types";
3
+ import { Context, Condition, PlainCondition } from "@featurevisor/types";
4
4
 
5
- export function conditionIsMatched(condition: PlainCondition, attributes: Attributes): boolean {
5
+ export function conditionIsMatched(condition: PlainCondition, context: Context): boolean {
6
6
  const { attribute, operator, value } = condition;
7
7
 
8
8
  if (operator === "equals") {
9
- return attributes[attribute] === value;
9
+ return context[attribute] === value;
10
10
  } else if (operator === "notEquals") {
11
- return attributes[attribute] !== value;
11
+ return context[attribute] !== value;
12
12
  } else if (operator === "before" || operator === "after") {
13
13
  // date comparisons
14
- const valueInAttributes = attributes[attribute] as string | Date;
14
+ const valueInContext = context[attribute] as string | Date;
15
15
 
16
- const dateInAttributes =
17
- valueInAttributes instanceof Date ? valueInAttributes : new Date(valueInAttributes);
16
+ const dateInContext =
17
+ valueInContext instanceof Date ? valueInContext : new Date(valueInContext);
18
18
  const dateInCondition = value instanceof Date ? value : new Date(value as string);
19
19
 
20
20
  return operator === "before"
21
- ? dateInAttributes < dateInCondition
22
- : dateInAttributes > dateInCondition;
23
- } else if (typeof attributes[attribute] === "string" && Array.isArray(value)) {
21
+ ? dateInContext < dateInCondition
22
+ : dateInContext > dateInCondition;
23
+ } else if (typeof context[attribute] === "string" && Array.isArray(value)) {
24
24
  // array
25
- const valueInAttributes = attributes[attribute] as string;
25
+ const valueInContext = context[attribute] as string;
26
26
 
27
27
  if (operator === "in") {
28
- return value.indexOf(valueInAttributes) !== -1;
28
+ return value.indexOf(valueInContext) !== -1;
29
29
  } else if (operator === "notIn") {
30
- return value.indexOf(valueInAttributes) === -1;
30
+ return value.indexOf(valueInContext) === -1;
31
31
  }
32
- } else if (typeof attributes[attribute] === "string" && typeof value === "string") {
32
+ } else if (typeof context[attribute] === "string" && typeof value === "string") {
33
33
  // string
34
- const valueInAttributes = attributes[attribute] as string;
34
+ const valueInContext = context[attribute] as string;
35
35
 
36
36
  if (operator === "contains") {
37
- return valueInAttributes.indexOf(value) !== -1;
37
+ return valueInContext.indexOf(value) !== -1;
38
38
  } else if (operator === "notContains") {
39
- return valueInAttributes.indexOf(value) === -1;
39
+ return valueInContext.indexOf(value) === -1;
40
40
  } else if (operator === "startsWith") {
41
- return valueInAttributes.startsWith(value);
41
+ return valueInContext.startsWith(value);
42
42
  } else if (operator === "endsWith") {
43
- return valueInAttributes.endsWith(value);
43
+ return valueInContext.endsWith(value);
44
44
  } else if (operator === "semverEquals") {
45
- return compareVersions(valueInAttributes, value) === 0;
45
+ return compareVersions(valueInContext, value) === 0;
46
46
  } else if (operator === "semverNotEquals") {
47
- return compareVersions(valueInAttributes, value) !== 0;
47
+ return compareVersions(valueInContext, value) !== 0;
48
48
  } else if (operator === "semverGreaterThan") {
49
- return compareVersions(valueInAttributes, value) === 1;
49
+ return compareVersions(valueInContext, value) === 1;
50
50
  } else if (operator === "semverGreaterThanOrEquals") {
51
- return compareVersions(valueInAttributes, value) >= 0;
51
+ return compareVersions(valueInContext, value) >= 0;
52
52
  } else if (operator === "semverLessThan") {
53
- return compareVersions(valueInAttributes, value) === -1;
53
+ return compareVersions(valueInContext, value) === -1;
54
54
  } else if (operator === "semverLessThanOrEquals") {
55
- return compareVersions(valueInAttributes, value) <= 0;
55
+ return compareVersions(valueInContext, value) <= 0;
56
56
  }
57
- } else if (typeof attributes[attribute] === "number" && typeof value === "number") {
57
+ } else if (typeof context[attribute] === "number" && typeof value === "number") {
58
58
  // numeric
59
- const valueInAttributes = attributes[attribute] as number;
59
+ const valueInContext = context[attribute] as number;
60
60
 
61
61
  if (operator === "greaterThan") {
62
- return valueInAttributes > value;
62
+ return valueInContext > value;
63
63
  } else if (operator === "greaterThanOrEquals") {
64
- return valueInAttributes >= value;
64
+ return valueInContext >= value;
65
65
  } else if (operator === "lessThan") {
66
- return valueInAttributes < value;
66
+ return valueInContext < value;
67
67
  } else if (operator === "lessThanOrEquals") {
68
- return valueInAttributes <= value;
68
+ return valueInContext <= value;
69
69
  }
70
70
  }
71
71
 
@@ -74,18 +74,18 @@ export function conditionIsMatched(condition: PlainCondition, attributes: Attrib
74
74
 
75
75
  export function allConditionsAreMatched(
76
76
  conditions: Condition[] | Condition,
77
- attributes: Attributes,
77
+ context: Context,
78
78
  ): boolean {
79
79
  if ("attribute" in conditions) {
80
- return conditionIsMatched(conditions, attributes);
80
+ return conditionIsMatched(conditions, context);
81
81
  }
82
82
 
83
83
  if ("and" in conditions && Array.isArray(conditions.and)) {
84
- return conditions.and.every((c) => allConditionsAreMatched(c, attributes));
84
+ return conditions.and.every((c) => allConditionsAreMatched(c, context));
85
85
  }
86
86
 
87
87
  if ("or" in conditions && Array.isArray(conditions.or)) {
88
- return conditions.or.some((c) => allConditionsAreMatched(c, attributes));
88
+ return conditions.or.some((c) => allConditionsAreMatched(c, context));
89
89
  }
90
90
 
91
91
  if ("not" in conditions && Array.isArray(conditions.not)) {
@@ -95,13 +95,13 @@ export function allConditionsAreMatched(
95
95
  {
96
96
  and: conditions.not,
97
97
  },
98
- attributes,
98
+ context,
99
99
  ) === false,
100
100
  );
101
101
  }
102
102
 
103
103
  if (Array.isArray(conditions)) {
104
- return conditions.every((c) => allConditionsAreMatched(c, attributes));
104
+ return conditions.every((c) => allConditionsAreMatched(c, context));
105
105
  }
106
106
 
107
107
  return false;
package/src/feature.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Allocation, Attributes, Traffic, Feature, Force } from "@featurevisor/types";
1
+ import { Allocation, Context, Traffic, Feature, Force } from "@featurevisor/types";
2
2
  import { DatafileReader } from "./datafileReader";
3
3
  import { allGroupSegmentsAreMatched } from "./segments";
4
4
  import { allConditionsAreMatched } from "./conditions";
@@ -26,7 +26,7 @@ export interface MatchedTrafficAndAllocation {
26
26
 
27
27
  export function getMatchedTrafficAndAllocation(
28
28
  traffic: Traffic[],
29
- attributes: Attributes,
29
+ context: Context,
30
30
  bucketValue: number,
31
31
  datafileReader: DatafileReader,
32
32
  logger: Logger,
@@ -37,7 +37,7 @@ export function getMatchedTrafficAndAllocation(
37
37
  if (
38
38
  !allGroupSegmentsAreMatched(
39
39
  typeof t.segments === "string" && t.segments !== "*" ? JSON.parse(t.segments) : t.segments,
40
- attributes,
40
+ context,
41
41
  datafileReader,
42
42
  )
43
43
  ) {
@@ -61,7 +61,7 @@ export function getMatchedTrafficAndAllocation(
61
61
 
62
62
  export function findForceFromFeature(
63
63
  feature: Feature,
64
- attributes: Attributes,
64
+ context: Context,
65
65
  datafileReader: DatafileReader,
66
66
  ): Force | undefined {
67
67
  if (!feature.force) {
@@ -70,11 +70,11 @@ export function findForceFromFeature(
70
70
 
71
71
  return feature.force.find((f: Force) => {
72
72
  if (f.conditions) {
73
- return allConditionsAreMatched(f.conditions, attributes);
73
+ return allConditionsAreMatched(f.conditions, context);
74
74
  }
75
75
 
76
76
  if (f.segments) {
77
- return allGroupSegmentsAreMatched(f.segments, attributes, datafileReader);
77
+ return allGroupSegmentsAreMatched(f.segments, context, datafileReader);
78
78
  }
79
79
 
80
80
  return false;
@@ -73,7 +73,7 @@ describe("sdk: instance", function () {
73
73
  attributes: [],
74
74
  segments: [],
75
75
  },
76
- configureBucketKey: function (feature, attributes, bucketKey) {
76
+ configureBucketKey: function (feature, context, bucketKey) {
77
77
  capturedBucketKey = bucketKey;
78
78
 
79
79
  return bucketKey;
@@ -117,7 +117,7 @@ describe("sdk: instance", function () {
117
117
  attributes: [],
118
118
  segments: [],
119
119
  },
120
- configureBucketKey: function (feature, attributes, bucketKey) {
120
+ configureBucketKey: function (feature, context, bucketKey) {
121
121
  capturedBucketKey = bucketKey;
122
122
 
123
123
  return bucketKey;
@@ -162,7 +162,7 @@ describe("sdk: instance", function () {
162
162
  attributes: [],
163
163
  segments: [],
164
164
  },
165
- configureBucketKey: function (feature, attributes, bucketKey) {
165
+ configureBucketKey: function (feature, context, bucketKey) {
166
166
  capturedBucketKey = bucketKey;
167
167
 
168
168
  return bucketKey;
@@ -185,7 +185,7 @@ describe("sdk: instance", function () {
185
185
  expect(capturedBucketKey).toEqual("456.test");
186
186
  });
187
187
 
188
- it("should intercept attributes", function () {
188
+ it("should intercept context", function () {
189
189
  let intercepted = false;
190
190
 
191
191
  const sdk = createInstance({
@@ -214,11 +214,11 @@ describe("sdk: instance", function () {
214
214
  attributes: [],
215
215
  segments: [],
216
216
  },
217
- interceptAttributes: function (attributes) {
217
+ interceptContext: function (context) {
218
218
  intercepted = true;
219
219
 
220
220
  return {
221
- ...attributes,
221
+ ...context,
222
222
  };
223
223
  },
224
224
  });
package/src/instance.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import {
2
- Attributes,
2
+ Context,
3
3
  AttributeValue,
4
4
  BucketKey,
5
5
  BucketValue,
@@ -31,13 +31,13 @@ export type ReadyCallback = () => void;
31
31
  export type ActivationCallback = (
32
32
  featureName: string,
33
33
  variation: VariationValue,
34
- attributes: Attributes,
35
- captureAttributes: Attributes,
34
+ context: Context,
35
+ captureContext: Context,
36
36
  ) => void;
37
37
 
38
- export type ConfigureBucketKey = (feature, attributes, bucketKey: BucketKey) => BucketKey;
38
+ export type ConfigureBucketKey = (feature, context, bucketKey: BucketKey) => BucketKey;
39
39
 
40
- export type ConfigureBucketValue = (feature, attributes, bucketValue: BucketValue) => BucketValue;
40
+ export type ConfigureBucketValue = (feature, context, bucketValue: BucketValue) => BucketValue;
41
41
 
42
42
  export interface Statuses {
43
43
  ready: boolean;
@@ -46,6 +46,8 @@ export interface Statuses {
46
46
 
47
47
  const DEFAULT_BUCKET_KEY_SEPARATOR = ".";
48
48
 
49
+ export type InterceptContext = (context: Context) => Context;
50
+
49
51
  export interface InstanceOptions {
50
52
  bucketKeySeparator?: string;
51
53
  configureBucketKey?: ConfigureBucketKey;
@@ -54,7 +56,7 @@ export interface InstanceOptions {
54
56
  datafileUrl?: string;
55
57
  handleDatafileFetch?: (datafileUrl: string) => Promise<DatafileContent>;
56
58
  initialFeatures?: InitialFeatures;
57
- interceptAttributes?: (attributes: Attributes) => Attributes;
59
+ interceptContext?: InterceptContext;
58
60
  logger?: Logger;
59
61
  onActivation?: ActivationCallback;
60
62
  onReady?: ReadyCallback;
@@ -156,7 +158,7 @@ export class FeaturevisorInstance {
156
158
  private datafileUrl?: string;
157
159
  private handleDatafileFetch?: DatafileFetchHandler;
158
160
  private initialFeatures?: InitialFeatures;
159
- private interceptAttributes?: (attributes: Attributes) => Attributes;
161
+ private interceptContext?: InterceptContext;
160
162
  private logger: Logger;
161
163
  private refreshInterval?: number; // seconds
162
164
  private stickyFeatures?: StickyFeatures;
@@ -182,7 +184,7 @@ export class FeaturevisorInstance {
182
184
  this.datafileUrl = options.datafileUrl;
183
185
  this.handleDatafileFetch = options.handleDatafileFetch;
184
186
  this.initialFeatures = options.initialFeatures;
185
- this.interceptAttributes = options.interceptAttributes;
187
+ this.interceptContext = options.interceptContext;
186
188
  this.logger = options.logger || createLogger();
187
189
  this.refreshInterval = options.refreshInterval;
188
190
  this.stickyFeatures = options.stickyFeatures;
@@ -281,7 +283,7 @@ export class FeaturevisorInstance {
281
283
  /**
282
284
  * Bucketing
283
285
  */
284
- private getBucketKey(feature: Feature, attributes: Attributes): BucketKey {
286
+ private getBucketKey(feature: Feature, context: Context): BucketKey {
285
287
  const featureKey = feature.key;
286
288
 
287
289
  let type;
@@ -305,7 +307,7 @@ export class FeaturevisorInstance {
305
307
  const bucketKey: AttributeValue[] = [];
306
308
 
307
309
  attributeKeys.forEach((attributeKey) => {
308
- const attributeValue = attributes[attributeKey];
310
+ const attributeValue = context[attributeKey];
309
311
 
310
312
  if (typeof attributeValue === "undefined") {
311
313
  return;
@@ -326,19 +328,19 @@ export class FeaturevisorInstance {
326
328
  const result = bucketKey.join(this.bucketKeySeparator);
327
329
 
328
330
  if (this.configureBucketKey) {
329
- return this.configureBucketKey(feature, attributes, result);
331
+ return this.configureBucketKey(feature, context, result);
330
332
  }
331
333
 
332
334
  return result;
333
335
  }
334
336
 
335
- private getBucketValue(feature: Feature, attributes: Attributes): BucketValue {
336
- const bucketKey = this.getBucketKey(feature, attributes);
337
+ private getBucketValue(feature: Feature, context: Context): BucketValue {
338
+ const bucketKey = this.getBucketKey(feature, context);
337
339
 
338
340
  const value = getBucketedNumber(bucketKey);
339
341
 
340
342
  if (this.configureBucketValue) {
341
- return this.configureBucketValue(feature, attributes, value);
343
+ return this.configureBucketValue(feature, context, value);
342
344
  }
343
345
 
344
346
  return value;
@@ -419,7 +421,7 @@ export class FeaturevisorInstance {
419
421
  /**
420
422
  * Variation
421
423
  */
422
- evaluateVariation(featureKey: FeatureKey | Feature, attributes: Attributes = {}): Evaluation {
424
+ evaluateVariation(featureKey: FeatureKey | Feature, context: Context = {}): Evaluation {
423
425
  let evaluation: Evaluation;
424
426
 
425
427
  try {
@@ -477,12 +479,10 @@ export class FeaturevisorInstance {
477
479
  return evaluation;
478
480
  }
479
481
 
480
- const finalAttributes = this.interceptAttributes
481
- ? this.interceptAttributes(attributes)
482
- : attributes;
482
+ const finalContext = this.interceptContext ? this.interceptContext(context) : context;
483
483
 
484
484
  // forced
485
- const force = findForceFromFeature(feature, attributes, this.datafileReader);
485
+ const force = findForceFromFeature(feature, context, this.datafileReader);
486
486
 
487
487
  if (force && force.variation) {
488
488
  const variation = feature.variations.find((v) => v.value === force.variation);
@@ -501,11 +501,11 @@ export class FeaturevisorInstance {
501
501
  }
502
502
 
503
503
  // bucketing
504
- const bucketValue = this.getBucketValue(feature, finalAttributes);
504
+ const bucketValue = this.getBucketValue(feature, finalContext);
505
505
 
506
506
  const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
507
507
  feature.traffic,
508
- finalAttributes,
508
+ finalContext,
509
509
  bucketValue,
510
510
  this.datafileReader,
511
511
  this.logger,
@@ -589,10 +589,10 @@ export class FeaturevisorInstance {
589
589
 
590
590
  getVariation(
591
591
  featureKey: FeatureKey | Feature,
592
- attributes: Attributes = {},
592
+ context: Context = {},
593
593
  ): VariationValue | undefined {
594
594
  try {
595
- const evaluation = this.evaluateVariation(featureKey, attributes);
595
+ const evaluation = this.evaluateVariation(featureKey, context);
596
596
 
597
597
  if (typeof evaluation.variationValue !== "undefined") {
598
598
  return evaluation.variationValue;
@@ -612,36 +612,27 @@ export class FeaturevisorInstance {
612
612
 
613
613
  getVariationBoolean(
614
614
  featureKey: FeatureKey | Feature,
615
- attributes: Attributes = {},
615
+ context: Context = {},
616
616
  ): boolean | undefined {
617
- const variationValue = this.getVariation(featureKey, attributes);
617
+ const variationValue = this.getVariation(featureKey, context);
618
618
 
619
619
  return getValueByType(variationValue, "boolean") as boolean | undefined;
620
620
  }
621
621
 
622
- getVariationString(
623
- featureKey: FeatureKey | Feature,
624
- attributes: Attributes = {},
625
- ): string | undefined {
626
- const variationValue = this.getVariation(featureKey, attributes);
622
+ getVariationString(featureKey: FeatureKey | Feature, context: Context = {}): string | undefined {
623
+ const variationValue = this.getVariation(featureKey, context);
627
624
 
628
625
  return getValueByType(variationValue, "string") as string | undefined;
629
626
  }
630
627
 
631
- getVariationInteger(
632
- featureKey: FeatureKey | Feature,
633
- attributes: Attributes = {},
634
- ): number | undefined {
635
- const variationValue = this.getVariation(featureKey, attributes);
628
+ getVariationInteger(featureKey: FeatureKey | Feature, context: Context = {}): number | undefined {
629
+ const variationValue = this.getVariation(featureKey, context);
636
630
 
637
631
  return getValueByType(variationValue, "integer") as number | undefined;
638
632
  }
639
633
 
640
- getVariationDouble(
641
- featureKey: FeatureKey | Feature,
642
- attributes: Attributes = {},
643
- ): number | undefined {
644
- const variationValue = this.getVariation(featureKey, attributes);
634
+ getVariationDouble(featureKey: FeatureKey | Feature, context: Context = {}): number | undefined {
635
+ const variationValue = this.getVariation(featureKey, context);
645
636
 
646
637
  return getValueByType(variationValue, "double") as number | undefined;
647
638
  }
@@ -649,9 +640,9 @@ export class FeaturevisorInstance {
649
640
  /**
650
641
  * Activate
651
642
  */
652
- activate(featureKey: FeatureKey, attributes: Attributes = {}): VariationValue | undefined {
643
+ activate(featureKey: FeatureKey, context: Context = {}): VariationValue | undefined {
653
644
  try {
654
- const evaluation = this.evaluateVariation(featureKey, attributes);
645
+ const evaluation = this.evaluateVariation(featureKey, context);
655
646
  const variationValue = evaluation.variation
656
647
  ? evaluation.variation.value
657
648
  : evaluation.variationValue;
@@ -660,19 +651,17 @@ export class FeaturevisorInstance {
660
651
  return undefined;
661
652
  }
662
653
 
663
- const finalAttributes = this.interceptAttributes
664
- ? this.interceptAttributes(attributes)
665
- : attributes;
654
+ const finalContext = this.interceptContext ? this.interceptContext(context) : context;
666
655
 
667
- const captureAttributes: Attributes = {};
656
+ const captureContext: Context = {};
668
657
 
669
658
  const attributesForCapturing = this.datafileReader
670
659
  .getAllAttributes()
671
660
  .filter((a) => a.capture === true);
672
661
 
673
662
  attributesForCapturing.forEach((a) => {
674
- if (typeof finalAttributes[a.key] !== "undefined") {
675
- captureAttributes[a.key] = attributes[a.key];
663
+ if (typeof finalContext[a.key] !== "undefined") {
664
+ captureContext[a.key] = context[a.key];
676
665
  }
677
666
  });
678
667
 
@@ -680,8 +669,8 @@ export class FeaturevisorInstance {
680
669
  "activation",
681
670
  featureKey,
682
671
  variationValue,
683
- finalAttributes,
684
- captureAttributes,
672
+ finalContext,
673
+ captureContext,
685
674
  evaluation,
686
675
  );
687
676
 
@@ -693,26 +682,26 @@ export class FeaturevisorInstance {
693
682
  }
694
683
  }
695
684
 
696
- activateBoolean(featureKey: FeatureKey, attributes: Attributes = {}): boolean | undefined {
697
- const variationValue = this.activate(featureKey, attributes);
685
+ activateBoolean(featureKey: FeatureKey, context: Context = {}): boolean | undefined {
686
+ const variationValue = this.activate(featureKey, context);
698
687
 
699
688
  return getValueByType(variationValue, "boolean") as boolean | undefined;
700
689
  }
701
690
 
702
- activateString(featureKey: FeatureKey, attributes: Attributes = {}): string | undefined {
703
- const variationValue = this.activate(featureKey, attributes);
691
+ activateString(featureKey: FeatureKey, context: Context = {}): string | undefined {
692
+ const variationValue = this.activate(featureKey, context);
704
693
 
705
694
  return getValueByType(variationValue, "string") as string | undefined;
706
695
  }
707
696
 
708
- activateInteger(featureKey: FeatureKey, attributes: Attributes = {}): number | undefined {
709
- const variationValue = this.activate(featureKey, attributes);
697
+ activateInteger(featureKey: FeatureKey, context: Context = {}): number | undefined {
698
+ const variationValue = this.activate(featureKey, context);
710
699
 
711
700
  return getValueByType(variationValue, "integer") as number | undefined;
712
701
  }
713
702
 
714
- activateDouble(featureKey: FeatureKey, attributes: Attributes = {}): number | undefined {
715
- const variationValue = this.activate(featureKey, attributes);
703
+ activateDouble(featureKey: FeatureKey, context: Context = {}): number | undefined {
704
+ const variationValue = this.activate(featureKey, context);
716
705
 
717
706
  return getValueByType(variationValue, "double") as number | undefined;
718
707
  }
@@ -723,7 +712,7 @@ export class FeaturevisorInstance {
723
712
  evaluateVariable(
724
713
  featureKey: FeatureKey | Feature,
725
714
  variableKey: VariableKey,
726
- attributes: Attributes = {},
715
+ context: Context = {},
727
716
  ): Evaluation {
728
717
  let evaluation: Evaluation;
729
718
 
@@ -801,12 +790,10 @@ export class FeaturevisorInstance {
801
790
  return evaluation;
802
791
  }
803
792
 
804
- const finalAttributes = this.interceptAttributes
805
- ? this.interceptAttributes(attributes)
806
- : attributes;
793
+ const finalContext = this.interceptContext ? this.interceptContext(context) : context;
807
794
 
808
795
  // forced
809
- const force = findForceFromFeature(feature, attributes, this.datafileReader);
796
+ const force = findForceFromFeature(feature, context, this.datafileReader);
810
797
 
811
798
  if (force && force.variables && typeof force.variables[variableKey] !== "undefined") {
812
799
  evaluation = {
@@ -823,11 +810,11 @@ export class FeaturevisorInstance {
823
810
  }
824
811
 
825
812
  // bucketing
826
- const bucketValue = this.getBucketValue(feature, finalAttributes);
813
+ const bucketValue = this.getBucketValue(feature, finalContext);
827
814
 
828
815
  const { matchedTraffic, matchedAllocation } = getMatchedTrafficAndAllocation(
829
816
  feature.traffic,
830
- finalAttributes,
817
+ finalContext,
831
818
  bucketValue,
832
819
  this.datafileReader,
833
820
  this.logger,
@@ -867,7 +854,7 @@ export class FeaturevisorInstance {
867
854
  if (o.conditions) {
868
855
  return allConditionsAreMatched(
869
856
  typeof o.conditions === "string" ? JSON.parse(o.conditions) : o.conditions,
870
- finalAttributes,
857
+ finalContext,
871
858
  );
872
859
  }
873
860
 
@@ -876,7 +863,7 @@ export class FeaturevisorInstance {
876
863
  typeof o.segments === "string" && o.segments !== "*"
877
864
  ? JSON.parse(o.segments)
878
865
  : o.segments,
879
- finalAttributes,
866
+ finalContext,
880
867
  this.datafileReader,
881
868
  );
882
869
  }
@@ -949,10 +936,10 @@ export class FeaturevisorInstance {
949
936
  getVariable(
950
937
  featureKey: FeatureKey | Feature,
951
938
  variableKey: string,
952
- attributes: Attributes = {},
939
+ context: Context = {},
953
940
  ): VariableValue | undefined {
954
941
  try {
955
- const evaluation = this.evaluateVariable(featureKey, variableKey, attributes);
942
+ const evaluation = this.evaluateVariable(featureKey, variableKey, context);
956
943
 
957
944
  if (typeof evaluation.variableValue !== "undefined") {
958
945
  if (
@@ -977,9 +964,9 @@ export class FeaturevisorInstance {
977
964
  getVariableBoolean(
978
965
  featureKey: FeatureKey | Feature,
979
966
  variableKey: string,
980
- attributes: Attributes = {},
967
+ context: Context = {},
981
968
  ): boolean | undefined {
982
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
969
+ const variableValue = this.getVariable(featureKey, variableKey, context);
983
970
 
984
971
  return getValueByType(variableValue, "boolean") as boolean | undefined;
985
972
  }
@@ -987,9 +974,9 @@ export class FeaturevisorInstance {
987
974
  getVariableString(
988
975
  featureKey: FeatureKey | Feature,
989
976
  variableKey: string,
990
- attributes: Attributes = {},
977
+ context: Context = {},
991
978
  ): string | undefined {
992
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
979
+ const variableValue = this.getVariable(featureKey, variableKey, context);
993
980
 
994
981
  return getValueByType(variableValue, "string") as string | undefined;
995
982
  }
@@ -997,9 +984,9 @@ export class FeaturevisorInstance {
997
984
  getVariableInteger(
998
985
  featureKey: FeatureKey | Feature,
999
986
  variableKey: string,
1000
- attributes: Attributes = {},
987
+ context: Context = {},
1001
988
  ): number | undefined {
1002
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
989
+ const variableValue = this.getVariable(featureKey, variableKey, context);
1003
990
 
1004
991
  return getValueByType(variableValue, "integer") as number | undefined;
1005
992
  }
@@ -1007,9 +994,9 @@ export class FeaturevisorInstance {
1007
994
  getVariableDouble(
1008
995
  featureKey: FeatureKey | Feature,
1009
996
  variableKey: string,
1010
- attributes: Attributes = {},
997
+ context: Context = {},
1011
998
  ): number | undefined {
1012
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
999
+ const variableValue = this.getVariable(featureKey, variableKey, context);
1013
1000
 
1014
1001
  return getValueByType(variableValue, "double") as number | undefined;
1015
1002
  }
@@ -1017,9 +1004,9 @@ export class FeaturevisorInstance {
1017
1004
  getVariableArray(
1018
1005
  featureKey: FeatureKey | Feature,
1019
1006
  variableKey: string,
1020
- attributes: Attributes = {},
1007
+ context: Context = {},
1021
1008
  ): string[] | undefined {
1022
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
1009
+ const variableValue = this.getVariable(featureKey, variableKey, context);
1023
1010
 
1024
1011
  return getValueByType(variableValue, "array") as string[] | undefined;
1025
1012
  }
@@ -1027,9 +1014,9 @@ export class FeaturevisorInstance {
1027
1014
  getVariableObject<T>(
1028
1015
  featureKey: FeatureKey | Feature,
1029
1016
  variableKey: string,
1030
- attributes: Attributes = {},
1017
+ context: Context = {},
1031
1018
  ): T | undefined {
1032
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
1019
+ const variableValue = this.getVariable(featureKey, variableKey, context);
1033
1020
 
1034
1021
  return getValueByType(variableValue, "object") as T | undefined;
1035
1022
  }
@@ -1037,9 +1024,9 @@ export class FeaturevisorInstance {
1037
1024
  getVariableJSON<T>(
1038
1025
  featureKey: FeatureKey | Feature,
1039
1026
  variableKey: string,
1040
- attributes: Attributes = {},
1027
+ context: Context = {},
1041
1028
  ): T | undefined {
1042
- const variableValue = this.getVariable(featureKey, variableKey, attributes);
1029
+ const variableValue = this.getVariable(featureKey, variableKey, context);
1043
1030
 
1044
1031
  return getValueByType(variableValue, "json") as T | undefined;
1045
1032
  }