1- import { EvaluationContext , Provider , ResolutionDetails , ParseError , FlagNotFoundError , JsonValue , OpenFeatureError , StandardResolutionReasons } from '@openfeature/js-sdk' ;
2- import SplitIO from '@splitsoftware/splitio/types/splitio' ;
1+ import {
2+ EvaluationContext ,
3+ Provider ,
4+ ResolutionDetails ,
5+ ParseError ,
6+ FlagNotFoundError ,
7+ JsonValue ,
8+ TargetingKeyMissingError ,
9+ StandardResolutionReasons ,
10+ } from "@openfeature/js-sdk" ;
11+ import type SplitIO from "@splitsoftware/splitio/types/splitio" ;
312
413export interface SplitProviderOptions {
514 splitClient : SplitIO . IClient ;
@@ -10,9 +19,11 @@ type Consumer = {
1019 attributes : SplitIO . Attributes ;
1120} ;
1221
22+ const CONTROL_VALUE_ERROR_MESSAGE = "Received the 'control' value from Split." ;
23+
1324export class OpenFeatureSplitProvider implements Provider {
1425 metadata = {
15- name : ' split' ,
26+ name : " split" ,
1627 } ;
1728 private initialized : Promise < void > ;
1829 private client : SplitIO . IClient ;
@@ -29,23 +40,26 @@ export class OpenFeatureSplitProvider implements Provider {
2940
3041 async resolveBooleanEvaluation (
3142 flagKey : string ,
32- defaultValue : boolean ,
43+ _ : boolean ,
3344 context : EvaluationContext
3445 ) : Promise < ResolutionDetails < boolean > > {
35- const details = await this . evaluateTreatment ( flagKey , this . transformContext ( context ) ) ;
46+ const details = await this . evaluateTreatment (
47+ flagKey ,
48+ this . transformContext ( context )
49+ ) ;
3650
3751 let value : boolean ;
3852 switch ( details . value as unknown ) {
39- case 'on' :
53+ case "on" :
4054 value = true ;
4155 break ;
42- case ' off' :
56+ case " off" :
4357 value = false ;
4458 break ;
45- case ' true' :
59+ case " true" :
4660 value = true ;
4761 break ;
48- case ' false' :
62+ case " false" :
4963 value = false ;
5064 break ;
5165 case true :
@@ -54,10 +68,8 @@ export class OpenFeatureSplitProvider implements Provider {
5468 case false :
5569 value = false ;
5670 break ;
57- case 'control' :
58- value = defaultValue ;
59- details . reason = 'FLAG_NOT_FOUND' ;
60- break ;
71+ case "control" :
72+ throw new FlagNotFoundError ( CONTROL_VALUE_ERROR_MESSAGE ) ;
6173 default :
6274 throw new ParseError ( `Invalid boolean value for ${ details . value } ` ) ;
6375 }
@@ -69,9 +81,12 @@ export class OpenFeatureSplitProvider implements Provider {
6981 _ : string ,
7082 context : EvaluationContext
7183 ) : Promise < ResolutionDetails < string > > {
72- const details = await this . evaluateTreatment ( flagKey , this . transformContext ( context ) ) ;
73- if ( details . value == 'control' ) {
74- throw new FlagNotFoundError ( `Got error for split ${ flagKey } ` ) ;
84+ const details = await this . evaluateTreatment (
85+ flagKey ,
86+ this . transformContext ( context )
87+ ) ;
88+ if ( details . value === "control" ) {
89+ throw new FlagNotFoundError ( CONTROL_VALUE_ERROR_MESSAGE ) ;
7590 }
7691 return details ;
7792 }
@@ -81,7 +96,10 @@ export class OpenFeatureSplitProvider implements Provider {
8196 _ : number ,
8297 context : EvaluationContext
8398 ) : Promise < ResolutionDetails < number > > {
84- const details = await this . evaluateTreatment ( flagKey , this . transformContext ( context ) ) ;
99+ const details = await this . evaluateTreatment (
100+ flagKey ,
101+ this . transformContext ( context )
102+ ) ;
85103 return { ...details , value : this . parseValidNumber ( details . value ) } ;
86104 }
87105
@@ -90,26 +108,32 @@ export class OpenFeatureSplitProvider implements Provider {
90108 _ : U ,
91109 context : EvaluationContext
92110 ) : Promise < ResolutionDetails < U > > {
93- const details = await this . evaluateTreatment ( flagKey , this . transformContext ( context ) ) ;
111+ const details = await this . evaluateTreatment (
112+ flagKey ,
113+ this . transformContext ( context )
114+ ) ;
94115 return { ...details , value : this . parseValidJsonObject ( details . value ) } ;
95116 }
96117
97- private async evaluateTreatment ( flagKey : string , consumer : Consumer ) : Promise < ResolutionDetails < string > > {
118+ private async evaluateTreatment (
119+ flagKey : string ,
120+ consumer : Consumer
121+ ) : Promise < ResolutionDetails < string > > {
98122 if ( ! consumer . key ) {
99- const details : ResolutionDetails < string > = {
100- value : 'control' ,
101- variant : 'control' ,
102- reason : StandardResolutionReasons . ERROR ,
103- errorCode : 'TARGETING_KEY_MISSING'
104- }
105- return details ;
123+ throw new TargetingKeyMissingError (
124+ "The Split provider requires a targeting key."
125+ ) ;
106126 } else {
107127 await this . initialized ;
108- const value = this . client . getTreatment ( consumer . key , flagKey , consumer . attributes ) ;
128+ const value = this . client . getTreatment (
129+ consumer . key ,
130+ flagKey ,
131+ consumer . attributes
132+ ) ;
109133 const details : ResolutionDetails < string > = {
110134 value : value ,
111135 variant : value ,
112- reason : StandardResolutionReasons . TARGETING_MATCH
136+ reason : StandardResolutionReasons . TARGETING_MATCH ,
113137 } ;
114138 return details ;
115139 }
@@ -136,14 +160,16 @@ export class OpenFeatureSplitProvider implements Provider {
136160 return result ;
137161 }
138162
139- private parseValidJsonObject < T extends JsonValue > ( stringValue : string | undefined ) : T {
163+ private parseValidJsonObject < T extends JsonValue > (
164+ stringValue : string | undefined
165+ ) : T {
140166 if ( stringValue === undefined ) {
141167 throw new ParseError ( `Invalid 'undefined' JSON value.` ) ;
142168 }
143169 // we may want to allow the parsing to be customized.
144170 try {
145171 const value = JSON . parse ( stringValue ) ;
146- if ( typeof value !== ' object' ) {
172+ if ( typeof value !== " object" ) {
147173 throw new ParseError (
148174 `Flag value ${ stringValue } had unexpected type ${ typeof value } , expected "object"`
149175 ) ;
0 commit comments