@featurevisor/types 2.0.1 → 2.0.3

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 CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [2.0.3](https://github.com/featurevisor/featurevisor/compare/v2.0.2...v2.0.3) (2025-07-20)
7
+
8
+ **Note:** Version bump only for package @featurevisor/types
9
+
10
+
11
+
12
+
13
+
14
+ ## [2.0.2](https://github.com/featurevisor/featurevisor/compare/v2.0.1...v2.0.2) (2025-07-19)
15
+
16
+ **Note:** Version bump only for package @featurevisor/types
17
+
18
+
19
+
20
+
21
+
6
22
  ## [2.0.1](https://github.com/featurevisor/featurevisor/compare/v2.0.0...v2.0.1) (2025-07-19)
7
23
 
8
24
  **Note:** Version bump only for package @featurevisor/types
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@featurevisor/types",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "Common Typescript types for Featurevisor",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
@@ -15,7 +15,7 @@
15
15
  "scripts": {
16
16
  "transpile": "echo 'Nothing to transpile'",
17
17
  "dist": "echo 'Nothing to dist'",
18
- "build": "echo 'Nothing to build'",
18
+ "build": "tsc ./src/index.d.ts",
19
19
  "test": "echo 'Nothing to test in types package'"
20
20
  },
21
21
  "author": {
@@ -47,5 +47,5 @@
47
47
  "url": "https://github.com/featurevisor/featurevisor/issues"
48
48
  },
49
49
  "license": "MIT",
50
- "gitHead": "f5d883e1d6f8ba1b0c14fbbd79329b98f66b46e8"
50
+ "gitHead": "5522c5cb67b648aac05c100733390e92a42f694b"
51
51
  }
