11import { engineParser } from './Engine' ;
22import { thenable } from '../utils/promise/thenable' ;
3- import { EXCEPTION , DEFINITION_NOT_FOUND } from '../utils/labels' ;
3+ import { EXCEPTION , NO_CONDITION_MATCH , DEFINITION_NOT_FOUND } from '../utils/labels' ;
44import { CONTROL } from '../utils/constants' ;
55import { ISplit , MaybeThenable } from '../dtos/types' ;
66import { IStorageAsync , IStorageSync } from '../storages/types' ;
@@ -10,24 +10,29 @@ import { ILogger } from '../logger/types';
1010import { returnSetsUnion , setToArray } from '../utils/lang/sets' ;
1111import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants' ;
1212
13- const treatmentException = {
13+ const EVALUATION_EXCEPTION = {
1414 treatment : CONTROL ,
1515 label : EXCEPTION ,
1616 config : null
1717} ;
1818
19+ let EVALUATION_NOT_FOUND = {
20+ treatment : CONTROL ,
21+ label : DEFINITION_NOT_FOUND ,
22+ config : null
23+ } ;
24+
1925function treatmentsException ( splitNames : string [ ] ) {
2026 const evaluations : Record < string , IEvaluationResult > = { } ;
2127 splitNames . forEach ( splitName => {
22- evaluations [ splitName ] = treatmentException ;
28+ evaluations [ splitName ] = EVALUATION_EXCEPTION ;
2329 } ) ;
2430 return evaluations ;
2531}
2632
27- // @TODO : test cases with no key
2833export function evaluateFeature (
2934 log : ILogger ,
30- key : SplitIO . SplitKey | undefined ,
35+ key : SplitIO . SplitKey ,
3136 splitName : string ,
3237 attributes : SplitIO . Attributes | undefined ,
3338 storage : IStorageSync | IStorageAsync ,
@@ -39,7 +44,7 @@ export function evaluateFeature(
3944 parsedSplit = storage . splits . getSplit ( splitName ) ;
4045 } catch ( e ) {
4146 // Exception on sync `getSplit` storage. Not possible ATM with InMemory and InLocal storages.
42- return treatmentException ;
47+ return EVALUATION_EXCEPTION ;
4348 }
4449
4550 if ( thenable ( parsedSplit ) ) {
@@ -53,7 +58,7 @@ export function evaluateFeature(
5358 ) ) . catch (
5459 // Exception on async `getSplit` storage. For example, when the storage is redis or
5560 // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
56- ( ) => treatmentException
61+ ( ) => EVALUATION_EXCEPTION
5762 ) ;
5863 }
5964
@@ -140,21 +145,16 @@ export function evaluateFeaturesByFlagSets(
140145
141146function getEvaluation (
142147 log : ILogger ,
143- key : SplitIO . SplitKey | undefined ,
148+ key : SplitIO . SplitKey ,
144149 splitJSON : ISplit | null ,
145150 attributes : SplitIO . Attributes | undefined ,
146151 storage : IStorageSync | IStorageAsync ,
147152 options ?: SplitIO . EvaluationOptions ,
148153) : MaybeThenable < IEvaluationResult > {
149- let evaluation : MaybeThenable < IEvaluationResult > = {
150- treatment : CONTROL ,
151- label : DEFINITION_NOT_FOUND ,
152- config : null
153- } ;
154154
155155 if ( splitJSON ) {
156156 const split = engineParser ( log , splitJSON , storage ) ;
157- evaluation = split . getTreatment ( key , attributes , evaluateFeature ) ;
157+ const evaluation = split . getTreatment ( key , attributes , evaluateFeature ) ;
158158
159159 // If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
160160 if ( thenable ( evaluation ) ) {
@@ -172,9 +172,11 @@ function getEvaluation(
172172 // @ts -expect-error impressionsDisabled is not exposed in the public typings yet.
173173 evaluation . impressionsDisabled = options ?. impressionsDisabled || splitJSON . impressionsDisabled ;
174174 }
175+
176+ return evaluation ;
175177 }
176178
177- return evaluation ;
179+ return EVALUATION_NOT_FOUND ;
178180}
179181
180182function getEvaluations (
@@ -208,3 +210,35 @@ function getEvaluations(
208210
209211 return thenables . length > 0 ? Promise . all ( thenables ) . then ( ( ) => result ) : result ;
210212}
213+
214+ export function evaluateDefaultTreatment (
215+ splitName : string ,
216+ storage : IStorageSync | IStorageAsync ,
217+ ) : MaybeThenable < IEvaluationResult > {
218+ let parsedSplit ;
219+
220+ try {
221+ parsedSplit = storage . splits . getSplit ( splitName ) ;
222+ } catch ( e ) {
223+ return EVALUATION_EXCEPTION ;
224+ }
225+
226+ return thenable ( parsedSplit ) ?
227+ parsedSplit . then ( getDefaultTreatment ) . catch ( ( ) => EVALUATION_EXCEPTION ) :
228+ getDefaultTreatment ( parsedSplit ) ;
229+ }
230+
231+ function getDefaultTreatment (
232+ splitJSON : ISplit | null ,
233+ ) : MaybeThenable < IEvaluationResult > {
234+ if ( splitJSON ) {
235+ return {
236+ treatment : splitJSON . defaultTreatment ,
237+ label : NO_CONDITION_MATCH , // "default rule"
238+ config : splitJSON . configurations && splitJSON . configurations [ splitJSON . defaultTreatment ] || null ,
239+ changeNumber : splitJSON . changeNumber
240+ } ;
241+ }
242+
243+ return EVALUATION_NOT_FOUND ;
244+ }
0 commit comments