-
Notifications
You must be signed in to change notification settings - Fork 2
/
types.go
366 lines (302 loc) · 10 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
package featurevisor
import "time"
type AttributeKey string
type AttributeValue struct {
String *string
Number *float64
Bool *bool
Date *time.Time
IsNil bool
}
type Context map[AttributeKey]AttributeValue
type Attribute struct {
Archived *bool `json:"archived,omitempty"`
Key string `json:"key"`
Type string `json:"type"`
Capture *bool `json:"capture,omitempty"`
}
type Operator string
const (
Equals Operator = "equals"
NotEquals Operator = "notEquals"
GreaterThan Operator = "greaterThan"
GreaterThanOrEquals Operator = "greaterThanOrEquals"
LessThan Operator = "lessThan"
LessThanOrEquals Operator = "lessThanOrEquals"
Contains Operator = "contains"
NotContains Operator = "notContains"
StartsWith Operator = "startsWith"
EndsWith Operator = "endsWith"
SemverEquals Operator = "semverEquals"
SemverNotEquals Operator = "semverNotEquals"
SemverGreaterThan Operator = "semverGreaterThan"
SemverGreaterThanOrEquals Operator = "semverGreaterThanOrEquals"
SemverLessThan Operator = "semverLessThan"
SemverLessThanOrEquals Operator = "semverLessThanOrEquals"
Before Operator = "before"
After Operator = "after"
In Operator = "in"
NotIn Operator = "notIn"
)
type ConditionValue struct {
String *string
Number *float64
Bool *bool
Date *time.Time
IsNil bool
Strings *[]string
}
type PlainCondition struct {
Attribute AttributeKey `json:"attribute"`
Operator Operator `json:"operator"`
Value ConditionValue `json:"value"`
}
type AndCondition struct {
And []Condition `json:"and"`
}
type OrCondition struct {
Or []Condition `json:"or"`
}
type NotCondition struct {
Not []Condition `json:"not"`
}
type Condition struct {
Plain *PlainCondition
And *AndCondition
Or *OrCondition
Not *NotCondition
}
type SegmentKey string
type Segment struct {
Archived *bool `json:"archived,omitempty"`
Key SegmentKey `json:"key"`
Conditions interface{} `json:"conditions"` // @TODO: This can be Condition, []Condition, or string
}
type PlainGroupSegment SegmentKey
type AndGroupSegment struct {
And []GroupSegment `json:"and"`
}
type OrGroupSegment struct {
Or []GroupSegment `json:"or"`
}
type NotGroupSegment struct {
Not []GroupSegment `json:"not"`
}
type GroupSegment struct {
Plain *PlainGroupSegment
And *AndGroupSegment
Or *OrGroupSegment
Not *NotGroupSegment
}
type VariationValue string
type VariableKey string
type VariableType string
const (
Boolean VariableType = "boolean"
String VariableType = "string"
Integer VariableType = "integer"
Double VariableType = "double"
Array VariableType = "array"
Object VariableType = "object"
Json VariableType = "json"
)
type VariableObjectValue map[string]VariableValue
type VariableValue struct {
Bool *bool
String *string
Number *float64
// ... and so on for other types
}
type VariableOverrideSegments struct {
Segments GroupSegment `json:"segments"`
}
type VariableOverrideConditions struct {
Conditions Condition `json:"conditions"`
}
type VariableOverrideBase struct {
Value VariableValue `json:"value"`
}
type VariableOverride struct {
Value VariableValue `json:"value"`
Conditions *Condition `json:"conditions,omitempty"`
Segments *GroupSegment `json:"segments,omitempty"`
}
type Variable struct {
Key VariableKey `json:"key"`
Value VariableValue `json:"value"`
Description *string `json:"description,omitempty"`
Overrides []VariableOverride `json:"overrides,omitempty"`
}
type Variation struct {
Description *string `json:"description,omitempty"`
Value VariationValue `json:"value"`
Weight *Weight `json:"weight,omitempty"`
Variables []VariableOverride `json:"variables,omitempty"`
}
type VariableSchema struct {
Key VariableKey `json:"key"`
Type VariableType `json:"type"`
DefaultValue VariableValue `json:"defaultValue"`
}
type FeatureKey string
type Force struct {
Conditions *[]Condition `json:"conditions,omitempty"`
Segments *[]GroupSegment `json:"segments,omitempty"`
Enabled *bool `json:"enabled,omitempty"`
Variation *VariationValue `json:"variation,omitempty"`
Variables *map[string]VariableValue `json:"variables,omitempty"`
}
type Slot struct {
Feature interface{} `json:"feature"` // @TODO: FeatureKey or false
Percentage Weight `json:"percentage"`
}
type Group struct {
Key string `json:"key"`
Description string `json:"description"`
Slots []Slot `json:"slots"`
}
type BucketKey string
type BucketValue int
/**
* Datafile-only types
*/
type Percentage int
type Range [2]Percentage
type Allocation struct {
Variation VariationValue `json:"variation"`
Range Range `json:"range"`
}
type Traffic struct {
Key string `json:"key"`
Segments interface{} `json:"segments"` // @TODO: GroupSegment, []GroupSegment, or "*"
Percentage Percentage `json:"percentage"`
Enabled *bool `json:"enabled,omitempty"`
Variation *VariationValue `json:"variation,omitempty"`
Variables *map[string]VariableValue `json:"variables,omitempty"`
Allocation []Allocation `json:"allocation"`
}
type PlainBucketBy AttributeKey
type AndBucketBy []AttributeKey
type OrBucketBy struct {
Or []AttributeKey `json:"or"`
}
type BucketBy struct {
Plain *PlainBucketBy
And *AndBucketBy
Or *OrBucketBy
}
type RequiredWithVariation struct {
Key FeatureKey `json:"key"`
Variation VariationValue `json:"variation"`
}
type Required struct {
Key *FeatureKey
Variation *RequiredWithVariation
}
type Feature struct {
Key FeatureKey `json:"key"`
Deprecated *bool `json:"deprecated,omitempty"`
Required *[]Required `json:"required,omitempty"`
VariablesSchema *[]VariableSchema `json:"variablesSchema,omitempty"`
Variations *[]Variation `json:"variations,omitempty"`
BucketBy BucketBy `json:"bucketBy"`
Traffic []Traffic `json:"traffic"`
Force *[]Force `json:"force,omitempty"`
Ranges *[]Range `json:"ranges,omitempty"`
}
type DatafileContent struct {
SchemaVersion string `json:"schemaVersion"`
Revision string `json:"revision"`
Attributes []Attribute `json:"attributes"`
Segments []Segment `json:"segments"`
Features []Feature `json:"features"`
}
type OverrideFeature struct {
Enabled bool `json:"enabled"`
Variation *VariationValue `json:"variation,omitempty"`
Variables *map[string]VariableValue `json:"variables,omitempty"`
}
type StickyFeatures map[FeatureKey]OverrideFeature
type InitialFeatures StickyFeatures
/**
* YAML-only types
*/
type Weight int
type EnvironmentKey string
type RuleKey string
type Rule struct {
Key RuleKey `json:"key"`
Segments []GroupSegment `json:"segments"`
Percentage Weight `json:"percentage"`
Enabled *bool `json:"enabled,omitempty"`
Variation *VariationValue `json:"variation,omitempty"`
Variables *map[string]VariableValue `json:"variables,omitempty"`
}
type Environment struct {
Expose *bool `json:"expose,omitempty"`
Rules []Rule `json:"rules"`
Force *[]Force `json:"force,omitempty"`
}
type Tag string
type ParsedFeature struct {
Key FeatureKey `json:"key"`
Archived *bool `json:"archived,omitempty"`
Deprecated *bool `json:"deprecated,omitempty"`
Description string `json:"description"`
Tags []Tag `json:"tags"`
Required *[]Required `json:"required,omitempty"`
BucketBy BucketBy `json:"bucketBy"`
VariablesSchema *[]VariableSchema `json:"variablesSchema,omitempty"`
Variations *[]Variation `json:"variations,omitempty"`
Environments map[EnvironmentKey]Environment `json:"environments"`
}
/**
* For maintaining old allocations info,
* allowing for gradual rollout of new allocations
* with consistent bucketing
*/
type ExistingFeature struct {
Variations *[]struct {
Value VariationValue `json:"value"`
Weight Weight `json:"weight"`
} `json:"variations,omitempty"`
Traffic *[]struct {
Key RuleKey `json:"key"`
Percentage Percentage `json:"percentage"`
Allocation []Allocation `json:"allocation"`
} `json:"traffic,omitempty"`
Ranges *[]Range `json:"ranges,omitempty"`
}
type ExistingFeatures map[FeatureKey]ExistingFeature
type ExistingState struct {
Features ExistingFeatures `json:"features"`
}
/**
* Tests
*/
type FeatureAssertion struct {
Description *string `json:"description,omitempty"`
Environment EnvironmentKey `json:"environment"`
At Weight `json:"at"`
Context Context `json:"context"`
ExpectedToBeEnabled bool `json:"expectedToBeEnabled"`
ExpectedVariation *VariationValue `json:"expectedVariation,omitempty"`
ExpectedVariables *map[string]VariableValue `json:"expectedVariables,omitempty"`
}
type TestFeature struct {
Feature FeatureKey `json:"feature"`
Assertions []FeatureAssertion `json:"assertions"`
}
type SegmentAssertion struct {
Description *string `json:"description,omitempty"`
Context Context `json:"context"`
ExpectedToMatch bool `json:"expectedToMatch"`
}
type TestSegment struct {
Segment SegmentKey `json:"segment"`
Assertions []SegmentAssertion `json:"assertions"`
}
type Test struct {
Segment *TestSegment
Feature *TestFeature
}