@@ -0,0 +1,46 @@
1
+ export type AttributeKey = string;
2
+
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;
16
+
17
+ export type AttributeType =
18
+ | "boolean"
19
+ | "string"
20
+ | "integer"
21
+ | "double"
22
+ | "date"
23
+ | "semver"
24
+ | "object"
25
+ | "array";
26
+
27
+ export interface Attribute {
28
+ archived?: boolean; // only available in YAML files
29
+ key?: AttributeKey; // needed for supporting v1 datafile generation
30
+ type: AttributeType;
31
+ description?: string; // only available in YAML files
32
+ properties?: {
33
+ [key: AttributeKey]: {
34
+ type:
35
+ | "boolean"
36
+ | "string"
37
+ | "integer"
38
+ | "double"
39
+ | "date"
40
+ | "semver"
41
+ // | "object" // NOTE: avoid nesting for now
42
+ | "array";
43
+ description?: string;
44
+ };
45
+ };
46
+ }
@@ -0,0 +1,8 @@
1
+ import type { AttributeKey } from "./attribute";
2
+
3
+ export type PlainBucketBy = AttributeKey;
4
+ export type AndBucketBy = AttributeKey[];
5
+ export interface OrBucketBy {
6
+ or: AttributeKey[];
7
+ }
8
+ export type BucketBy = PlainBucketBy | AndBucketBy | OrBucketBy;
@@ -0,0 +1,68 @@
1
+ import type { AttributeKey } from "./attribute";
2
+
3
+ export type Operator =
4
+ | "equals"
5
+ | "notEquals"
6
+ | "exists"
7
+ | "notExists"
8
+
9
+ // numeric
10
+ | "greaterThan"
11
+ | "greaterThanOrEquals"
12
+ | "lessThan"
13
+ | "lessThanOrEquals"
14
+
15
+ // string
16
+ | "contains"
17
+ | "notContains"
18
+ | "startsWith"
19
+ | "endsWith"
20
+
21
+ // semver (string)
22
+ | "semverEquals"
23
+ | "semverNotEquals"
24
+ | "semverGreaterThan"
25
+ | "semverGreaterThanOrEquals"
26
+ | "semverLessThan"
27
+ | "semverLessThanOrEquals"
28
+
29
+ // date comparisons
30
+ | "before"
31
+ | "after"
32
+
33
+ // array of strings
34
+ | "includes"
35
+ | "notIncludes"
36
+
37
+ // regex
38
+ | "matches"
39
+ | "notMatches"
40
+
41
+ // array of strings
42
+ | "in"
43
+ | "notIn";
44
+
45
+ export type ConditionValue = string | number | boolean | Date | null | undefined | string[];
46
+
47
+ export interface PlainCondition {
48
+ attribute: AttributeKey;
49
+ operator: Operator;
50
+ value?: ConditionValue; // for all operators, except for "exists" and "notExists"
51
+ regexFlags?: string; // for regex operators only (matches, notMatches)
52
+ }
53
+
54
+ export interface AndCondition {
55
+ and: Condition[];
56
+ }
57
+
58
+ export interface OrCondition {
59
+ or: Condition[];
60
+ }
61
+
62
+ export interface NotCondition {
63
+ not: Condition[];
64
+ }
65
+
66
+ export type AndOrNotCondition = AndCondition | OrCondition | NotCondition;
67
+
68
+ export type Condition = PlainCondition | AndOrNotCondition | string;
@@ -0,0 +1,5 @@
1
+ import type { AttributeKey, AttributeValue } from "./attribute";
2
+
3
+ export interface Context {
4
+ [key: AttributeKey]: AttributeValue;
5
+ }
@@ -0,0 +1,89 @@
1
+ import type { Attribute } from "./attribute";
2
+ import type { BucketBy } from "./bucket";
3
+ import type {
4
+ VariationValue,
5
+ RuleKey,
6
+ VariableValue,
7
+ Weight,
8
+ FeatureKey,
9
+ Required,
10
+ VariableKey,
11
+ VariableSchema,
12
+ Variation,
13
+ Force,
14
+ VariationV1,
15
+ } from "./feature";
16
+ import type { GroupSegment, Segment, SegmentKey } from "./segment";
17
+
18
+ export type Percentage = number; // 0 to 100,000 (100% * 1000 to include three decimal places in same integer)
19
+
20
+ export type Range = [Percentage, Percentage]; // 0 to 100k
21
+
22
+ export interface Allocation {
23
+ variation: VariationValue;
24
+ range: Range;
25
+ }
26
+
27
+ export interface Traffic {
28
+ key: RuleKey;
29
+ segments: GroupSegment | GroupSegment[] | "*";
30
+ percentage: Percentage;
31
+
32
+ enabled?: boolean;
33
+ variation?: VariationValue;
34
+ variables?: {
35
+ [key: string]: VariableValue;
36
+ };
37
+ variationWeights?: {
38
+ [key: string]: Weight;
39
+ };
40
+
41
+ allocation?: Allocation[];
42
+ }
43
+
44
+ export interface Feature {
45
+ key?: FeatureKey; // needed for supporting v1 datafile generation
46
+ hash?: string;
47
+ deprecated?: boolean;
48
+ required?: Required[];
49
+ variablesSchema?: Record<VariableKey, VariableSchema>;
50
+ disabledVariationValue?: VariationValue;
51
+ variations?: Variation[];
52
+ bucketBy: BucketBy;
53
+ traffic: Traffic[];
54
+ force?: Force[];
55
+ ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
56
+ }
57
+
58
+ export interface FeatureV1 {
59
+ key?: FeatureKey;
60
+ hash?: string;
61
+ deprecated?: boolean;
62
+ required?: Required[];
63
+ bucketBy: BucketBy;
64
+ traffic: Traffic[];
65
+ force?: Force[];
66
+ ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
67
+
68
+ variablesSchema?: VariableSchema[];
69
+ variations?: VariationV1[];
70
+ }
71
+
72
+ export interface DatafileContentV1 {
73
+ schemaVersion: string;
74
+ revision: string;
75
+ attributes: Attribute[];
76
+ segments: Segment[];
77
+ features: FeatureV1[];
78
+ }
79
+
80
+ export interface DatafileContent {
81
+ schemaVersion: string;
82
+ revision: string;
83
+ segments: {
84
+ [key: SegmentKey]: Segment;
85
+ };
86
+ features: {
87
+ [key: FeatureKey]: Feature;
88
+ };
89
+ }
@@ -0,0 +1,181 @@
1
+ import type { BucketBy } from "./bucket";
2
+ import type { Condition } from "./condition";
3
+ import type { GroupSegment } from "./segment";
4
+
5
+ export type VariationValue = string;
6
+
7
+ export type VariableKey = string;
8
+ export type VariableType =
9
+ | "boolean"
10
+ | "string"
11
+ | "integer"
12
+ | "double"
13
+ | "array"
14
+ | "object"
15
+ | "json";
16
+ export interface VariableObjectValue {
17
+ [key: string]: VariableValue;
18
+ }
19
+ export type VariableValue =
20
+ | boolean
21
+ | string
22
+ | number
23
+ | string[]
24
+ | VariableObjectValue
25
+ | null
26
+ | undefined;
27
+
28
+ export interface VariableOverrideSegments {
29
+ segments: GroupSegment | GroupSegment[];
30
+ }
31
+
32
+ export interface VariableOverrideConditions {
33
+ conditions: Condition | Condition[];
34
+ }
35
+
36
+ export type VariableOverrideSegmentsOrConditions =
37
+ | VariableOverrideSegments
38
+ | VariableOverrideConditions;
39
+
40
+ export interface VariableOverride {
41
+ value: VariableValue;
42
+
43
+ // one of the below must be present in YAML files
44
+ conditions?: Condition | Condition[];
45
+ segments?: GroupSegment | GroupSegment[];
46
+ }
47
+
48
+ export interface VariableV1 {
49
+ key: VariableKey;
50
+ value: VariableValue;
51
+ description?: string; // only available in YAML files
52
+ overrides?: VariableOverride[];
53
+ }
54
+
55
+ export interface VariationV1 {
56
+ description?: string; // only available in YAML files
57
+ value: VariationValue;
58
+ weight?: Weight; // 0 to 100 (available from parsed YAML, but not in datafile)
59
+ variables?: VariableV1[];
60
+ }
61
+
62
+ export interface Variation {
63
+ description?: string; // only available in YAML files
64
+ value: VariationValue;
65
+ weight?: Weight; // 0 to 100 (available from parsed YAML, but not in datafile)
66
+ variables?: {
67
+ [key: VariableKey]: VariableValue;
68
+ };
69
+ variableOverrides?: {
70
+ [key: VariableKey]: VariableOverride[];
71
+ };
72
+ }
73
+
74
+ export interface VariableSchema {
75
+ deprecated?: boolean;
76
+ key?: VariableKey; // @NOTE: remove
77
+ type: VariableType;
78
+ defaultValue: VariableValue;
79
+ description?: string; // only available in YAML files
80
+ useDefaultWhenDisabled?: boolean;
81
+ disabledValue?: VariableValue;
82
+ }
83
+
84
+ export type FeatureKey = string;
85
+
86
+ export interface RequiredWithVariation {
87
+ key: FeatureKey;
88
+ variation: VariationValue;
89
+ }
90
+
91
+ export type Required = FeatureKey | RequiredWithVariation;
92
+
93
+ export type Weight = number; // 0 to 100
94
+
95
+ export type EnvironmentKey = string; // ideally "production", "staging", "testing", or "development" only
96
+
97
+ export type Tag = string;
98
+
99
+ export type RuleKey = string;
100
+
101
+ export interface Rule {
102
+ key: RuleKey;
103
+ description?: string; // only available in YAML
104
+ segments: GroupSegment | GroupSegment[];
105
+ percentage: Weight;
106
+
107
+ enabled?: boolean;
108
+ variation?: VariationValue;
109
+ variables?: {
110
+ [key: string]: VariableValue;
111
+ };
112
+ variationWeights?: {
113
+ [key: string]: Weight;
114
+ };
115
+ }
116
+
117
+ export interface RulesByEnvironment {
118
+ [key: EnvironmentKey]: Rule[];
119
+ }
120
+
121
+ export interface Force {
122
+ // one of the below must be present in YAML
123
+ conditions?: Condition | Condition[];
124
+ segments?: GroupSegment | GroupSegment[];
125
+
126
+ enabled?: boolean;
127
+ variation?: VariationValue;
128
+ variables?: {
129
+ [key: string]: VariableValue;
130
+ };
131
+ }
132
+
133
+ export interface ForceByEnvironment {
134
+ [key: EnvironmentKey]: Force[];
135
+ }
136
+
137
+ export type Expose = boolean | Tag[];
138
+
139
+ export interface ExposeByEnvironment {
140
+ [key: EnvironmentKey]: Expose;
141
+ }
142
+
143
+ export interface ParsedFeature {
144
+ key: FeatureKey;
145
+
146
+ archived?: boolean;
147
+ deprecated?: boolean;
148
+
149
+ description: string;
150
+ tags: Tag[];
151
+
152
+ required?: Required[];
153
+
154
+ bucketBy: BucketBy;
155
+
156
+ disabledVariationValue?: VariationValue;
157
+
158
+ variablesSchema?: Record<VariableKey, VariableSchema>;
159
+ variations?: Variation[];
160
+
161
+ expose?: ExposeByEnvironment | Expose;
162
+ force?: ForceByEnvironment | Force[];
163
+ rules?: RulesByEnvironment | Rule[];
164
+ }
165
+
166
+ /**
167
+ * Used by SDK
168
+ */
169
+ export interface EvaluatedFeature {
170
+ enabled: boolean;
171
+ variation?: VariationValue;
172
+ variables?: {
173
+ [key: VariableKey]: VariableValue;
174
+ };
175
+ }
176
+
177
+ export interface EvaluatedFeatures {
178
+ [key: FeatureKey]: EvaluatedFeature;
179
+ }
180
+
181
+ export type StickyFeatures = EvaluatedFeatures;
package/src/group.d.ts ADDED
@@ -0,0 +1,12 @@
1
+ import type { FeatureKey, Weight } from "./feature";
2
+
3
+ export interface Slot {
4
+ feature: FeatureKey | false;
5
+ percentage: Weight; // 0 to 100
6
+ }
7
+
8
+ export interface Group {
9
+ key: string;
10
+ description: string;
11
+ slots: Slot[];
12
+ }
package/src/index.d.ts CHANGED
@@ -1,621 +1,11 @@
1
- export type AttributeKey = string;
2
-
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;
16
-
17
- export interface Context {
18
- [key: AttributeKey]: AttributeValue;
19
- }
20
-
21
- export type AttributeType =
22
- | "boolean"
23
- | "string"
24
- | "integer"
25
- | "double"
26
- | "date"
27
- | "semver"
28
- | "object"
29
- | "array";
30
-
31
- export interface Attribute {
32
- archived?: boolean; // only available in YAML files
33
- key?: AttributeKey; // needed for supporting v1 datafile generation
34
- type: AttributeType;
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
- };
50
- }
51
-
52
- export type Operator =
53
- | "equals"
54
- | "notEquals"
55
- | "exists"
56
- | "notExists"
57
-
58
- // numeric
59
- | "greaterThan"
60
- | "greaterThanOrEquals"
61
- | "lessThan"
62
- | "lessThanOrEquals"
63
-
64
- // string
65
- | "contains"
66
- | "notContains"
67
- | "startsWith"
68
- | "endsWith"
69
-
70
- // semver (string)
71
- | "semverEquals"
72
- | "semverNotEquals"
73
- | "semverGreaterThan"
74
- | "semverGreaterThanOrEquals"
75
- | "semverLessThan"
76
- | "semverLessThanOrEquals"
77
-
78
- // date comparisons
79
- | "before"
80
- | "after"
81
-
82
- // array of strings
83
- | "includes"
84
- | "notIncludes"
85
-
86
- // regex
87
- | "matches"
88
- | "notMatches"
89
-
90
- // array of strings
91
- | "in"
92
- | "notIn";
93
-
94
- export type ConditionValue = string | number | boolean | Date | null | undefined | string[];
95
-
96
- export interface PlainCondition {
97
- attribute: AttributeKey;
98
- operator: Operator;
99
- value?: ConditionValue; // for all operators, except for "exists" and "notExists"
100
- regexFlags?: string; // for regex operators only (matches, notMatches)
101
- }
102
-
103
- export interface AndCondition {
104
- and: Condition[];
105
- }
106
-
107
- export interface OrCondition {
108
- or: Condition[];
109
- }
110
-
111
- export interface NotCondition {
112
- not: Condition[];
113
- }
114
-
115
- export type AndOrNotCondition = AndCondition | OrCondition | NotCondition;
116
-
117
- export type Condition = PlainCondition | AndOrNotCondition | string;
118
-
119
- export type SegmentKey = string;
120
-
121
- export interface Segment {
122
- archived?: boolean; // only available in YAML files
123
- key?: SegmentKey; // needed for supporting v1 datafile generation
124
- conditions: Condition | Condition[]; // string only when stringified for datafile
125
- description?: string; // only available in YAML files
126
- }
127
-
128
- export type PlainGroupSegment = SegmentKey;
129
-
130
- export interface AndGroupSegment {
131
- and: GroupSegment[];
132
- }
133
-
134
- export interface OrGroupSegment {
135
- or: GroupSegment[];
136
- }
137
-
138
- export interface NotGroupSegment {
139
- not: GroupSegment[];
140
- }
141
-
142
- export type AndOrNotGroupSegment = AndGroupSegment | OrGroupSegment | NotGroupSegment;
143
-
144
- // group of segment keys with and/or conditions, or just string
145
- export type GroupSegment = PlainGroupSegment | AndOrNotGroupSegment;
146
-
147
- export type VariationValue = string;
148
-
149
- export type VariableKey = string;
150
- export type VariableType =
151
- | "boolean"
152
- | "string"
153
- | "integer"
154
- | "double"
155
- | "array"
156
- | "object"
157
- | "json";
158
- export interface VariableObjectValue {
159
- [key: string]: VariableValue;
160
- }
161
- export type VariableValue =
162
- | boolean
163
- | string
164
- | number
165
- | string[]
166
- | VariableObjectValue
167
- | null
168
- | undefined;
169
-
170
- export interface VariableOverrideSegments {
171
- segments: GroupSegment | GroupSegment[];
172
- }
173
-
174
- export interface VariableOverrideConditions {
175
- conditions: Condition | Condition[];
176
- }
177
-
178
- export type VariableOverrideSegmentsOrConditions =
179
- | VariableOverrideSegments
180
- | VariableOverrideConditions;
181
-
182
- export interface VariableOverride {
183
- value: VariableValue;
184
-
185
- // one of the below must be present in YAML files
186
- conditions?: Condition | Condition[];
187
- segments?: GroupSegment | GroupSegment[];
188
- }
189
-
190
- export interface VariableV1 {
191
- key: VariableKey;
192
- value: VariableValue;
193
- description?: string; // only available in YAML files
194
- overrides?: VariableOverride[];
195
- }
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
-
204
- export interface Variation {
205
- description?: string; // only available in YAML files
206
- value: VariationValue;
207
- weight?: Weight; // 0 to 100 (available from parsed YAML, but not in datafile)
208
- variables?: {
209
- [key: VariableKey]: VariableValue;
210
- };
211
- variableOverrides?: {
212
- [key: VariableKey]: VariableOverride[];
213
- };
214
- }
215
-
216
- export interface VariableSchema {
217
- deprecated?: boolean;
218
- key?: VariableKey; // @NOTE: remove
219
- type: VariableType;
220
- defaultValue: VariableValue;
221
- description?: string; // only available in YAML files
222
- useDefaultWhenDisabled?: boolean;
223
- disabledValue?: VariableValue;
224
- }
225
-
226
- export type FeatureKey = string;
227
-
228
- export interface Slot {
229
- feature: FeatureKey | false;
230
- percentage: Weight; // 0 to 100
231
- }
232
-
233
- export interface Group {
234
- key: string;
235
- description: string;
236
- slots: Slot[];
237
- }
238
-
239
- export type BucketKey = string;
240
- export type BucketValue = number; // 0 to 100,000 (100% * 1000 to include three decimal places in same integer)
241
-
242
- /**
243
- * Datafile-only types
244
- */
245
- export type Percentage = number; // 0 to 100,000 (100% * 1000 to include three decimal places in same integer)
246
-
247
- export type Range = [Percentage, Percentage]; // 0 to 100k
248
-
249
- export interface Allocation {
250
- variation: VariationValue;
251
- range: Range;
252
- }
253
-
254
- export interface Traffic {
255
- key: RuleKey;
256
- segments: GroupSegment | GroupSegment[] | "*";
257
- percentage: Percentage;
258
-
259
- enabled?: boolean;
260
- variation?: VariationValue;
261
- variables?: {
262
- [key: string]: VariableValue;
263
- };
264
- variationWeights?: {
265
- [key: string]: Weight;
266
- };
267
-
268
- allocation?: Allocation[];
269
- }
270
-
271
- export type PlainBucketBy = AttributeKey;
272
- export type AndBucketBy = AttributeKey[];
273
- export interface OrBucketBy {
274
- or: AttributeKey[];
275
- }
276
- export type BucketBy = PlainBucketBy | AndBucketBy | OrBucketBy;
277
-
278
- export interface RequiredWithVariation {
279
- key: FeatureKey;
280
- variation: VariationValue;
281
- }
282
-
283
- export type Required = FeatureKey | RequiredWithVariation;
284
-
285
- export interface Feature {
286
- key?: FeatureKey; // needed for supporting v1 datafile generation
287
- hash?: string;
288
- deprecated?: boolean;
289
- required?: Required[];
290
- variablesSchema?: Record<VariableKey, VariableSchema>;
291
- disabledVariationValue?: VariationValue;
292
- variations?: Variation[];
293
- bucketBy: BucketBy;
294
- traffic: Traffic[];
295
- force?: Force[];
296
- ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
297
- }
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
-
313
- export interface DatafileContentV1 {
314
- schemaVersion: string;
315
- revision: string;
316
- attributes: Attribute[];
317
- segments: Segment[];
318
- features: FeatureV1[];
319
- }
320
-
321
- export interface DatafileContent {
322
- schemaVersion: string;
323
- revision: string;
324
- segments: {
325
- [key: SegmentKey]: Segment;
326
- };
327
- features: {
328
- [key: FeatureKey]: Feature;
329
- };
330
- }
331
-
332
- export interface EvaluatedFeature {
333
- enabled: boolean;
334
- variation?: VariationValue;
335
- variables?: {
336
- [key: VariableKey]: VariableValue;
337
- };
338
- }
339
-
340
- export interface EvaluatedFeatures {
341
- [key: FeatureKey]: EvaluatedFeature;
342
- }
343
-
344
- export type StickyFeatures = EvaluatedFeatures;
345
-
346
- /**
347
- * YAML-only type
348
- */
349
- export type Weight = number; // 0 to 100
350
-
351
- export type EnvironmentKey = string; // ideally "production", "staging", "testing", or "development" only
352
-
353
- export type Tag = string;
354
-
355
- export type RuleKey = string;
356
-
357
- export interface Rule {
358
- key: RuleKey;
359
- description?: string; // only available in YAML
360
- segments: GroupSegment | GroupSegment[];
361
- percentage: Weight;
362
-
363
- enabled?: boolean;
364
- variation?: VariationValue;
365
- variables?: {
366
- [key: string]: VariableValue;
367
- };
368
- variationWeights?: {
369
- [key: string]: Weight;
370
- };
371
- }
372
-
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
- }
392
-
393
- export type Expose = boolean | Tag[];
394
-
395
- export interface ExposeByEnvironment {
396
- [key: EnvironmentKey]: Expose;
397
- }
398
-
399
- export interface ParsedFeature {
400
- key: FeatureKey;
401
-
402
- archived?: boolean;
403
- deprecated?: boolean;
404
-
405
- description: string;
406
- tags: Tag[];
407
-
408
- required?: Required[];
409
-
410
- bucketBy: BucketBy;
411
-
412
- disabledVariationValue?: VariationValue;
413
-
414
- variablesSchema?: Record<VariableKey, VariableSchema>;
415
- variations?: Variation[];
416
-
417
- expose?: ExposeByEnvironment | Expose;
418
- force?: ForceByEnvironment | Force[];
419
- rules?: RulesByEnvironment | Rule[];
420
- }
421
-
422
- /**
423
- * For maintaining old allocations info,
424
- * allowing for gradual rollout of new allocations
425
- * with consistent bucketing
426
- */
427
- export interface ExistingFeature {
428
- hash?: string;
429
- variations?: {
430
- value: VariationValue;
431
- weight: Weight;
432
- }[];
433
- traffic: {
434
- key: RuleKey;
435
- percentage: Percentage;
436
- allocation?: Allocation[];
437
- }[];
438
- ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
439
- }
440
-
441
- export interface ExistingFeatures {
442
- [key: FeatureKey]: ExistingFeature;
443
- }
444
-
445
- export interface ExistingState {
446
- features: ExistingFeatures;
447
- }
448
-
449
- /**
450
- * Tests
451
- */
452
- export interface AssertionMatrix {
453
- [key: string]: AttributeValue[];
454
- }
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
-
481
- export interface FeatureAssertion {
482
- matrix?: AssertionMatrix;
483
- description?: string;
484
- environment: EnvironmentKey;
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;
496
- expectedVariation?: VariationValue;
497
- expectedVariables?: {
498
- [key: VariableKey]: VariableValue;
499
- };
500
- expectedEvaluations?: ExpectedEvaluations;
501
-
502
- children?: FeatureChildAssertion[];
503
- }
504
-
505
- export interface TestFeature {
506
- key?: string; // file path
507
- feature: FeatureKey;
508
- assertions: FeatureAssertion[];
509
- }
510
-
511
- export interface SegmentAssertion {
512
- matrix?: AssertionMatrix;
513
- description?: string;
514
- context: Context;
515
- expectedToMatch: boolean;
516
- }
517
-
518
- export interface TestSegment {
519
- key?: string; // file path
520
- segment: SegmentKey;
521
- assertions: SegmentAssertion[];
522
- }
523
-
524
- export type Test = TestSegment | TestFeature;
525
-
526
- export interface TestResultAssertionError {
527
- type: "flag" | "variation" | "variable" | "segment" | "evaluation";
528
- expected: string | number | boolean | Date | null | undefined;
529
- actual: string | number | boolean | Date | null | undefined;
530
- message?: string;
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
- };
537
- }
538
-
539
- export interface TestResultAssertion {
540
- description: string;
541
- duration: number;
542
- passed: boolean;
543
- errors?: TestResultAssertionError[];
544
- }
545
-
546
- export interface TestResult {
547
- type: "feature" | "segment";
548
- key: string;
549
- notFound?: boolean;
550
- passed: boolean;
551
- duration: number;
552
- assertions: TestResultAssertion[];
553
- }
554
-
555
- /**
556
- * Site index and history
557
- */
558
- export type EntityType = "attribute" | "segment" | "feature" | "group" | "test";
559
-
560
- export type CommitHash = string;
561
-
562
- export interface HistoryEntity {
563
- type: EntityType;
564
- key: string;
565
- }
566
-
567
- export interface HistoryEntry {
568
- commit: CommitHash;
569
- author: string;
570
- timestamp: string;
571
- entities: HistoryEntity[];
572
- }
573
-
574
- export interface LastModified {
575
- commit: CommitHash;
576
- timestamp: string;
577
- author: string;
578
- }
579
-
580
- export interface SearchIndex {
581
- links?: {
582
- feature: string;
583
- segment: string;
584
- attribute: string;
585
- commit: CommitHash;
586
- };
587
- projectConfig: {
588
- tags: Tag[];
589
- environments: EnvironmentKey[] | false;
590
- };
591
- entities: {
592
- attributes: (Attribute & {
593
- lastModified?: LastModified;
594
- usedInSegments: SegmentKey[];
595
- usedInFeatures: FeatureKey[];
596
- })[];
597
- segments: (Segment & {
598
- lastModified?: LastModified;
599
- usedInFeatures: FeatureKey[];
600
- })[];
601
- features: (ParsedFeature & {
602
- lastModified?: LastModified;
603
- })[];
604
- };
605
- }
606
-
607
- export interface EntityDiff {
608
- type: EntityType;
609
- key: string;
610
- created?: boolean;
611
- deleted?: boolean;
612
- updated?: boolean;
613
- content?: string;
614
- }
615
-
616
- export interface Commit {
617
- hash: CommitHash;
618
- author: string;
619
- timestamp: string;
620
- entities: EntityDiff[];
621
- }
1
+ export * from "./attribute";
2
+ export * from "./bucket";
3
+ export * from "./condition";
4
+ export * from "./context";
5
+ export * from "./datafile";
6
+ export * from "./feature";
7
+ export * from "./group";
8
+ export * from "./segment";
9
+ export * from "./site";
10
+ export * from "./state";
11
+ export * from "./test";
@@ -0,0 +1,29 @@
1
+ import type { Condition } from "./condition";
2
+
3
+ export type SegmentKey = string;
4
+
5
+ export interface Segment {
6
+ archived?: boolean; // only available in YAML files
7
+ key?: SegmentKey; // needed for supporting v1 datafile generation
8
+ conditions: Condition | Condition[]; // string only when stringified for datafile
9
+ description?: string; // only available in YAML files
10
+ }
11
+
12
+ export type PlainGroupSegment = SegmentKey;
13
+
14
+ export interface AndGroupSegment {
15
+ and: GroupSegment[];
16
+ }
17
+
18
+ export interface OrGroupSegment {
19
+ or: GroupSegment[];
20
+ }
21
+
22
+ export interface NotGroupSegment {
23
+ not: GroupSegment[];
24
+ }
25
+
26
+ export type AndOrNotGroupSegment = AndGroupSegment | OrGroupSegment | NotGroupSegment;
27
+
28
+ // group of segment keys with and/or conditions, or just string
29
+ export type GroupSegment = PlainGroupSegment | AndOrNotGroupSegment;
package/src/site.d.ts ADDED
@@ -0,0 +1,68 @@
1
+ import type { Attribute } from "./attribute";
2
+ import type { Segment, SegmentKey } from "./segment";
3
+ import type { Tag, EnvironmentKey, FeatureKey, ParsedFeature } from "./feature";
4
+
5
+ export type EntityType = "attribute" | "segment" | "feature" | "group" | "test";
6
+
7
+ export type CommitHash = string;
8
+
9
+ export interface HistoryEntity {
10
+ type: EntityType;
11
+ key: string;
12
+ }
13
+
14
+ export interface HistoryEntry {
15
+ commit: CommitHash;
16
+ author: string;
17
+ timestamp: string;
18
+ entities: HistoryEntity[];
19
+ }
20
+
21
+ export interface LastModified {
22
+ commit: CommitHash;
23
+ timestamp: string;
24
+ author: string;
25
+ }
26
+
27
+ export interface SearchIndex {
28
+ links?: {
29
+ feature: string;
30
+ segment: string;
31
+ attribute: string;
32
+ commit: CommitHash;
33
+ };
34
+ projectConfig: {
35
+ tags: Tag[];
36
+ environments: EnvironmentKey[] | false;
37
+ };
38
+ entities: {
39
+ attributes: (Attribute & {
40
+ lastModified?: LastModified;
41
+ usedInSegments: SegmentKey[];
42
+ usedInFeatures: FeatureKey[];
43
+ })[];
44
+ segments: (Segment & {
45
+ lastModified?: LastModified;
46
+ usedInFeatures: FeatureKey[];
47
+ })[];
48
+ features: (ParsedFeature & {
49
+ lastModified?: LastModified;
50
+ })[];
51
+ };
52
+ }
53
+
54
+ export interface EntityDiff {
55
+ type: EntityType;
56
+ key: string;
57
+ created?: boolean;
58
+ deleted?: boolean;
59
+ updated?: boolean;
60
+ content?: string;
61
+ }
62
+
63
+ export interface Commit {
64
+ hash: CommitHash;
65
+ author: string;
66
+ timestamp: string;
67
+ entities: EntityDiff[];
68
+ }
package/src/state.d.ts ADDED
@@ -0,0 +1,24 @@
1
+ import type { FeatureKey, RuleKey, VariationValue, Weight } from "./feature";
2
+ import type { Percentage, Allocation, Range } from "./datafile";
3
+
4
+ export interface ExistingFeature {
5
+ hash?: string;
6
+ variations?: {
7
+ value: VariationValue;
8
+ weight: Weight;
9
+ }[];
10
+ traffic: {
11
+ key: RuleKey;
12
+ percentage: Percentage;
13
+ allocation?: Allocation[];
14
+ }[];
15
+ ranges?: Range[]; // if in a Group (mutex), these are the available slot ranges
16
+ }
17
+
18
+ export interface ExistingFeatures {
19
+ [key: FeatureKey]: ExistingFeature;
20
+ }
21
+
22
+ export interface ExistingState {
23
+ features: ExistingFeatures;
24
+ }
package/src/test.d.ts ADDED
@@ -0,0 +1,118 @@
1
+ import type { AttributeValue } from "./attribute";
2
+ import type { Context } from "./context";
3
+ import type {
4
+ VariableKey,
5
+ FeatureKey,
6
+ VariationValue,
7
+ StickyFeatures,
8
+ VariableValue,
9
+ EnvironmentKey,
10
+ Weight,
11
+ } from "./feature";
12
+ import type { SegmentKey } from "./segment";
13
+
14
+ export interface AssertionMatrix {
15
+ [key: string]: AttributeValue[];
16
+ }
17
+
18
+ export interface ExpectedEvaluations {
19
+ flag?: Record<string, any>;
20
+ variation?: Record<string, any>;
21
+ variables?: {
22
+ [key: VariableKey]: Record<string, any>;
23
+ };
24
+ }
25
+
26
+ export interface FeatureChildAssertion {
27
+ sticky?: StickyFeatures;
28
+ context?: Context;
29
+
30
+ defaultVariationValue?: VariationValue;
31
+ defaultVariableValues?: {
32
+ [key: string]: VariableValue;
33
+ };
34
+
35
+ expectedToBeEnabled?: boolean;
36
+ expectedVariation?: VariationValue;
37
+ expectedVariables?: {
38
+ [key: VariableKey]: VariableValue;
39
+ };
40
+ expectedEvaluations?: ExpectedEvaluations;
41
+ }
42
+
43
+ export interface FeatureAssertion {
44
+ matrix?: AssertionMatrix;
45
+ description?: string;
46
+ environment: EnvironmentKey;
47
+ at?: Weight; // bucket weight: 0 to 100
48
+
49
+ sticky?: StickyFeatures;
50
+ context?: Context;
51
+
52
+ defaultVariationValue?: VariationValue;
53
+ defaultVariableValues?: {
54
+ [key: string]: VariableValue;
55
+ };
56
+
57
+ expectedToBeEnabled?: boolean;
58
+ expectedVariation?: VariationValue;
59
+ expectedVariables?: {
60
+ [key: VariableKey]: VariableValue;
61
+ };
62
+ expectedEvaluations?: ExpectedEvaluations;
63
+
64
+ children?: FeatureChildAssertion[];
65
+ }
66
+
67
+ export interface TestFeature {
68
+ key?: string; // file path
69
+ feature: FeatureKey;
70
+ assertions: FeatureAssertion[];
71
+ }
72
+
73
+ export interface SegmentAssertion {
74
+ matrix?: AssertionMatrix;
75
+ description?: string;
76
+ context: Context;
77
+ expectedToMatch: boolean;
78
+ }
79
+
80
+ export interface TestSegment {
81
+ key?: string; // file path
82
+ segment: SegmentKey;
83
+ assertions: SegmentAssertion[];
84
+ }
85
+
86
+ export type Test = TestSegment | TestFeature;
87
+
88
+ /**
89
+ * Used by test runner
90
+ */
91
+ export interface TestResultAssertionError {
92
+ type: "flag" | "variation" | "variable" | "segment" | "evaluation";
93
+ expected: string | number | boolean | Date | null | undefined;
94
+ actual: string | number | boolean | Date | null | undefined;
95
+ message?: string;
96
+ details?: {
97
+ evaluationType?: string; // e.g., "flag", "variation", "variable"
98
+ evaluationKey?: string; // e.g., "myFeatureKey", "myVariableKey"
99
+ childIndex?: number; // for children assertions
100
+ [key: string]: any;
101
+ };
102
+ }
103
+
104
+ export interface TestResultAssertion {
105
+ description: string;
106
+ duration: number;
107
+ passed: boolean;
108
+ errors?: TestResultAssertionError[];
109
+ }
110
+
111
+ export interface TestResult {
112
+ type: "feature" | "segment";
113
+ key: string;
114
+ notFound?: boolean;
115
+ passed: boolean;
116
+ duration: number;
117
+ assertions: TestResultAssertion[];
118
+ }
@@ -3,5 +3,5 @@
3
3
  "compilerOptions": {
4
4
  "outDir": "./lib"
5
5
  },
6
- "include": ["./src/**/*.ts"]
6
+ "include": ["./src/**/*.ts", "./src/**/*.d.ts"]
7
7
  }
package/tsconfig.cjs.json DELETED
@@ -1,7 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.cjs.json",
3
- "compilerOptions": {
4
- "outDir": "./lib"
5
- },
6
- "include": ["./src/**/*.ts"]
7
- }