@@ -27,17 +27,21 @@ export class FeatureContext {
27
27
) { }
28
28
}
29
29
30
- const testFeatureName = 'testFeature'
31
- const customizationArnOverrideName = 'customizationArnOverride'
32
30
const featureConfigPollIntervalInMs = 30 * 60 * 1000 // 30 mins
33
- const dataCollectionFeatureName = 'IDEProjectContextDataCollection'
34
31
35
- // TODO: add real feature later
36
- export const featureDefinitions = new Map ( [
37
- [ testFeatureName , new FeatureContext ( testFeatureName , 'CONTROL' , { stringValue : 'testValue' } ) ] ,
32
+ export const Features = {
33
+ customizationArnOverride : 'customizationArnOverride' ,
34
+ dataCollectionFeature : 'IDEProjectContextDataCollection' ,
35
+ test : 'testFeature' ,
36
+ } as const
37
+
38
+ export type FeatureName = ( typeof Features ) [ keyof typeof Features ]
39
+
40
+ export const featureDefinitions = new Map < FeatureName , FeatureContext > ( [
41
+ [ Features . test , new FeatureContext ( Features . test , 'CONTROL' , { stringValue : 'testValue' } ) ] ,
38
42
[
39
- customizationArnOverrideName ,
40
- new FeatureContext ( customizationArnOverrideName , 'customizationARN' , { stringValue : '' } ) ,
43
+ Features . customizationArnOverride ,
44
+ new FeatureContext ( Features . customizationArnOverride , 'customizationARN' , { stringValue : '' } ) ,
41
45
] ,
42
46
] )
43
47
@@ -103,11 +107,12 @@ export class FeatureConfigProvider {
103
107
} )
104
108
getLogger ( ) . info ( 'AB Testing Cohort Assignments %s' , JSON . stringify ( response . featureEvaluations ) )
105
109
106
- const customizationArnOverride = this . featureConfigs . get ( customizationArnOverrideName ) ?. value ?. stringValue
110
+ const customizationArnOverride = this . featureConfigs . get ( Features . customizationArnOverride ) ?. value
111
+ ?. stringValue
107
112
if ( customizationArnOverride !== undefined ) {
108
113
// Double check if server-side wrongly returns a customizationArn to BID users
109
114
if ( isBuilderIdConnection ( AuthUtil . instance . conn ) ) {
110
- this . featureConfigs . delete ( customizationArnOverrideName )
115
+ this . featureConfigs . delete ( Features . customizationArnOverride )
111
116
} else if ( isIdcSsoConnection ( AuthUtil . instance . conn ) ) {
112
117
let availableCustomizations = undefined
113
118
try {
@@ -131,12 +136,12 @@ export class FeatureConfigProvider {
131
136
getLogger ( ) . debug (
132
137
`Customization arn ${ customizationArnOverride } not available in listAvailableCustomizations, not using`
133
138
)
134
- this . featureConfigs . delete ( customizationArnOverrideName )
139
+ this . featureConfigs . delete ( Features . customizationArnOverride )
135
140
}
136
141
}
137
142
}
138
143
139
- const dataCollectionValue = this . featureConfigs . get ( dataCollectionFeatureName ) ?. value . stringValue
144
+ const dataCollectionValue = this . featureConfigs . get ( Features . dataCollectionFeature ) ?. value . stringValue
140
145
if ( dataCollectionValue === 'data-collection' ) {
141
146
this . _isDataCollectionGroup = true
142
147
// Enable local workspace index by default, for Amzn users.
@@ -172,16 +177,16 @@ export class FeatureConfigProvider {
172
177
// 6) Add a test case for this feature.
173
178
// 7) In case `getXXX()` returns undefined, it should be treated as a default/control group.
174
179
getTestFeature ( ) : string | undefined {
175
- return this . getFeatureValueForKey ( testFeatureName ) . stringValue
180
+ return this . getFeatureValueForKey ( Features . test ) . stringValue
176
181
}
177
182
178
183
getCustomizationArnOverride ( ) : string | undefined {
179
- return this . getFeatureValueForKey ( customizationArnOverrideName ) . stringValue
184
+ return this . getFeatureValueForKey ( Features . customizationArnOverride ) . stringValue
180
185
}
181
186
182
187
// Get the feature value for the given key.
183
188
// In case of a misconfiguration, it will return a default feature value of Boolean true.
184
- private getFeatureValueForKey ( name : string ) : FeatureValue {
189
+ private getFeatureValueForKey ( name : FeatureName ) : FeatureValue {
185
190
return this . featureConfigs . get ( name ) ?. value ?? featureDefinitions . get ( name ) ?. value ?? { boolValue : true }
186
191
}
187
192
@@ -193,4 +198,28 @@ export class FeatureConfigProvider {
193
198
public static getFeatureConfigs ( ) : Map < string , FeatureContext > {
194
199
return FeatureConfigProvider . instance . featureConfigs
195
200
}
201
+
202
+ /**
203
+ * Retrieves the FeatureContext object for a given feature name.
204
+ *
205
+ * @param {string } featureName - The name of the feature.
206
+ * @returns {FeatureContext | undefined } The FeatureContext object for the specified feature, or undefined if the feature doesn't exist.
207
+ */
208
+ public static getFeature ( featureName : FeatureName ) : FeatureContext | undefined {
209
+ return FeatureConfigProvider . instance . featureConfigs . get ( featureName )
210
+ }
211
+
212
+ /**
213
+ * Checks if a feature is active or not.
214
+ *
215
+ * @param {string } featureName - The name of the feature to check.
216
+ * @returns {boolean } False if the variation is not CONTROL, otherwise True
217
+ */
218
+ public static isEnabled ( featureName : FeatureName ) : boolean {
219
+ const featureContext = FeatureConfigProvider . getFeature ( featureName )
220
+ if ( featureContext && featureContext . variation . toLocaleLowerCase ( ) !== 'control' ) {
221
+ return true
222
+ }
223
+ return false
224
+ }
196
225
}
0 commit comments