@featurevisor/types 1.35.3 → 2.0.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/README.md +0 -6
- package/lib/index.d.ts +128 -55
- package/package.json +2 -2
- package/src/index.ts +180 -69
package/README.md
CHANGED
package/lib/index.d.ts
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
1
|
export type AttributeKey = string;
|
|
2
|
-
export
|
|
2
|
+
export interface AttributeObjectValue {
|
|
3
|
+
[key: AttributeKey]: AttributeValue;
|
|
4
|
+
}
|
|
5
|
+
export type AttributeValue = string | number | boolean | Date | null | undefined | string[] | AttributeObjectValue;
|
|
3
6
|
export interface Context {
|
|
4
7
|
[key: AttributeKey]: AttributeValue;
|
|
5
8
|
}
|
|
6
|
-
export type AttributeType = "boolean" | "string" | "integer" | "double" | "date" | "semver";
|
|
9
|
+
export type AttributeType = "boolean" | "string" | "integer" | "double" | "date" | "semver" | "object" | "array";
|
|
7
10
|
export interface Attribute {
|
|
8
11
|
archived?: boolean;
|
|
9
|
-
key
|
|
12
|
+
key?: AttributeKey;
|
|
10
13
|
type: AttributeType;
|
|
11
|
-
capture?: boolean;
|
|
12
14
|
description?: string;
|
|
15
|
+
properties?: {
|
|
16
|
+
[key: AttributeKey]: {
|
|
17
|
+
type: "boolean" | "string" | "integer" | "double" | "date" | "semver" | "array";
|
|
18
|
+
description?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
13
21
|
}
|
|
14
|
-
export type Operator = "equals" | "notEquals" | "greaterThan" | "greaterThanOrEquals" | "lessThan" | "lessThanOrEquals" | "contains" | "notContains" | "startsWith" | "endsWith" | "semverEquals" | "semverNotEquals" | "semverGreaterThan" | "semverGreaterThanOrEquals" | "semverLessThan" | "semverLessThanOrEquals" | "before" | "after" | "in" | "notIn";
|
|
22
|
+
export type Operator = "equals" | "notEquals" | "exists" | "notExists" | "greaterThan" | "greaterThanOrEquals" | "lessThan" | "lessThanOrEquals" | "contains" | "notContains" | "startsWith" | "endsWith" | "semverEquals" | "semverNotEquals" | "semverGreaterThan" | "semverGreaterThanOrEquals" | "semverLessThan" | "semverLessThanOrEquals" | "before" | "after" | "includes" | "notIncludes" | "matches" | "notMatches" | "in" | "notIn";
|
|
15
23
|
export type ConditionValue = string | number | boolean | Date | null | undefined | string[];
|
|
16
24
|
export interface PlainCondition {
|
|
17
25
|
attribute: AttributeKey;
|
|
18
26
|
operator: Operator;
|
|
19
|
-
value
|
|
27
|
+
value?: ConditionValue;
|
|
28
|
+
regexFlags?: string;
|
|
20
29
|
}
|
|
21
30
|
export interface AndCondition {
|
|
22
31
|
and: Condition[];
|
|
@@ -28,12 +37,12 @@ export interface NotCondition {
|
|
|
28
37
|
not: Condition[];
|
|
29
38
|
}
|
|
30
39
|
export type AndOrNotCondition = AndCondition | OrCondition | NotCondition;
|
|
31
|
-
export type Condition = PlainCondition | AndOrNotCondition;
|
|
40
|
+
export type Condition = PlainCondition | AndOrNotCondition | string;
|
|
32
41
|
export type SegmentKey = string;
|
|
33
42
|
export interface Segment {
|
|
34
43
|
archived?: boolean;
|
|
35
|
-
key
|
|
36
|
-
conditions: Condition | Condition[]
|
|
44
|
+
key?: SegmentKey;
|
|
45
|
+
conditions: Condition | Condition[];
|
|
37
46
|
description?: string;
|
|
38
47
|
}
|
|
39
48
|
export type PlainGroupSegment = SegmentKey;
|
|
@@ -61,44 +70,45 @@ export interface VariableOverrideSegments {
|
|
|
61
70
|
export interface VariableOverrideConditions {
|
|
62
71
|
conditions: Condition | Condition[];
|
|
63
72
|
}
|
|
64
|
-
export interface VariableOverrideBase {
|
|
65
|
-
value: VariableValue;
|
|
66
|
-
}
|
|
67
73
|
export type VariableOverrideSegmentsOrConditions = VariableOverrideSegments | VariableOverrideConditions;
|
|
68
74
|
export interface VariableOverride {
|
|
69
75
|
value: VariableValue;
|
|
70
76
|
conditions?: Condition | Condition[];
|
|
71
77
|
segments?: GroupSegment | GroupSegment[];
|
|
72
78
|
}
|
|
73
|
-
export interface
|
|
79
|
+
export interface VariableV1 {
|
|
74
80
|
key: VariableKey;
|
|
75
81
|
value: VariableValue;
|
|
76
82
|
description?: string;
|
|
77
83
|
overrides?: VariableOverride[];
|
|
78
84
|
}
|
|
85
|
+
export interface VariationV1 {
|
|
86
|
+
description?: string;
|
|
87
|
+
value: VariationValue;
|
|
88
|
+
weight?: Weight;
|
|
89
|
+
variables?: VariableV1[];
|
|
90
|
+
}
|
|
79
91
|
export interface Variation {
|
|
80
92
|
description?: string;
|
|
81
93
|
value: VariationValue;
|
|
82
94
|
weight?: Weight;
|
|
83
|
-
variables?:
|
|
95
|
+
variables?: {
|
|
96
|
+
[key: VariableKey]: VariableValue;
|
|
97
|
+
};
|
|
98
|
+
variableOverrides?: {
|
|
99
|
+
[key: VariableKey]: VariableOverride[];
|
|
100
|
+
};
|
|
84
101
|
}
|
|
85
102
|
export interface VariableSchema {
|
|
86
103
|
deprecated?: boolean;
|
|
87
|
-
key
|
|
104
|
+
key?: VariableKey;
|
|
88
105
|
type: VariableType;
|
|
89
106
|
defaultValue: VariableValue;
|
|
90
107
|
description?: string;
|
|
108
|
+
useDefaultWhenDisabled?: boolean;
|
|
109
|
+
disabledValue?: VariableValue;
|
|
91
110
|
}
|
|
92
111
|
export type FeatureKey = string;
|
|
93
|
-
export interface Force {
|
|
94
|
-
conditions?: Condition | Condition[];
|
|
95
|
-
segments?: GroupSegment | GroupSegment[];
|
|
96
|
-
enabled?: boolean;
|
|
97
|
-
variation?: VariationValue;
|
|
98
|
-
variables?: {
|
|
99
|
-
[key: string]: VariableValue;
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
112
|
export interface Slot {
|
|
103
113
|
feature: FeatureKey | false;
|
|
104
114
|
percentage: Weight;
|
|
@@ -128,7 +138,10 @@ export interface Traffic {
|
|
|
128
138
|
variables?: {
|
|
129
139
|
[key: string]: VariableValue;
|
|
130
140
|
};
|
|
131
|
-
|
|
141
|
+
variationWeights?: {
|
|
142
|
+
[key: string]: Weight;
|
|
143
|
+
};
|
|
144
|
+
allocation?: Allocation[];
|
|
132
145
|
}
|
|
133
146
|
export type PlainBucketBy = AttributeKey;
|
|
134
147
|
export type AndBucketBy = AttributeKey[];
|
|
@@ -142,29 +155,40 @@ export interface RequiredWithVariation {
|
|
|
142
155
|
}
|
|
143
156
|
export type Required = FeatureKey | RequiredWithVariation;
|
|
144
157
|
export interface Feature {
|
|
145
|
-
key
|
|
158
|
+
key?: FeatureKey;
|
|
159
|
+
hash?: string;
|
|
146
160
|
deprecated?: boolean;
|
|
147
161
|
required?: Required[];
|
|
148
|
-
variablesSchema?:
|
|
162
|
+
variablesSchema?: Record<VariableKey, VariableSchema>;
|
|
163
|
+
disabledVariationValue?: VariationValue;
|
|
149
164
|
variations?: Variation[];
|
|
150
165
|
bucketBy: BucketBy;
|
|
151
166
|
traffic: Traffic[];
|
|
152
167
|
force?: Force[];
|
|
153
168
|
ranges?: Range[];
|
|
154
169
|
}
|
|
170
|
+
export interface FeatureV1 {
|
|
171
|
+
key?: FeatureKey;
|
|
172
|
+
hash?: string;
|
|
173
|
+
deprecated?: boolean;
|
|
174
|
+
required?: Required[];
|
|
175
|
+
bucketBy: BucketBy;
|
|
176
|
+
traffic: Traffic[];
|
|
177
|
+
force?: Force[];
|
|
178
|
+
ranges?: Range[];
|
|
179
|
+
variablesSchema?: VariableSchema[];
|
|
180
|
+
variations?: VariationV1[];
|
|
181
|
+
}
|
|
155
182
|
export interface DatafileContentV1 {
|
|
156
183
|
schemaVersion: string;
|
|
157
184
|
revision: string;
|
|
158
185
|
attributes: Attribute[];
|
|
159
186
|
segments: Segment[];
|
|
160
|
-
features:
|
|
187
|
+
features: FeatureV1[];
|
|
161
188
|
}
|
|
162
|
-
export interface
|
|
189
|
+
export interface DatafileContent {
|
|
163
190
|
schemaVersion: string;
|
|
164
191
|
revision: string;
|
|
165
|
-
attributes: {
|
|
166
|
-
[key: AttributeKey]: Attribute;
|
|
167
|
-
};
|
|
168
192
|
segments: {
|
|
169
193
|
[key: SegmentKey]: Segment;
|
|
170
194
|
};
|
|
@@ -172,23 +196,23 @@ export interface DatafileContentV2 {
|
|
|
172
196
|
[key: FeatureKey]: Feature;
|
|
173
197
|
};
|
|
174
198
|
}
|
|
175
|
-
export
|
|
176
|
-
export interface OverrideFeature {
|
|
199
|
+
export interface EvaluatedFeature {
|
|
177
200
|
enabled: boolean;
|
|
178
201
|
variation?: VariationValue;
|
|
179
202
|
variables?: {
|
|
180
203
|
[key: VariableKey]: VariableValue;
|
|
181
204
|
};
|
|
182
205
|
}
|
|
183
|
-
export interface
|
|
184
|
-
[key: FeatureKey]:
|
|
206
|
+
export interface EvaluatedFeatures {
|
|
207
|
+
[key: FeatureKey]: EvaluatedFeature;
|
|
185
208
|
}
|
|
186
|
-
export type
|
|
209
|
+
export type StickyFeatures = EvaluatedFeatures;
|
|
187
210
|
/**
|
|
188
211
|
* YAML-only type
|
|
189
212
|
*/
|
|
190
213
|
export type Weight = number;
|
|
191
214
|
export type EnvironmentKey = string;
|
|
215
|
+
export type Tag = string;
|
|
192
216
|
export type RuleKey = string;
|
|
193
217
|
export interface Rule {
|
|
194
218
|
key: RuleKey;
|
|
@@ -200,13 +224,28 @@ export interface Rule {
|
|
|
200
224
|
variables?: {
|
|
201
225
|
[key: string]: VariableValue;
|
|
202
226
|
};
|
|
227
|
+
variationWeights?: {
|
|
228
|
+
[key: string]: Weight;
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
export interface RulesByEnvironment {
|
|
232
|
+
[key: EnvironmentKey]: Rule[];
|
|
233
|
+
}
|
|
234
|
+
export interface Force {
|
|
235
|
+
conditions?: Condition | Condition[];
|
|
236
|
+
segments?: GroupSegment | GroupSegment[];
|
|
237
|
+
enabled?: boolean;
|
|
238
|
+
variation?: VariationValue;
|
|
239
|
+
variables?: {
|
|
240
|
+
[key: string]: VariableValue;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
export interface ForceByEnvironment {
|
|
244
|
+
[key: EnvironmentKey]: Force[];
|
|
203
245
|
}
|
|
204
|
-
export type Tag = string;
|
|
205
246
|
export type Expose = boolean | Tag[];
|
|
206
|
-
export interface
|
|
207
|
-
|
|
208
|
-
rules: Rule[];
|
|
209
|
-
force?: Force[];
|
|
247
|
+
export interface ExposeByEnvironment {
|
|
248
|
+
[key: EnvironmentKey]: Expose;
|
|
210
249
|
}
|
|
211
250
|
export interface ParsedFeature {
|
|
212
251
|
key: FeatureKey;
|
|
@@ -216,14 +255,12 @@ export interface ParsedFeature {
|
|
|
216
255
|
tags: Tag[];
|
|
217
256
|
required?: Required[];
|
|
218
257
|
bucketBy: BucketBy;
|
|
219
|
-
|
|
258
|
+
disabledVariationValue?: VariationValue;
|
|
259
|
+
variablesSchema?: Record<VariableKey, VariableSchema>;
|
|
220
260
|
variations?: Variation[];
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
expose?: Expose;
|
|
225
|
-
rules?: Rule[];
|
|
226
|
-
force?: Force[];
|
|
261
|
+
expose?: ExposeByEnvironment | Expose;
|
|
262
|
+
force?: ForceByEnvironment | Force[];
|
|
263
|
+
rules?: RulesByEnvironment | Rule[];
|
|
227
264
|
}
|
|
228
265
|
/**
|
|
229
266
|
* For maintaining old allocations info,
|
|
@@ -231,6 +268,7 @@ export interface ParsedFeature {
|
|
|
231
268
|
* with consistent bucketing
|
|
232
269
|
*/
|
|
233
270
|
export interface ExistingFeature {
|
|
271
|
+
hash?: string;
|
|
234
272
|
variations?: {
|
|
235
273
|
value: VariationValue;
|
|
236
274
|
weight: Weight;
|
|
@@ -238,7 +276,7 @@ export interface ExistingFeature {
|
|
|
238
276
|
traffic: {
|
|
239
277
|
key: RuleKey;
|
|
240
278
|
percentage: Percentage;
|
|
241
|
-
allocation
|
|
279
|
+
allocation?: Allocation[];
|
|
242
280
|
}[];
|
|
243
281
|
ranges?: Range[];
|
|
244
282
|
}
|
|
@@ -254,19 +292,48 @@ export interface ExistingState {
|
|
|
254
292
|
export interface AssertionMatrix {
|
|
255
293
|
[key: string]: AttributeValue[];
|
|
256
294
|
}
|
|
295
|
+
export interface ExpectedEvaluations {
|
|
296
|
+
flag?: Record<string, any>;
|
|
297
|
+
variation?: Record<string, any>;
|
|
298
|
+
variables?: {
|
|
299
|
+
[key: VariableKey]: Record<string, any>;
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
export interface FeatureChildAssertion {
|
|
303
|
+
sticky?: StickyFeatures;
|
|
304
|
+
context?: Context;
|
|
305
|
+
defaultVariationValue?: VariationValue;
|
|
306
|
+
defaultVariableValues?: {
|
|
307
|
+
[key: string]: VariableValue;
|
|
308
|
+
};
|
|
309
|
+
expectedToBeEnabled?: boolean;
|
|
310
|
+
expectedVariation?: VariationValue;
|
|
311
|
+
expectedVariables?: {
|
|
312
|
+
[key: VariableKey]: VariableValue;
|
|
313
|
+
};
|
|
314
|
+
expectedEvaluations?: ExpectedEvaluations;
|
|
315
|
+
}
|
|
257
316
|
export interface FeatureAssertion {
|
|
258
317
|
matrix?: AssertionMatrix;
|
|
259
318
|
description?: string;
|
|
260
319
|
environment: EnvironmentKey;
|
|
261
|
-
at
|
|
262
|
-
|
|
263
|
-
|
|
320
|
+
at?: Weight;
|
|
321
|
+
sticky?: StickyFeatures;
|
|
322
|
+
context?: Context;
|
|
323
|
+
defaultVariationValue?: VariationValue;
|
|
324
|
+
defaultVariableValues?: {
|
|
325
|
+
[key: string]: VariableValue;
|
|
326
|
+
};
|
|
327
|
+
expectedToBeEnabled?: boolean;
|
|
264
328
|
expectedVariation?: VariationValue;
|
|
265
329
|
expectedVariables?: {
|
|
266
330
|
[key: VariableKey]: VariableValue;
|
|
267
331
|
};
|
|
332
|
+
expectedEvaluations?: ExpectedEvaluations;
|
|
333
|
+
children?: FeatureChildAssertion[];
|
|
268
334
|
}
|
|
269
335
|
export interface TestFeature {
|
|
336
|
+
key?: string;
|
|
270
337
|
feature: FeatureKey;
|
|
271
338
|
assertions: FeatureAssertion[];
|
|
272
339
|
}
|
|
@@ -277,16 +344,22 @@ export interface SegmentAssertion {
|
|
|
277
344
|
expectedToMatch: boolean;
|
|
278
345
|
}
|
|
279
346
|
export interface TestSegment {
|
|
347
|
+
key?: string;
|
|
280
348
|
segment: SegmentKey;
|
|
281
349
|
assertions: SegmentAssertion[];
|
|
282
350
|
}
|
|
283
351
|
export type Test = TestSegment | TestFeature;
|
|
284
352
|
export interface TestResultAssertionError {
|
|
285
|
-
type: "flag" | "variation" | "variable" | "segment";
|
|
353
|
+
type: "flag" | "variation" | "variable" | "segment" | "evaluation";
|
|
286
354
|
expected: string | number | boolean | Date | null | undefined;
|
|
287
355
|
actual: string | number | boolean | Date | null | undefined;
|
|
288
356
|
message?: string;
|
|
289
|
-
details?:
|
|
357
|
+
details?: {
|
|
358
|
+
evaluationType?: string;
|
|
359
|
+
evaluationKey?: string;
|
|
360
|
+
childIndex?: number;
|
|
361
|
+
[key: string]: any;
|
|
362
|
+
};
|
|
290
363
|
}
|
|
291
364
|
export interface TestResultAssertion {
|
|
292
365
|
description: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@featurevisor/types",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Common Typescript types for Featurevisor",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "lib/index.js",
|
|
@@ -40,5 +40,5 @@
|
|
|
40
40
|
"url": "https://github.com/featurevisor/featurevisor/issues"
|
|
41
41
|
},
|
|
42
42
|
"license": "MIT",
|
|
43
|
-
"gitHead": "
|
|
43
|
+
"gitHead": "9817e05a07735294c750ee921991509b67015afd"
|
|
44
44
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,24 +1,59 @@
|
|
|
1
1
|
export type AttributeKey = string;
|
|
2
2
|
|
|
3
|
-
export
|
|
3
|
+
export interface AttributeObjectValue {
|
|
4
|
+
[key: AttributeKey]: AttributeValue;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type AttributeValue =
|
|
8
|
+
| string
|
|
9
|
+
| number
|
|
10
|
+
| boolean
|
|
11
|
+
| Date
|
|
12
|
+
| null
|
|
13
|
+
| undefined
|
|
14
|
+
| string[]
|
|
15
|
+
| AttributeObjectValue;
|
|
4
16
|
|
|
5
17
|
export interface Context {
|
|
6
18
|
[key: AttributeKey]: AttributeValue;
|
|
7
19
|
}
|
|
8
20
|
|
|
9
|
-
export type AttributeType =
|
|
21
|
+
export type AttributeType =
|
|
22
|
+
| "boolean"
|
|
23
|
+
| "string"
|
|
24
|
+
| "integer"
|
|
25
|
+
| "double"
|
|
26
|
+
| "date"
|
|
27
|
+
| "semver"
|
|
28
|
+
| "object"
|
|
29
|
+
| "array";
|
|
10
30
|
|
|
11
31
|
export interface Attribute {
|
|
12
32
|
archived?: boolean; // only available in YAML files
|
|
13
|
-
key
|
|
33
|
+
key?: AttributeKey; // needed for supporting v1 datafile generation
|
|
14
34
|
type: AttributeType;
|
|
15
|
-
capture?: boolean;
|
|
16
35
|
description?: string; // only available in YAML files
|
|
36
|
+
properties?: {
|
|
37
|
+
[key: AttributeKey]: {
|
|
38
|
+
type:
|
|
39
|
+
| "boolean"
|
|
40
|
+
| "string"
|
|
41
|
+
| "integer"
|
|
42
|
+
| "double"
|
|
43
|
+
| "date"
|
|
44
|
+
| "semver"
|
|
45
|
+
// | "object" // NOTE: avoid nesting for now
|
|
46
|
+
| "array";
|
|
47
|
+
description?: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
17
50
|
}
|
|
18
51
|
|
|
19
52
|
export type Operator =
|
|
20
53
|
| "equals"
|
|
21
54
|
| "notEquals"
|
|
55
|
+
| "exists"
|
|
56
|
+
| "notExists"
|
|
22
57
|
|
|
23
58
|
// numeric
|
|
24
59
|
| "greaterThan"
|
|
@@ -44,6 +79,14 @@ export type Operator =
|
|
|
44
79
|
| "before"
|
|
45
80
|
| "after"
|
|
46
81
|
|
|
82
|
+
// array of strings
|
|
83
|
+
| "includes"
|
|
84
|
+
| "notIncludes"
|
|
85
|
+
|
|
86
|
+
// regex
|
|
87
|
+
| "matches"
|
|
88
|
+
| "notMatches"
|
|
89
|
+
|
|
47
90
|
// array of strings
|
|
48
91
|
| "in"
|
|
49
92
|
| "notIn";
|
|
@@ -53,7 +96,8 @@ export type ConditionValue = string | number | boolean | Date | null | undefined
|
|
|
53
96
|
export interface PlainCondition {
|
|
54
97
|
attribute: AttributeKey;
|
|
55
98
|
operator: Operator;
|
|
56
|
-
value
|
|
99
|
+
value?: ConditionValue; // for all operators, except for "exists" and "notExists"
|
|
100
|
+
regexFlags?: string; // for regex operators only (matches, notMatches)
|
|
57
101
|
}
|
|
58
102
|
|
|
59
103
|
export interface AndCondition {
|
|
@@ -70,14 +114,14 @@ export interface NotCondition {
|
|
|
70
114
|
|
|
71
115
|
export type AndOrNotCondition = AndCondition | OrCondition | NotCondition;
|
|
72
116
|
|
|
73
|
-
export type Condition = PlainCondition | AndOrNotCondition;
|
|
117
|
+
export type Condition = PlainCondition | AndOrNotCondition | string;
|
|
74
118
|
|
|
75
119
|
export type SegmentKey = string;
|
|
76
120
|
|
|
77
121
|
export interface Segment {
|
|
78
122
|
archived?: boolean; // only available in YAML files
|
|
79
|
-
key
|
|
80
|
-
conditions: Condition | Condition[]
|
|
123
|
+
key?: SegmentKey; // needed for supporting v1 datafile generation
|
|
124
|
+
conditions: Condition | Condition[]; // string only when stringified for datafile
|
|
81
125
|
description?: string; // only available in YAML files
|
|
82
126
|
}
|
|
83
127
|
|
|
@@ -131,62 +175,56 @@ export interface VariableOverrideConditions {
|
|
|
131
175
|
conditions: Condition | Condition[];
|
|
132
176
|
}
|
|
133
177
|
|
|
134
|
-
export interface VariableOverrideBase {
|
|
135
|
-
value: VariableValue;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
178
|
export type VariableOverrideSegmentsOrConditions =
|
|
139
179
|
| VariableOverrideSegments
|
|
140
180
|
| VariableOverrideConditions;
|
|
141
181
|
|
|
142
|
-
// export type VariableOverride = VariableOverrideBase & VariableOverrideSegmentsOrConditions;
|
|
143
|
-
|
|
144
182
|
export interface VariableOverride {
|
|
145
183
|
value: VariableValue;
|
|
146
184
|
|
|
147
185
|
// one of the below must be present in YAML files
|
|
148
|
-
// @TODO: try with above commented out TypeScript later
|
|
149
186
|
conditions?: Condition | Condition[];
|
|
150
187
|
segments?: GroupSegment | GroupSegment[];
|
|
151
188
|
}
|
|
152
189
|
|
|
153
|
-
export interface
|
|
190
|
+
export interface VariableV1 {
|
|
154
191
|
key: VariableKey;
|
|
155
192
|
value: VariableValue;
|
|
156
193
|
description?: string; // only available in YAML files
|
|
157
194
|
overrides?: VariableOverride[];
|
|
158
195
|
}
|
|
159
196
|
|
|
197
|
+
export interface VariationV1 {
|
|
198
|
+
description?: string; // only available in YAML files
|
|
199
|
+
value: VariationValue;
|
|
200
|
+
weight?: Weight; // 0 to 100 (available from parsed YAML, but not in datafile)
|
|
201
|
+
variables?: VariableV1[];
|
|
202
|
+
}
|
|
203
|
+
|
|
160
204
|
export interface Variation {
|
|
161
205
|
description?: string; // only available in YAML files
|
|
162
206
|
value: VariationValue;
|
|
163
207
|
weight?: Weight; // 0 to 100 (available from parsed YAML, but not in datafile)
|
|
164
|
-
variables?:
|
|
208
|
+
variables?: {
|
|
209
|
+
[key: VariableKey]: VariableValue;
|
|
210
|
+
};
|
|
211
|
+
variableOverrides?: {
|
|
212
|
+
[key: VariableKey]: VariableOverride[];
|
|
213
|
+
};
|
|
165
214
|
}
|
|
166
215
|
|
|
167
216
|
export interface VariableSchema {
|
|
168
217
|
deprecated?: boolean;
|
|
169
|
-
key
|
|
218
|
+
key?: VariableKey; // @NOTE: remove
|
|
170
219
|
type: VariableType;
|
|
171
220
|
defaultValue: VariableValue;
|
|
172
221
|
description?: string; // only available in YAML files
|
|
222
|
+
useDefaultWhenDisabled?: boolean;
|
|
223
|
+
disabledValue?: VariableValue;
|
|
173
224
|
}
|
|
174
225
|
|
|
175
226
|
export type FeatureKey = string;
|
|
176
227
|
|
|
177
|
-
export interface Force {
|
|
178
|
-
// one of the below must be present in YAML
|
|
179
|
-
// @TODO: make it better with TypeScript
|
|
180
|
-
conditions?: Condition | Condition[];
|
|
181
|
-
segments?: GroupSegment | GroupSegment[];
|
|
182
|
-
|
|
183
|
-
enabled?: boolean;
|
|
184
|
-
variation?: VariationValue;
|
|
185
|
-
variables?: {
|
|
186
|
-
[key: string]: VariableValue;
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
|
|
190
228
|
export interface Slot {
|
|
191
229
|
feature: FeatureKey | false;
|
|
192
230
|
percentage: Weight; // 0 to 100
|
|
@@ -210,7 +248,7 @@ export type Range = [Percentage, Percentage]; // 0 to 100k
|
|
|
210
248
|
|
|
211
249
|
export interface Allocation {
|
|
212
250
|
variation: VariationValue;
|
|
213
|
-
range: Range;
|
|
251
|
+
range: Range;
|
|
214
252
|
}
|
|
215
253
|
|
|
216
254
|
export interface Traffic {
|
|
@@ -223,8 +261,11 @@ export interface Traffic {
|
|
|
223
261
|
variables?: {
|
|
224
262
|
[key: string]: VariableValue;
|
|
225
263
|
};
|
|
264
|
+
variationWeights?: {
|
|
265
|
+
[key: string]: Weight;
|
|
266
|
+
};
|
|
226
267
|
|
|
227
|
-
allocation
|
|
268
|
+
allocation?: Allocation[];
|
|
228
269
|
}
|
|
229
270
|
|
|
230
271
|
export type PlainBucketBy = AttributeKey;
|
|
@@ -242,10 +283,12 @@ export interface RequiredWithVariation {
|
|
|
242
283
|
export type Required = FeatureKey | RequiredWithVariation;
|
|
243
284
|
|
|
244
285
|
export interface Feature {
|
|
245
|
-
key
|
|
286
|
+
key?: FeatureKey; // needed for supporting v1 datafile generation
|
|
287
|
+
hash?: string;
|
|
246
288
|
deprecated?: boolean;
|
|
247
289
|
required?: Required[];
|
|
248
|
-
variablesSchema?:
|
|
290
|
+
variablesSchema?: Record<VariableKey, VariableSchema>;
|
|
291
|
+
disabledVariationValue?: VariationValue;
|
|
249
292
|
variations?: Variation[];
|
|
250
293
|
bucketBy: BucketBy;
|
|
251
294
|
traffic: Traffic[];
|
|
@@ -253,20 +296,31 @@ export interface Feature {
|
|
|
253
296
|
ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
|
|
254
297
|
}
|
|
255
298
|
|
|
299
|
+
export interface FeatureV1 {
|
|
300
|
+
key?: FeatureKey;
|
|
301
|
+
hash?: string;
|
|
302
|
+
deprecated?: boolean;
|
|
303
|
+
required?: Required[];
|
|
304
|
+
bucketBy: BucketBy;
|
|
305
|
+
traffic: Traffic[];
|
|
306
|
+
force?: Force[];
|
|
307
|
+
ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
|
|
308
|
+
|
|
309
|
+
variablesSchema?: VariableSchema[];
|
|
310
|
+
variations?: VariationV1[];
|
|
311
|
+
}
|
|
312
|
+
|
|
256
313
|
export interface DatafileContentV1 {
|
|
257
314
|
schemaVersion: string;
|
|
258
315
|
revision: string;
|
|
259
316
|
attributes: Attribute[];
|
|
260
317
|
segments: Segment[];
|
|
261
|
-
features:
|
|
318
|
+
features: FeatureV1[];
|
|
262
319
|
}
|
|
263
320
|
|
|
264
|
-
export interface
|
|
321
|
+
export interface DatafileContent {
|
|
265
322
|
schemaVersion: string;
|
|
266
323
|
revision: string;
|
|
267
|
-
attributes: {
|
|
268
|
-
[key: AttributeKey]: Attribute;
|
|
269
|
-
};
|
|
270
324
|
segments: {
|
|
271
325
|
[key: SegmentKey]: Segment;
|
|
272
326
|
};
|
|
@@ -275,9 +329,7 @@ export interface DatafileContentV2 {
|
|
|
275
329
|
};
|
|
276
330
|
}
|
|
277
331
|
|
|
278
|
-
export
|
|
279
|
-
|
|
280
|
-
export interface OverrideFeature {
|
|
332
|
+
export interface EvaluatedFeature {
|
|
281
333
|
enabled: boolean;
|
|
282
334
|
variation?: VariationValue;
|
|
283
335
|
variables?: {
|
|
@@ -285,11 +337,11 @@ export interface OverrideFeature {
|
|
|
285
337
|
};
|
|
286
338
|
}
|
|
287
339
|
|
|
288
|
-
export interface
|
|
289
|
-
[key: FeatureKey]:
|
|
340
|
+
export interface EvaluatedFeatures {
|
|
341
|
+
[key: FeatureKey]: EvaluatedFeature;
|
|
290
342
|
}
|
|
291
343
|
|
|
292
|
-
export type
|
|
344
|
+
export type StickyFeatures = EvaluatedFeatures;
|
|
293
345
|
|
|
294
346
|
/**
|
|
295
347
|
* YAML-only type
|
|
@@ -298,6 +350,8 @@ export type Weight = number; // 0 to 100
|
|
|
298
350
|
|
|
299
351
|
export type EnvironmentKey = string; // ideally "production", "staging", "testing", or "development" only
|
|
300
352
|
|
|
353
|
+
export type Tag = string;
|
|
354
|
+
|
|
301
355
|
export type RuleKey = string;
|
|
302
356
|
|
|
303
357
|
export interface Rule {
|
|
@@ -311,16 +365,35 @@ export interface Rule {
|
|
|
311
365
|
variables?: {
|
|
312
366
|
[key: string]: VariableValue;
|
|
313
367
|
};
|
|
368
|
+
variationWeights?: {
|
|
369
|
+
[key: string]: Weight;
|
|
370
|
+
};
|
|
314
371
|
}
|
|
315
372
|
|
|
316
|
-
export
|
|
373
|
+
export interface RulesByEnvironment {
|
|
374
|
+
[key: EnvironmentKey]: Rule[];
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
export interface Force {
|
|
378
|
+
// one of the below must be present in YAML
|
|
379
|
+
conditions?: Condition | Condition[];
|
|
380
|
+
segments?: GroupSegment | GroupSegment[];
|
|
381
|
+
|
|
382
|
+
enabled?: boolean;
|
|
383
|
+
variation?: VariationValue;
|
|
384
|
+
variables?: {
|
|
385
|
+
[key: string]: VariableValue;
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
export interface ForceByEnvironment {
|
|
390
|
+
[key: EnvironmentKey]: Force[];
|
|
391
|
+
}
|
|
317
392
|
|
|
318
393
|
export type Expose = boolean | Tag[];
|
|
319
394
|
|
|
320
|
-
export interface
|
|
321
|
-
|
|
322
|
-
rules: Rule[];
|
|
323
|
-
force?: Force[];
|
|
395
|
+
export interface ExposeByEnvironment {
|
|
396
|
+
[key: EnvironmentKey]: Expose;
|
|
324
397
|
}
|
|
325
398
|
|
|
326
399
|
export interface ParsedFeature {
|
|
@@ -336,18 +409,14 @@ export interface ParsedFeature {
|
|
|
336
409
|
|
|
337
410
|
bucketBy: BucketBy;
|
|
338
411
|
|
|
339
|
-
|
|
340
|
-
variations?: Variation[];
|
|
412
|
+
disabledVariationValue?: VariationValue;
|
|
341
413
|
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
[key: EnvironmentKey]: Environment;
|
|
345
|
-
};
|
|
414
|
+
variablesSchema?: Record<VariableKey, VariableSchema>;
|
|
415
|
+
variations?: Variation[];
|
|
346
416
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
rules?: Rule[];
|
|
350
|
-
force?: Force[];
|
|
417
|
+
expose?: ExposeByEnvironment | Expose;
|
|
418
|
+
force?: ForceByEnvironment | Force[];
|
|
419
|
+
rules?: RulesByEnvironment | Rule[];
|
|
351
420
|
}
|
|
352
421
|
|
|
353
422
|
/**
|
|
@@ -356,16 +425,15 @@ export interface ParsedFeature {
|
|
|
356
425
|
* with consistent bucketing
|
|
357
426
|
*/
|
|
358
427
|
export interface ExistingFeature {
|
|
428
|
+
hash?: string;
|
|
359
429
|
variations?: {
|
|
360
|
-
// @TODO: use Exclude with Variation?
|
|
361
430
|
value: VariationValue;
|
|
362
431
|
weight: Weight;
|
|
363
432
|
}[];
|
|
364
433
|
traffic: {
|
|
365
|
-
// @TODO: use Exclude with Traffic?
|
|
366
434
|
key: RuleKey;
|
|
367
435
|
percentage: Percentage;
|
|
368
|
-
allocation
|
|
436
|
+
allocation?: Allocation[];
|
|
369
437
|
}[];
|
|
370
438
|
ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
|
|
371
439
|
}
|
|
@@ -385,20 +453,57 @@ export interface AssertionMatrix {
|
|
|
385
453
|
[key: string]: AttributeValue[];
|
|
386
454
|
}
|
|
387
455
|
|
|
456
|
+
export interface ExpectedEvaluations {
|
|
457
|
+
flag?: Record<string, any>;
|
|
458
|
+
variation?: Record<string, any>;
|
|
459
|
+
variables?: {
|
|
460
|
+
[key: VariableKey]: Record<string, any>;
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
export interface FeatureChildAssertion {
|
|
465
|
+
sticky?: StickyFeatures;
|
|
466
|
+
context?: Context;
|
|
467
|
+
|
|
468
|
+
defaultVariationValue?: VariationValue;
|
|
469
|
+
defaultVariableValues?: {
|
|
470
|
+
[key: string]: VariableValue;
|
|
471
|
+
};
|
|
472
|
+
|
|
473
|
+
expectedToBeEnabled?: boolean;
|
|
474
|
+
expectedVariation?: VariationValue;
|
|
475
|
+
expectedVariables?: {
|
|
476
|
+
[key: VariableKey]: VariableValue;
|
|
477
|
+
};
|
|
478
|
+
expectedEvaluations?: ExpectedEvaluations;
|
|
479
|
+
}
|
|
480
|
+
|
|
388
481
|
export interface FeatureAssertion {
|
|
389
482
|
matrix?: AssertionMatrix;
|
|
390
483
|
description?: string;
|
|
391
484
|
environment: EnvironmentKey;
|
|
392
|
-
at
|
|
393
|
-
|
|
394
|
-
|
|
485
|
+
at?: Weight; // bucket weight: 0 to 100
|
|
486
|
+
|
|
487
|
+
sticky?: StickyFeatures;
|
|
488
|
+
context?: Context;
|
|
489
|
+
|
|
490
|
+
defaultVariationValue?: VariationValue;
|
|
491
|
+
defaultVariableValues?: {
|
|
492
|
+
[key: string]: VariableValue;
|
|
493
|
+
};
|
|
494
|
+
|
|
495
|
+
expectedToBeEnabled?: boolean;
|
|
395
496
|
expectedVariation?: VariationValue;
|
|
396
497
|
expectedVariables?: {
|
|
397
498
|
[key: VariableKey]: VariableValue;
|
|
398
499
|
};
|
|
500
|
+
expectedEvaluations?: ExpectedEvaluations;
|
|
501
|
+
|
|
502
|
+
children?: FeatureChildAssertion[];
|
|
399
503
|
}
|
|
400
504
|
|
|
401
505
|
export interface TestFeature {
|
|
506
|
+
key?: string; // file path
|
|
402
507
|
feature: FeatureKey;
|
|
403
508
|
assertions: FeatureAssertion[];
|
|
404
509
|
}
|
|
@@ -411,6 +516,7 @@ export interface SegmentAssertion {
|
|
|
411
516
|
}
|
|
412
517
|
|
|
413
518
|
export interface TestSegment {
|
|
519
|
+
key?: string; // file path
|
|
414
520
|
segment: SegmentKey;
|
|
415
521
|
assertions: SegmentAssertion[];
|
|
416
522
|
}
|
|
@@ -418,11 +524,16 @@ export interface TestSegment {
|
|
|
418
524
|
export type Test = TestSegment | TestFeature;
|
|
419
525
|
|
|
420
526
|
export interface TestResultAssertionError {
|
|
421
|
-
type: "flag" | "variation" | "variable" | "segment";
|
|
527
|
+
type: "flag" | "variation" | "variable" | "segment" | "evaluation";
|
|
422
528
|
expected: string | number | boolean | Date | null | undefined;
|
|
423
529
|
actual: string | number | boolean | Date | null | undefined;
|
|
424
530
|
message?: string;
|
|
425
|
-
details?:
|
|
531
|
+
details?: {
|
|
532
|
+
evaluationType?: string; // e.g., "flag", "variation", "variable"
|
|
533
|
+
evaluationKey?: string; // e.g., "myFeatureKey", "myVariableKey"
|
|
534
|
+
childIndex?: number; // for children assertions
|
|
535
|
+
[key: string]: any;
|
|
536
|
+
};
|
|
426
537
|
}
|
|
427
538
|
|
|
428
539
|
export interface TestResultAssertion {
|