@@ -4,23 +4,154 @@ import { IDefinitionChangesFetcher } from './types';
44import SplitIO from '../../../../types/splitio' ;
55import { ISdkFactoryContextSync } from '../../../sdkFactory/types' ;
66
7- type IConfigMatcher = {
8- type : 'IS_EQUAL_TO' ;
9- data : { type : 'NUMBER' ; number : number } ;
10- attribute ?: string ;
11- } | {
12- type : 'WHITELIST' ;
7+ type IConfigMatcherDataType = 'DATETIME' | 'NUMBER'
8+
9+ interface IConfigMatcherBase {
10+ type : string ;
11+ attribute ?: string | null ;
12+ data ?:
13+ { type ?: IConfigMatcherDataType ; number : number } |
14+ { type ?: IConfigMatcherDataType ; start : number ; end : number } |
15+ { strings : string [ ] } |
16+ { name : string } |
17+ { config : string ; variants : string [ ] } |
18+ { value : boolean } |
19+ { string : string } |
20+ { start : string ; end : string }
21+ }
22+
23+ interface IAllKeysConfigMatcher extends IConfigMatcherBase {
24+ type : 'ALL_KEYS'
25+ }
26+
27+ interface IWhitelistConfigMatcher extends IConfigMatcherBase {
28+ type : 'WHITELIST' ,
29+ data : { strings : string [ ] }
30+ }
31+
32+ interface IEqualToConfigMatcher extends IConfigMatcherBase {
33+ type : 'EQUAL_TO' ;
34+ data : { type ?: IConfigMatcherDataType ; number : number } ;
35+ }
36+
37+ interface IGreaterThanOrEqualToConfigMatcher extends IConfigMatcherBase {
38+ type : 'GREATER_THAN_OR_EQUAL_TO' ;
39+ data : { type ?: IConfigMatcherDataType ; number : number } ;
40+ }
41+
42+ interface ILessThanOrEqualToConfigMatcher extends IConfigMatcherBase {
43+ type : 'LESS_THAN_OR_EQUAL_TO' ;
44+ data : { type ?: IConfigMatcherDataType ; number : number } ;
45+ }
46+
47+ interface IBetweenConfigMatcher extends IConfigMatcherBase {
48+ type : 'BETWEEN' ;
49+ data : { type ?: IConfigMatcherDataType ; start : number ; end : number } ;
50+ }
51+
52+ interface IInSegmentConfigMatcher extends IConfigMatcherBase {
53+ type : 'IN_SEGMENT' ;
54+ data : { name : string } ;
55+ }
56+
57+ interface IInRBSegmentConfigMatcher extends IConfigMatcherBase {
58+ type : 'IN_RULE_BASED_SEGMENT' ;
59+ data : { name : string } ;
60+ }
61+
62+ interface IInLargeSegmentConfigMatcher extends IConfigMatcherBase {
63+ type : 'IN_LARGE_SEGMENT' ;
64+ data : { name : string } ;
65+ }
66+
67+ interface IEqualToSetConfigMatcher extends IConfigMatcherBase {
68+ type : 'EQUAL_TO_SET' ;
69+ data : { strings : string [ ] } ;
70+ }
71+
72+ interface IContainsAnyOfSetConfigMatcher extends IConfigMatcherBase {
73+ type : 'CONTAINS_ANY_OF_SET' ;
74+ data : { strings : string [ ] } ;
75+ }
76+
77+ interface IContainsAllOfSetConfigMatcher extends IConfigMatcherBase {
78+ type : 'CONTAINS_ALL_OF_SET' ;
79+ data : { strings : string [ ] } ;
80+ }
81+
82+ interface IPartOfSetConfigMatcher extends IConfigMatcherBase {
83+ type : 'PART_OF_SET' ;
84+ data : { strings : string [ ] } ;
85+ }
86+
87+ interface IStartsWithConfigMatcher extends IConfigMatcherBase {
88+ type : 'STARTS_WITH' ;
89+ data : { strings : string [ ] } ;
90+ }
91+
92+ interface IEndsWithConfigMatcher extends IConfigMatcherBase {
93+ type : 'ENDS_WITH' ;
94+ data : { strings : string [ ] } ;
95+ }
96+
97+ interface IContainsStringConfigMatcher extends IConfigMatcherBase {
98+ type : 'CONTAINS_STRING' ;
99+ data : { strings : string [ ] } ;
100+ }
101+
102+ interface IInListSemverConfigMatcher extends IConfigMatcherBase {
103+ type : 'IN_LIST_SEMVER' ;
13104 data : { strings : string [ ] } ;
14- attribute ?: string ;
15105}
16106
107+ interface IInConfigVariantConfigMatcher extends IConfigMatcherBase {
108+ type : 'IN_CONFIG_VARIANT' ;
109+ data : { config : string ; variants : string [ ] } ;
110+ }
111+
112+ interface IEqualToBooleanConfigMatcher extends IConfigMatcherBase {
113+ type : 'EQUAL_TO_BOOLEAN' ;
114+ data : { value : boolean } ;
115+ }
116+
117+ interface IMatchesStringConfigMatcher extends IConfigMatcherBase {
118+ type : 'MATCHES_STRING' ;
119+ data : { string : string } ;
120+ }
121+
122+ interface IEqualToSemverConfigMatcher extends IConfigMatcherBase {
123+ type : 'EQUAL_TO_SEMVER' ;
124+ data : { string : string } ;
125+ }
126+
127+ interface IGreaterThanOrEqualToSemverConfigMatcher extends IConfigMatcherBase {
128+ type : 'GREATER_THAN_OR_EQUAL_TO_SEMVER' ;
129+ data : { string : string } ;
130+ }
131+
132+ interface ILessThanOrEqualToSemverConfigMatcher extends IConfigMatcherBase {
133+ type : 'LESS_THAN_OR_EQUAL_TO_SEMVER' ;
134+ data : { string : string } ;
135+ }
136+
137+ interface IBetweenSemverConfigMatcher extends IConfigMatcherBase {
138+ type : 'BETWEEN_SEMVER' ;
139+ data : { start : string ; end : string } ;
140+ }
141+
142+ type IConfigMatcher = IAllKeysConfigMatcher | IInSegmentConfigMatcher | IWhitelistConfigMatcher | IEqualToConfigMatcher | IGreaterThanOrEqualToConfigMatcher |
143+ ILessThanOrEqualToConfigMatcher | IBetweenConfigMatcher | IEqualToSetConfigMatcher | IContainsAnyOfSetConfigMatcher | IContainsAllOfSetConfigMatcher | IPartOfSetConfigMatcher |
144+ IStartsWithConfigMatcher | IEndsWithConfigMatcher | IContainsStringConfigMatcher | IInConfigVariantConfigMatcher | IEqualToBooleanConfigMatcher | IMatchesStringConfigMatcher |
145+ IEqualToSemverConfigMatcher | IGreaterThanOrEqualToSemverConfigMatcher | ILessThanOrEqualToSemverConfigMatcher | IBetweenSemverConfigMatcher | IInListSemverConfigMatcher |
146+ IInLargeSegmentConfigMatcher | IInRBSegmentConfigMatcher
147+
17148interface IConfigPartition {
18149 variant : string
19150 size : number
20151}
21152
22153interface IConfig {
23- name : string ;
154+ identifier : string ;
24155 variants : Array < {
25156 name : string ;
26157 definition : SplitIO . JsonObject ;
@@ -37,6 +168,7 @@ interface IConfig {
37168 trafficAllocation ?: number ,
38169 trafficAllocationSeed ?: number ,
39170 conditions ?: Array < {
171+ type ?: 'ROLLOUT' | 'WHITELIST' ;
40172 label : string ;
41173 partitions : Array < IConfigPartition > ;
42174 matchers : Array < IConfigMatcher > ;
@@ -77,7 +209,6 @@ export function configsFetcherFactory(params: ISdkFactoryContextSync): IDefiniti
77209
78210 configsFetcher . type = 'configs' as const ;
79211 return configsFetcher ;
80-
81212}
82213
83214function defaultCondition ( treatment : string ) : IDefinitionCondition {
@@ -96,25 +227,33 @@ function defaultCondition(treatment: string): IDefinitionCondition {
96227 } ;
97228}
98229
230+ const wl = ( d : { strings : string [ ] } ) => ( { whitelistMatcherData : { whitelist : d . strings } } ) ;
231+ const num = ( d : { type ?: IConfigMatcherDataType ; number : number } ) => ( { unaryNumericMatcherData : { dataType : d . type || 'NUMBER' , value : d . number } } ) ;
232+ const seg = ( d : { name : string } ) => ( { userDefinedSegmentMatcherData : { segmentName : d . name } } ) ;
233+ const str = ( d : { string : string } ) => ( { stringMatcherData : d . string } ) ;
234+
235+ const MATCHER_CONVERTERS : Record < IConfigMatcher [ 'type' ] , ( data : any ) => Record < string , any > > = {
236+ ALL_KEYS : ( ) => ( { } ) ,
237+ IN_SEGMENT : seg , IN_RULE_BASED_SEGMENT : seg ,
238+ IN_LARGE_SEGMENT : ( d ) => ( { userDefinedLargeSegmentMatcherData : { largeSegmentName : d . name } } ) ,
239+ WHITELIST : wl , EQUAL_TO_SET : wl , CONTAINS_ANY_OF_SET : wl , CONTAINS_ALL_OF_SET : wl ,
240+ PART_OF_SET : wl , STARTS_WITH : wl , ENDS_WITH : wl , CONTAINS_STRING : wl , IN_LIST_SEMVER : wl ,
241+ EQUAL_TO : num , GREATER_THAN_OR_EQUAL_TO : num , LESS_THAN_OR_EQUAL_TO : num ,
242+ BETWEEN : ( d ) => ( { betweenMatcherData : { dataType : d . type || 'NUMBER' , start : d . start , end : d . end } } ) ,
243+ IN_CONFIG_VARIANT : ( d ) => ( { dependencyMatcherData : { split : d . config , treatments : d . variants } } ) ,
244+ EQUAL_TO_BOOLEAN : ( d ) => ( { booleanMatcherData : d . value } ) ,
245+ MATCHES_STRING : str , EQUAL_TO_SEMVER : str , GREATER_THAN_OR_EQUAL_TO_SEMVER : str , LESS_THAN_OR_EQUAL_TO_SEMVER : str ,
246+ BETWEEN_SEMVER : ( d ) => ( { betweenStringMatcherData : { start : d . start , end : d . end } } ) ,
247+ } ;
248+
99249function convertMatcher ( matcher : IConfigMatcher ) : IDefinitionMatcher {
100250 const keySelector = matcher . attribute ? { trafficType : 'user' , attribute : matcher . attribute } : null ;
101-
102- switch ( matcher . type ) {
103- case 'IS_EQUAL_TO' :
104- return {
105- matcherType : 'EQUAL_TO' ,
106- negate : false ,
107- keySelector,
108- unaryNumericMatcherData : { dataType : matcher . data . type , value : matcher . data . number } ,
109- } ;
110- case 'WHITELIST' :
111- return {
112- matcherType : 'WHITELIST' ,
113- negate : false ,
114- keySelector,
115- whitelistMatcherData : { whitelist : matcher . data . strings } ,
116- } ;
117- }
251+ return {
252+ matcherType : matcher . type ,
253+ negate : false ,
254+ keySelector,
255+ ...MATCHER_CONVERTERS [ matcher . type ] ( matcher . data ) ,
256+ } as IDefinitionMatcher ;
118257}
119258
120259function convertConfigToDefinition ( config : IConfig ) : IDefinition {
@@ -124,7 +263,7 @@ function convertConfigToDefinition(config: IConfig): IDefinition {
124263 config . variants . forEach ( variant => configurations [ variant . name ] = variant . definition ) ;
125264
126265 const conditions : IDefinitionCondition [ ] = config . targeting ?. conditions ?. map ( condition => ( {
127- conditionType : condition . matchers . some ( ( m : IConfigMatcher ) => m . type === 'WHITELIST' ) ? 'WHITELIST' : 'ROLLOUT' ,
266+ conditionType : condition . type || ( condition . matchers . some ( ( m : IConfigMatcher ) => m . type === 'WHITELIST' ) ? 'WHITELIST' : 'ROLLOUT' ) ,
128267 label : condition . label ,
129268 matcherGroup : {
130269 combiner : 'AND' ,
@@ -133,10 +272,13 @@ function convertConfigToDefinition(config: IConfig): IDefinition {
133272 partitions : condition . partitions . map ( partition => ( { treatment : partition . variant , size : partition . size } ) ) ,
134273 } ) ) || [ ] ;
135274
136- conditions . push ( defaultCondition ( defaultTreatment ) ) ;
275+ // only add default condition if there is no a last condition with matcher type ALL_KEYS
276+ if ( ! conditions . some ( condition => condition . matcherGroup . matchers . some ( matcher => matcher . matcherType === 'ALL_KEYS' ) ) ) {
277+ conditions . push ( defaultCondition ( defaultTreatment ) ) ;
278+ }
137279
138280 return {
139- name : config . name ,
281+ name : config . identifier ,
140282 changeNumber : config . changeNumber || 0 ,
141283 status : 'ACTIVE' ,
142284 conditions,
0 commit comments