@splitsoftware/splitio-commons 1.13.2-rc.1 → 1.13.2-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/CHANGES.txt +4 -3
  2. package/cjs/evaluator/Engine.js +5 -6
  3. package/cjs/evaluator/combiners/ifelseif.js +2 -3
  4. package/cjs/evaluator/condition/index.js +2 -3
  5. package/cjs/evaluator/index.js +4 -5
  6. package/cjs/evaluator/matchers/all.js +1 -3
  7. package/cjs/evaluator/matchers/between.js +1 -3
  8. package/cjs/evaluator/matchers/boolean.js +1 -3
  9. package/cjs/evaluator/matchers/cont_all.js +1 -3
  10. package/cjs/evaluator/matchers/cont_any.js +1 -3
  11. package/cjs/evaluator/matchers/cont_str.js +1 -3
  12. package/cjs/evaluator/matchers/dependency.js +1 -1
  13. package/cjs/evaluator/matchers/eq.js +1 -3
  14. package/cjs/evaluator/matchers/eq_set.js +1 -3
  15. package/cjs/evaluator/matchers/ew.js +1 -3
  16. package/cjs/evaluator/matchers/gte.js +3 -5
  17. package/cjs/evaluator/matchers/index.js +12 -2
  18. package/cjs/evaluator/matchers/lte.js +3 -5
  19. package/cjs/evaluator/matchers/matcherTypes.js +6 -1
  20. package/cjs/evaluator/matchers/part_of.js +1 -3
  21. package/cjs/evaluator/matchers/segment.js +1 -6
  22. package/cjs/evaluator/matchers/semver_between.js +14 -0
  23. package/cjs/evaluator/matchers/semver_eq.js +13 -0
  24. package/cjs/evaluator/matchers/semver_gte.js +13 -0
  25. package/cjs/evaluator/matchers/semver_inlist.js +17 -0
  26. package/cjs/evaluator/matchers/semver_lte.js +13 -0
  27. package/cjs/evaluator/matchers/string.js +3 -12
  28. package/cjs/evaluator/matchers/sw.js +1 -3
  29. package/cjs/evaluator/matchers/whitelist.js +3 -4
  30. package/cjs/evaluator/matchersTransform/index.js +21 -16
  31. package/cjs/evaluator/matchersTransform/whitelist.js +2 -3
  32. package/cjs/evaluator/parser/index.js +23 -7
  33. package/cjs/logger/constants.js +5 -20
  34. package/cjs/logger/index.js +8 -1
  35. package/cjs/logger/messages/debug.js +5 -21
  36. package/cjs/logger/messages/error.js +2 -1
  37. package/cjs/logger/messages/warn.js +1 -1
  38. package/cjs/services/splitApi.js +5 -5
  39. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
  40. package/cjs/storages/pluggable/index.js +1 -1
  41. package/cjs/utils/Semver.js +103 -0
  42. package/cjs/utils/labels/index.js +1 -1
  43. package/cjs/utils/settingsValidation/logger/pluggableLogger.js +1 -1
  44. package/esm/evaluator/Engine.js +5 -5
  45. package/esm/evaluator/combiners/ifelseif.js +2 -2
  46. package/esm/evaluator/condition/index.js +2 -2
  47. package/esm/evaluator/index.js +4 -4
  48. package/esm/evaluator/matchers/all.js +1 -3
  49. package/esm/evaluator/matchers/between.js +1 -3
  50. package/esm/evaluator/matchers/boolean.js +1 -3
  51. package/esm/evaluator/matchers/cont_all.js +1 -3
  52. package/esm/evaluator/matchers/cont_any.js +1 -3
  53. package/esm/evaluator/matchers/cont_str.js +1 -3
  54. package/esm/evaluator/matchers/dependency.js +1 -1
  55. package/esm/evaluator/matchers/eq.js +1 -3
  56. package/esm/evaluator/matchers/eq_set.js +1 -3
  57. package/esm/evaluator/matchers/ew.js +1 -3
  58. package/esm/evaluator/matchers/gte.js +3 -5
  59. package/esm/evaluator/matchers/index.js +12 -2
  60. package/esm/evaluator/matchers/lte.js +3 -5
  61. package/esm/evaluator/matchers/matcherTypes.js +6 -1
  62. package/esm/evaluator/matchers/part_of.js +1 -3
  63. package/esm/evaluator/matchers/segment.js +1 -6
  64. package/esm/evaluator/matchers/semver_between.js +10 -0
  65. package/esm/evaluator/matchers/semver_eq.js +9 -0
  66. package/esm/evaluator/matchers/semver_gte.js +9 -0
  67. package/esm/evaluator/matchers/semver_inlist.js +13 -0
  68. package/esm/evaluator/matchers/semver_lte.js +9 -0
  69. package/esm/evaluator/matchers/string.js +3 -12
  70. package/esm/evaluator/matchers/sw.js +1 -3
  71. package/esm/evaluator/matchers/whitelist.js +4 -5
  72. package/esm/evaluator/matchersTransform/index.js +21 -16
  73. package/esm/evaluator/matchersTransform/whitelist.js +2 -3
  74. package/esm/evaluator/parser/index.js +23 -7
  75. package/esm/logger/constants.js +2 -17
  76. package/esm/logger/index.js +9 -2
  77. package/esm/logger/messages/debug.js +5 -21
  78. package/esm/logger/messages/error.js +2 -1
  79. package/esm/logger/messages/warn.js +1 -1
  80. package/esm/services/splitApi.js +5 -5
  81. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +1 -1
  82. package/esm/storages/pluggable/index.js +1 -1
  83. package/esm/utils/Semver.js +100 -0
  84. package/esm/utils/labels/index.js +1 -1
  85. package/esm/utils/settingsValidation/logger/pluggableLogger.js +1 -1
  86. package/package.json +1 -2
  87. package/src/dtos/types.ts +34 -1
  88. package/src/evaluator/Engine.ts +5 -6
  89. package/src/evaluator/combiners/ifelseif.ts +2 -2
  90. package/src/evaluator/condition/index.ts +2 -2
  91. package/src/evaluator/index.ts +4 -4
  92. package/src/evaluator/matchers/all.ts +1 -5
  93. package/src/evaluator/matchers/between.ts +3 -7
  94. package/src/evaluator/matchers/boolean.ts +2 -6
  95. package/src/evaluator/matchers/cont_all.ts +1 -5
  96. package/src/evaluator/matchers/cont_any.ts +1 -5
  97. package/src/evaluator/matchers/cont_str.ts +2 -6
  98. package/src/evaluator/matchers/dependency.ts +1 -1
  99. package/src/evaluator/matchers/eq.ts +2 -6
  100. package/src/evaluator/matchers/eq_set.ts +1 -5
  101. package/src/evaluator/matchers/ew.ts +2 -6
  102. package/src/evaluator/matchers/gte.ts +3 -7
  103. package/src/evaluator/matchers/index.ts +29 -19
  104. package/src/evaluator/matchers/lte.ts +3 -7
  105. package/src/evaluator/matchers/matcherTypes.ts +6 -1
  106. package/src/evaluator/matchers/part_of.ts +1 -5
  107. package/src/evaluator/matchers/segment.ts +1 -8
  108. package/src/evaluator/matchers/semver_between.ts +15 -0
  109. package/src/evaluator/matchers/semver_eq.ts +13 -0
  110. package/src/evaluator/matchers/semver_gte.ts +13 -0
  111. package/src/evaluator/matchers/semver_inlist.ts +17 -0
  112. package/src/evaluator/matchers/semver_lte.ts +13 -0
  113. package/src/evaluator/matchers/string.ts +3 -16
  114. package/src/evaluator/matchers/sw.ts +2 -6
  115. package/src/evaluator/matchers/whitelist.ts +5 -7
  116. package/src/evaluator/matchersTransform/index.ts +31 -23
  117. package/src/evaluator/matchersTransform/whitelist.ts +4 -5
  118. package/src/evaluator/parser/index.ts +24 -8
  119. package/src/evaluator/types.ts +3 -3
  120. package/src/logger/constants.ts +2 -17
  121. package/src/logger/index.ts +8 -2
  122. package/src/logger/messages/debug.ts +5 -21
  123. package/src/logger/messages/error.ts +2 -1
  124. package/src/logger/messages/warn.ts +1 -1
  125. package/src/services/splitApi.ts +4 -5
  126. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +1 -1
  127. package/src/storages/pluggable/index.ts +1 -1
  128. package/src/utils/Semver.ts +111 -0
  129. package/src/utils/labels/index.ts +1 -1
  130. package/src/utils/settingsValidation/logger/pluggableLogger.ts +1 -1
  131. package/types/dtos/types.d.ts +26 -1
  132. package/types/evaluator/matchers/all.d.ts +1 -2
  133. package/types/evaluator/matchers/between.d.ts +1 -2
  134. package/types/evaluator/matchers/boolean.d.ts +1 -2
  135. package/types/evaluator/matchers/cont_all.d.ts +1 -2
  136. package/types/evaluator/matchers/cont_any.d.ts +1 -2
  137. package/types/evaluator/matchers/cont_str.d.ts +1 -2
  138. package/types/evaluator/matchers/dependency.d.ts +1 -1
  139. package/types/evaluator/matchers/eq.d.ts +1 -2
  140. package/types/evaluator/matchers/eq_set.d.ts +1 -2
  141. package/types/evaluator/matchers/ew.d.ts +1 -2
  142. package/types/evaluator/matchers/gte.d.ts +1 -2
  143. package/types/evaluator/matchers/lte.d.ts +1 -2
  144. package/types/evaluator/matchers/part_of.d.ts +1 -2
  145. package/types/evaluator/matchers/segment.d.ts +1 -2
  146. package/types/evaluator/matchers/sember_inlist.d.ts +3 -0
  147. package/types/evaluator/matchers/semver_between.d.ts +2 -0
  148. package/types/evaluator/matchers/semver_eq.d.ts +1 -0
  149. package/types/evaluator/matchers/semver_gte.d.ts +1 -0
  150. package/types/evaluator/matchers/semver_inlist.d.ts +1 -0
  151. package/types/evaluator/matchers/semver_lte.d.ts +1 -0
  152. package/types/evaluator/matchers/string.d.ts +1 -2
  153. package/types/evaluator/matchers/sw.d.ts +1 -2
  154. package/types/evaluator/matchers/whitelist.d.ts +1 -3
  155. package/types/evaluator/matchersTransform/set.d.ts +2 -2
  156. package/types/evaluator/matchersTransform/string.d.ts +7 -0
  157. package/types/evaluator/matchersTransform/whitelist.d.ts +3 -3
  158. package/types/evaluator/types.d.ts +3 -3
  159. package/types/logger/constants.d.ts +2 -17
  160. package/types/utils/labels/index.d.ts +1 -1
  161. package/types/utils/semVer.d.ts +15 -0
  162. package/cjs/evaluator/matchersTransform/set.js +0 -10
  163. package/esm/evaluator/matchersTransform/set.js +0 -6
  164. package/src/evaluator/matchersTransform/set.ts +0 -8
@@ -0,0 +1,100 @@
1
+ import { isString } from '../utils/lang';
2
+ var NUMERIC_IDENTIFIER_REGEX = /^[0-9]+$/;
3
+ var METADATA_DELIMITER = '+';
4
+ var PRERELEASE_DELIMITER = '-';
5
+ var VALUE_DELIMITER = '.';
6
+ /**
7
+ * Compares two strings. If both strings are numeric identifiers, they are compared numerically. Otherwise, they are compared lexicographically.
8
+ * This could be implemented using `a.localeCompare(b, undefined, { numeric: true })` but locale options are not broadly supported.
9
+ */
10
+ function compareStrings(a, b) {
11
+ if (NUMERIC_IDENTIFIER_REGEX.test(a) && NUMERIC_IDENTIFIER_REGEX.test(b)) {
12
+ var result = a.length - b.length;
13
+ if (result !== 0) {
14
+ return result;
15
+ }
16
+ }
17
+ return a < b ? -1 : a > b ? 1 : 0;
18
+ }
19
+ // Sanitizes a numeric identifier by removing leading zeros
20
+ function sanitizeNumericIdentifier(value) {
21
+ return value.replace(/^0+(?=\d)/, '');
22
+ }
23
+ function throwError(version) {
24
+ throw new Error('Unable to convert to Semver, incorrect format: ' + version);
25
+ }
26
+ var Semver = /** @class */ (function () {
27
+ function Semver(version) {
28
+ if (!isString(version))
29
+ throwError(version);
30
+ // Separate metadata if exists
31
+ var index = version.indexOf(METADATA_DELIMITER);
32
+ var _a = index === -1 ? [version] : [version.slice(0, index), version.slice(index + 1)], vWithoutMetadata = _a[0], metadata = _a[1];
33
+ if (metadata === '')
34
+ throwError(version);
35
+ // Set pre-release versions if exists
36
+ index = vWithoutMetadata.indexOf(PRERELEASE_DELIMITER);
37
+ if (index === -1) {
38
+ this._isStable = true;
39
+ this._preRelease = [];
40
+ }
41
+ else {
42
+ this._isStable = false;
43
+ this._preRelease = vWithoutMetadata.slice(index + 1).split(VALUE_DELIMITER).map(function (value) {
44
+ if (!value)
45
+ throwError(version);
46
+ return NUMERIC_IDENTIFIER_REGEX.test(value) ?
47
+ sanitizeNumericIdentifier(value) :
48
+ value;
49
+ });
50
+ vWithoutMetadata = vWithoutMetadata.slice(0, index);
51
+ }
52
+ // Set major, minor, and patch versions
53
+ var vParts = vWithoutMetadata.split(VALUE_DELIMITER).map(function (value) {
54
+ if (!value || !NUMERIC_IDENTIFIER_REGEX.test(value))
55
+ throwError(version);
56
+ return sanitizeNumericIdentifier(value);
57
+ });
58
+ if (vParts.length !== 3)
59
+ throwError(version);
60
+ this._major = vParts[0];
61
+ this._minor = vParts[1];
62
+ this._patch = vParts[2];
63
+ // Set version string
64
+ this.version = vParts.join(VALUE_DELIMITER);
65
+ if (this._preRelease.length)
66
+ this.version += PRERELEASE_DELIMITER + this._preRelease.join(VALUE_DELIMITER);
67
+ if (metadata)
68
+ this.version += METADATA_DELIMITER + metadata;
69
+ }
70
+ /**
71
+ * Precedence comparision between 2 Semver objects.
72
+ *
73
+ * @return `0` if `this === toCompare`, `-1` if `this < toCompare`, and `1` if `this > toCompare`
74
+ */
75
+ Semver.prototype.compare = function (toCompare) {
76
+ if (this.version === toCompare.version)
77
+ return 0;
78
+ var result = compareStrings(this._major, toCompare._major);
79
+ if (result !== 0)
80
+ return result;
81
+ result = compareStrings(this._minor, toCompare._minor);
82
+ if (result !== 0)
83
+ return result;
84
+ result = compareStrings(this._patch, toCompare._patch);
85
+ if (result !== 0)
86
+ return result;
87
+ if (!this._isStable && toCompare._isStable)
88
+ return -1;
89
+ if (this._isStable && !toCompare._isStable)
90
+ return 1;
91
+ for (var i = 0, length_1 = Math.min(this._preRelease.length, toCompare._preRelease.length); i < length_1; i++) {
92
+ var result_1 = compareStrings(this._preRelease[i], toCompare._preRelease[i]);
93
+ if (result_1 !== 0)
94
+ return result_1;
95
+ }
96
+ return this._preRelease.length - toCompare._preRelease.length;
97
+ };
98
+ return Semver;
99
+ }());
100
+ export { Semver };
@@ -5,4 +5,4 @@ export var SDK_NOT_READY = 'not ready';
5
5
  export var EXCEPTION = 'exception';
6
6
  export var SPLIT_ARCHIVED = 'archived';
7
7
  export var NOT_IN_SPLIT = 'not in split';
8
- export var UNSUPPORTED_MATCHER_TYPE = 'unsupported matcher type';
8
+ export var UNSUPPORTED_MATCHER_TYPE = 'targeting rule type unsupported by sdk';
@@ -1,7 +1,7 @@
1
1
  import { Logger, LogLevels } from '../../../logger';
2
2
  import { getLogLevel } from './commons';
3
3
  function isLogger(log) {
4
- return log && typeof log.debug === 'function' && typeof log.info === 'function' && typeof log.warn === 'function' && typeof log.error === 'function' && typeof log.setLogLevel === 'function';
4
+ return log !== null && typeof log === 'object' && typeof log.debug === 'function' && typeof log.info === 'function' && typeof log.warn === 'function' && typeof log.error === 'function' && typeof log.setLogLevel === 'function';
5
5
  }
6
6
  // By default it starts disabled.
7
7
  var initialLogLevel = LogLevels.NONE;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "1.13.2-rc.1",
3
+ "version": "1.13.2-rc.10",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -63,7 +63,6 @@
63
63
  "@typescript-eslint/eslint-plugin": "^6.6.0",
64
64
  "@typescript-eslint/parser": "^6.6.0",
65
65
  "cross-env": "^7.0.2",
66
- "csv-streamify": "^4.0.0",
67
66
  "eslint": "^8.48.0",
68
67
  "eslint-plugin-compat": "^4.2.0",
69
68
  "eslint-plugin-import": "^2.25.3",
package/src/dtos/types.ts CHANGED
@@ -17,6 +17,11 @@ export interface IBetweenMatcherData {
17
17
  end: number
18
18
  }
19
19
 
20
+ export interface IBetweenStringMatcherData {
21
+ start: string
22
+ end: string
23
+ }
24
+
20
25
  export interface IWhitelistMatcherData {
21
26
  whitelist: string[]
22
27
  }
@@ -44,6 +49,7 @@ interface ISplitMatcherBase {
44
49
  dependencyMatcherData?: null | IDependencyMatcherData
45
50
  booleanMatcherData?: null | boolean
46
51
  stringMatcherData?: null | string
52
+ betweenStringMatcherData?: null | IBetweenStringMatcherData
47
53
  }
48
54
 
49
55
  interface IAllKeysMatcher extends ISplitMatcherBase {
@@ -130,9 +136,36 @@ interface IMatchesStringMatcher extends ISplitMatcherBase {
130
136
  stringMatcherData: string
131
137
  }
132
138
 
139
+ interface IEqualToSemverMatcher extends ISplitMatcherBase {
140
+ matcherType: 'EQUAL_TO_SEMVER',
141
+ stringMatcherData: string
142
+ }
143
+
144
+ interface IGreaterThanOrEqualToSemverMatcher extends ISplitMatcherBase {
145
+ matcherType: 'GREATER_THAN_OR_EQUAL_TO_SEMVER',
146
+ stringMatcherData: string
147
+ }
148
+
149
+
150
+ interface ILessThanOrEqualToSemverMatcher extends ISplitMatcherBase {
151
+ matcherType: 'LESS_THAN_OR_EQUAL_TO_SEMVER',
152
+ stringMatcherData: string
153
+ }
154
+
155
+ interface IBetweenSemverMatcher extends ISplitMatcherBase {
156
+ matcherType: 'BETWEEN_SEMVER'
157
+ betweenStringMatcherData: IBetweenStringMatcherData
158
+ }
159
+
160
+ interface IInListSemverMatcher extends ISplitMatcherBase {
161
+ matcherType: 'IN_LIST_SEMVER',
162
+ whitelistMatcherData: IWhitelistMatcherData
163
+ }
164
+
133
165
  export type ISplitMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher |
134
166
  ILessThanOrEqualToMatcher | IBetweenMatcher | IEqualToSetMatcher | IContainsAnyOfSetMatcher | IContainsAllOfSetMatcher | IPartOfSetMatcher |
135
- IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher
167
+ IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher |
168
+ IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher
136
169
 
137
170
  /** Split object */
138
171
  export interface ISplitPartition {
@@ -2,7 +2,7 @@ import { get } from '../utils/lang';
2
2
  import { parser } from './parser';
3
3
  import { keyParser } from '../utils/key';
4
4
  import { thenable } from '../utils/promise/thenable';
5
- import * as LabelsConstants from '../utils/labels';
5
+ import { EXCEPTION, NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED } from '../utils/labels';
6
6
  import { CONTROL } from '../utils/constants';
7
7
  import { ISplit, MaybeThenable } from '../dtos/types';
8
8
  import { SplitIO } from '../types';
@@ -13,7 +13,7 @@ import { ILogger } from '../logger/types';
13
13
  function evaluationResult(result: IEvaluation | undefined, defaultTreatment: string): IEvaluationResult {
14
14
  return {
15
15
  treatment: get(result, 'treatment', defaultTreatment),
16
- label: get(result, 'label', LabelsConstants.NO_CONDITION_MATCH)
16
+ label: get(result, 'label', NO_CONDITION_MATCH)
17
17
  };
18
18
  }
19
19
 
@@ -55,16 +55,16 @@ export class Engine {
55
55
  } catch (err) {
56
56
  return {
57
57
  treatment: CONTROL,
58
- label: LabelsConstants.EXCEPTION
58
+ label: EXCEPTION
59
59
  };
60
60
  }
61
61
 
62
62
  if (this.isGarbage()) {
63
63
  treatment = CONTROL;
64
- label = LabelsConstants.SPLIT_ARCHIVED;
64
+ label = SPLIT_ARCHIVED;
65
65
  } else if (killed) {
66
66
  treatment = defaultTreatment;
67
- label = LabelsConstants.SPLIT_KILLED;
67
+ label = SPLIT_KILLED;
68
68
  } else {
69
69
  const evaluation = this.evaluator(
70
70
  parsedKey,
@@ -98,4 +98,3 @@ export class Engine {
98
98
  return this.baseInfo.changeNumber;
99
99
  }
100
100
  }
101
-
@@ -1,7 +1,7 @@
1
1
  import { findIndex } from '../../utils/lang';
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { thenable } from '../../utils/promise/thenable';
4
- import * as LabelsConstants from '../../utils/labels';
4
+ import { UNSUPPORTED_MATCHER_TYPE } from '../../utils/labels';
5
5
  import { CONTROL } from '../../utils/constants';
6
6
  import { SplitIO } from '../../types';
7
7
  import { IEvaluation, IEvaluator, ISplitEvaluator } from '../types';
@@ -14,7 +14,7 @@ export function ifElseIfCombinerContext(log: ILogger, predicates: IEvaluator[]):
14
14
 
15
15
  return {
16
16
  treatment: CONTROL,
17
- label: LabelsConstants.UNSUPPORTED_MATCHER_TYPE
17
+ label: UNSUPPORTED_MATCHER_TYPE
18
18
  };
19
19
  }
20
20
 
@@ -1,6 +1,6 @@
1
1
  import { getTreatment, shouldApplyRollout } from './engineUtils';
2
2
  import { thenable } from '../../utils/promise/thenable';
3
- import * as LabelsConstants from '../../utils/labels';
3
+ import { NOT_IN_SPLIT } from '../../utils/labels';
4
4
  import { MaybeThenable } from '../../dtos/types';
5
5
  import { IEvaluation, IEvaluator, ISplitEvaluator } from '../types';
6
6
  import { SplitIO } from '../../types';
@@ -30,7 +30,7 @@ export function conditionContext(log: ILogger, matcherEvaluator: (...args: any)
30
30
  if (conditionType === 'ROLLOUT' && !shouldApplyRollout(trafficAllocation as number, (key as SplitIO.SplitKeyObject).bucketingKey as string, trafficAllocationSeed as number)) {
31
31
  return {
32
32
  treatment: undefined, // treatment value is assigned later
33
- label: LabelsConstants.NOT_IN_SPLIT
33
+ label: NOT_IN_SPLIT
34
34
  };
35
35
  }
36
36
 
@@ -1,6 +1,6 @@
1
1
  import { Engine } from './Engine';
2
2
  import { thenable } from '../utils/promise/thenable';
3
- import * as LabelsConstants from '../utils/labels';
3
+ import { EXCEPTION, SPLIT_NOT_FOUND } from '../utils/labels';
4
4
  import { CONTROL } from '../utils/constants';
5
5
  import { ISplit, MaybeThenable } from '../dtos/types';
6
6
  import { IStorageAsync, IStorageSync } from '../storages/types';
@@ -12,7 +12,7 @@ import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
12
12
 
13
13
  const treatmentException = {
14
14
  treatment: CONTROL,
15
- label: LabelsConstants.EXCEPTION,
15
+ label: EXCEPTION,
16
16
  config: null
17
17
  };
18
18
 
@@ -143,7 +143,7 @@ function getEvaluation(
143
143
  ): MaybeThenable<IEvaluationResult> {
144
144
  let evaluation: MaybeThenable<IEvaluationResult> = {
145
145
  treatment: CONTROL,
146
- label: LabelsConstants.SPLIT_NOT_FOUND,
146
+ label: SPLIT_NOT_FOUND,
147
147
  config: null
148
148
  };
149
149
 
@@ -151,7 +151,7 @@ function getEvaluation(
151
151
  const split = Engine.parse(log, splitJSON, storage);
152
152
  evaluation = split.getTreatment(key, attributes, evaluateFeature);
153
153
 
154
- // If the storage is async and the evaluated split uses segment, evaluation is thenable
154
+ // If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
155
155
  if (thenable(evaluation)) {
156
156
  return evaluation.then(result => {
157
157
  result.changeNumber = split.getChangeNumber();
@@ -1,10 +1,6 @@
1
- import { ENGINE_MATCHER_ALL } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
1
+ export function allMatcherContext() {
3
2
 
4
- export function allMatcherContext(log: ILogger) {
5
3
  return function allMatcher(runtimeAttr: string): boolean {
6
- log.debug(ENGINE_MATCHER_ALL);
7
-
8
4
  return runtimeAttr != null;
9
5
  };
10
6
  }
@@ -1,13 +1,9 @@
1
1
  import { IBetweenMatcherData } from '../../dtos/types';
2
- import { ENGINE_MATCHER_BETWEEN } from '../../logger/constants';
3
- import { ILogger } from '../../logger/types';
4
2
 
5
- export function betweenMatcherContext(log: ILogger, ruleVO: IBetweenMatcherData) /*: Function */ {
6
- return function betweenMatcher(runtimeAttr: number): boolean {
7
-
8
- let isBetween = runtimeAttr >= ruleVO.start && runtimeAttr <= ruleVO.end;
3
+ export function betweenMatcherContext(ruleVO: IBetweenMatcherData) {
9
4
 
10
- log.debug(ENGINE_MATCHER_BETWEEN, [runtimeAttr, ruleVO.start, ruleVO.end, isBetween]);
5
+ return function betweenMatcher(runtimeAttr: number): boolean {
6
+ const isBetween = runtimeAttr >= ruleVO.start && runtimeAttr <= ruleVO.end;
11
7
 
12
8
  return isBetween;
13
9
  };
@@ -1,11 +1,7 @@
1
- import { ENGINE_MATCHER_BOOLEAN } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
1
+ export function booleanMatcherContext(ruleAttr: boolean) {
3
2
 
4
- export function booleanMatcherContext(log: ILogger, ruleAttr: boolean) /*: Function */ {
5
3
  return function booleanMatcher(runtimeAttr: boolean): boolean {
6
- let booleanMatches = ruleAttr === runtimeAttr;
7
-
8
- log.debug(ENGINE_MATCHER_BOOLEAN, [ruleAttr, runtimeAttr]);
4
+ const booleanMatches = ruleAttr === runtimeAttr;
9
5
 
10
6
  return booleanMatches;
11
7
  };
@@ -1,8 +1,6 @@
1
- import { ENGINE_MATCHER_CONTAINS_ALL } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
3
1
  import { findIndex } from '../../utils/lang';
4
2
 
5
- export function containsAllSetMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function containsAllSetMatcherContext(ruleAttr: string[]) {
6
4
  return function containsAllMatcher(runtimeAttr: string[]): boolean {
7
5
  let containsAll = true;
8
6
 
@@ -15,8 +13,6 @@ export function containsAllSetMatcherContext(log: ILogger, ruleAttr: string[]) /
15
13
  }
16
14
  }
17
15
 
18
- log.debug(ENGINE_MATCHER_CONTAINS_ALL, [runtimeAttr, ruleAttr, containsAll]);
19
-
20
16
  return containsAll;
21
17
  };
22
18
  }
@@ -1,8 +1,6 @@
1
- import { ENGINE_MATCHER_CONTAINS_ANY } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
3
1
  import { findIndex } from '../../utils/lang';
4
2
 
5
- export function containsAnySetMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function containsAnySetMatcherContext(ruleAttr: string[]) {
6
4
  return function containsAnyMatcher(runtimeAttr: string[]): boolean {
7
5
  let containsAny = false;
8
6
 
@@ -10,8 +8,6 @@ export function containsAnySetMatcherContext(log: ILogger, ruleAttr: string[]) /
10
8
  if (findIndex(runtimeAttr, e => e === ruleAttr[i]) >= 0) containsAny = true;
11
9
  }
12
10
 
13
- log.debug(ENGINE_MATCHER_CONTAINS_ANY, [runtimeAttr, ruleAttr, containsAny]);
14
-
15
11
  return containsAny;
16
12
  };
17
13
  }
@@ -1,12 +1,8 @@
1
1
  import { isString } from '../../utils/lang';
2
- import { ILogger } from '../../logger/types';
3
- import { ENGINE_MATCHER_CONTAINS_STRING } from '../../logger/constants';
4
2
 
5
- export function containsStringMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function containsStringMatcherContext(ruleAttr: string[]) {
6
4
  return function containsStringMatcher(runtimeAttr: string): boolean {
7
- let contains = ruleAttr.some(e => isString(runtimeAttr) && runtimeAttr.indexOf(e) > -1);
8
-
9
- log.debug(ENGINE_MATCHER_CONTAINS_STRING, [runtimeAttr, ruleAttr, contains]);
5
+ const contains = ruleAttr.some(e => isString(runtimeAttr) && runtimeAttr.indexOf(e) > -1);
10
6
 
11
7
  return contains;
12
8
  };
@@ -5,7 +5,7 @@ import { thenable } from '../../utils/promise/thenable';
5
5
  import { IDependencyMatcherValue, IEvaluation, ISplitEvaluator } from '../types';
6
6
  import { ENGINE_MATCHER_DEPENDENCY, ENGINE_MATCHER_DEPENDENCY_PRE } from '../../logger/constants';
7
7
 
8
- export function dependencyMatcherContext(log: ILogger, { split, treatments }: IDependencyMatcherData, storage: IStorageSync | IStorageAsync) {
8
+ export function dependencyMatcherContext({ split, treatments }: IDependencyMatcherData, storage: IStorageSync | IStorageAsync, log: ILogger) {
9
9
 
10
10
  function checkTreatment(evaluation: IEvaluation, acceptableTreatments: string[], parentName: string) {
11
11
  let matches = false;
@@ -1,11 +1,7 @@
1
- import { ENGINE_MATCHER_EQUAL } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
1
+ export function equalToMatcherContext(ruleAttr: number) {
3
2
 
4
- export function equalToMatcherContext(log: ILogger, ruleAttr: number) /*: Function */ {
5
3
  return function equalToMatcher(runtimeAttr: number): boolean {
6
- let isEqual = runtimeAttr === ruleAttr;
7
-
8
- log.debug(ENGINE_MATCHER_EQUAL, [runtimeAttr, ruleAttr, isEqual]);
4
+ const isEqual = runtimeAttr === ruleAttr;
9
5
 
10
6
  return isEqual;
11
7
  };
@@ -1,8 +1,6 @@
1
- import { ENGINE_MATCHER_EQUAL_TO_SET } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
3
1
  import { findIndex } from '../../utils/lang';
4
2
 
5
- export function equalToSetMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function equalToSetMatcherContext(ruleAttr: string[]) {
6
4
  return function equalToSetMatcher(runtimeAttr: string[]): boolean {
7
5
  // Length being the same is the first condition.
8
6
  let isEqual = runtimeAttr.length === ruleAttr.length;
@@ -12,8 +10,6 @@ export function equalToSetMatcherContext(log: ILogger, ruleAttr: string[]) /*: F
12
10
  if (findIndex(ruleAttr, e => e === runtimeAttr[i]) < 0) isEqual = false;
13
11
  }
14
12
 
15
- log.debug(ENGINE_MATCHER_EQUAL_TO_SET, [runtimeAttr, ruleAttr, isEqual]);
16
-
17
13
  return isEqual;
18
14
  };
19
15
  }
@@ -1,12 +1,8 @@
1
- import { ENGINE_MATCHER_ENDS_WITH } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
3
1
  import { endsWith } from '../../utils/lang';
4
2
 
5
- export function endsWithMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function endsWithMatcherContext(ruleAttr: string[]) {
6
4
  return function endsWithMatcher(runtimeAttr: string): boolean {
7
- let strEndsWith = ruleAttr.some(e => endsWith(runtimeAttr, e));
8
-
9
- log.debug(ENGINE_MATCHER_ENDS_WITH, [runtimeAttr, ruleAttr, strEndsWith]);
5
+ const strEndsWith = ruleAttr.some(e => endsWith(runtimeAttr, e));
10
6
 
11
7
  return strEndsWith;
12
8
  };
@@ -1,12 +1,8 @@
1
- import { ENGINE_MATCHER_GREATER } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
1
+ export function greaterThanEqualMatcherContext(ruleAttr: number) {
3
2
 
4
- export function greaterThanEqualMatcherContext(log: ILogger, ruleAttr: number) /*: Function */ {
5
3
  return function greaterThanEqualMatcher(runtimeAttr: number): boolean {
6
- let isGreaterEqualThan = runtimeAttr >= ruleAttr;
4
+ const isGreaterThanEqual = runtimeAttr >= ruleAttr;
7
5
 
8
- log.debug(ENGINE_MATCHER_GREATER, [runtimeAttr, ruleAttr, isGreaterEqualThan]);
9
-
10
- return isGreaterEqualThan;
6
+ return isGreaterThanEqual;
11
7
  };
12
8
  }
@@ -15,29 +15,39 @@ import { containsStringMatcherContext } from './cont_str';
15
15
  import { dependencyMatcherContext } from './dependency';
16
16
  import { booleanMatcherContext } from './boolean';
17
17
  import { stringMatcherContext } from './string';
18
+ import { equalToSemverMatcherContext } from './semver_eq';
19
+ import { greaterThanEqualToSemverMatcherContext } from './semver_gte';
20
+ import { lessThanEqualToSemverMatcherContext } from './semver_lte';
21
+ import { betweenSemverMatcherContext } from './semver_between';
22
+ import { inListSemverMatcherContext } from './semver_inlist';
18
23
  import { IStorageAsync, IStorageSync } from '../../storages/types';
19
24
  import { IMatcher, IMatcherDto } from '../types';
20
25
  import { ILogger } from '../../logger/types';
21
26
 
22
27
  const matchers = [
23
- undefined, // UNDEFINED: 0,
24
- allMatcherContext, // ALL_KEYS: 1,
25
- segmentMatcherContext, // IN_SEGMENT: 2,
26
- whitelistMatcherContext, // WHITELIST: 3,
27
- equalToMatcherContext, // EQUAL_TO: 4,
28
- greaterThanEqualMatcherContext, // GREATER_THAN_OR_EQUAL_TO: 5,
29
- lessThanEqualMatcherContext, // LESS_THAN_OR_EQUAL_TO: 6,
30
- betweenMatcherContext, // BETWEEN: 7,
31
- equalToSetMatcherContext, // EQUAL_TO_SET: 8,
32
- containsAnySetMatcherContext, // CONTAINS_ANY_OF_SET: 9,
33
- containsAllSetMatcherContext, // CONTAINS_ALL_OF_SET: 10,
34
- partOfSetMatcherContext, // PART_OF_SET: 11,
35
- endsWithMatcherContext, // ENDS_WITH: 12,
36
- startsWithMatcherContext, // STARTS_WITH: 13,
37
- containsStringMatcherContext, // CONTAINS_STRING: 14,
38
- dependencyMatcherContext, // IN_SPLIT_TREATMENT: 15,
39
- booleanMatcherContext, // EQUAL_TO_BOOLEAN: 16,
40
- stringMatcherContext // MATCHES_STRING: 17
28
+ undefined, // UNDEFINED: 0
29
+ allMatcherContext, // ALL_KEYS: 1
30
+ segmentMatcherContext, // IN_SEGMENT: 2
31
+ whitelistMatcherContext, // WHITELIST: 3
32
+ equalToMatcherContext, // EQUAL_TO: 4
33
+ greaterThanEqualMatcherContext, // GREATER_THAN_OR_EQUAL_TO: 5
34
+ lessThanEqualMatcherContext, // LESS_THAN_OR_EQUAL_TO: 6
35
+ betweenMatcherContext, // BETWEEN: 7
36
+ equalToSetMatcherContext, // EQUAL_TO_SET: 8
37
+ containsAnySetMatcherContext, // CONTAINS_ANY_OF_SET: 9
38
+ containsAllSetMatcherContext, // CONTAINS_ALL_OF_SET: 10
39
+ partOfSetMatcherContext, // PART_OF_SET: 11
40
+ endsWithMatcherContext, // ENDS_WITH: 12
41
+ startsWithMatcherContext, // STARTS_WITH: 13
42
+ containsStringMatcherContext, // CONTAINS_STRING: 14
43
+ dependencyMatcherContext, // IN_SPLIT_TREATMENT: 15
44
+ booleanMatcherContext, // EQUAL_TO_BOOLEAN: 16
45
+ stringMatcherContext, // MATCHES_STRING: 17
46
+ equalToSemverMatcherContext, // EQUAL_TO_SEMVER: 18
47
+ greaterThanEqualToSemverMatcherContext, // GREATER_THAN_OR_EQUAL_TO_SEMVER: 19
48
+ lessThanEqualToSemverMatcherContext, // LESS_THAN_OR_EQUAL_TO_SEMVER: 20
49
+ betweenSemverMatcherContext, // BETWEEN_SEMVER: 21
50
+ inListSemverMatcherContext, // IN_LIST_SEMVER: 22
41
51
  ];
42
52
 
43
53
  /**
@@ -51,6 +61,6 @@ export function matcherFactory(log: ILogger, matcherDto: IMatcherDto, storage?:
51
61
 
52
62
  let matcherFn;
53
63
  // @ts-ignore
54
- if (matchers[type]) matcherFn = matchers[type](log, value, storage); // There is no index-out-of-bound exception in JavaScript
64
+ if (matchers[type]) matcherFn = matchers[type](value, storage, log); // There is no index-out-of-bound exception in JavaScript
55
65
  return matcherFn;
56
66
  }
@@ -1,12 +1,8 @@
1
- import { ENGINE_MATCHER_LESS } from '../../logger/constants';
2
- import { ILogger } from '../../logger/types';
1
+ export function lessThanEqualMatcherContext(ruleAttr: number) {
3
2
 
4
- export function lessThanEqualMatcherContext(log: ILogger, ruleAttr: number) /*: function */ {
5
3
  return function lessThanEqualMatcher(runtimeAttr: number): boolean {
6
- let isLessEqualThan = runtimeAttr <= ruleAttr;
4
+ const isLessThanEqual = runtimeAttr <= ruleAttr;
7
5
 
8
- log.debug(ENGINE_MATCHER_LESS, [runtimeAttr, ruleAttr, isLessEqualThan]);
9
-
10
- return isLessEqualThan;
6
+ return isLessThanEqual;
11
7
  };
12
8
  }
@@ -16,7 +16,12 @@ export const matcherTypes: Record<string, number> = {
16
16
  CONTAINS_STRING: 14,
17
17
  IN_SPLIT_TREATMENT: 15,
18
18
  EQUAL_TO_BOOLEAN: 16,
19
- MATCHES_STRING: 17
19
+ MATCHES_STRING: 17,
20
+ EQUAL_TO_SEMVER: 18,
21
+ GREATER_THAN_OR_EQUAL_TO_SEMVER: 19,
22
+ LESS_THAN_OR_EQUAL_TO_SEMVER: 20,
23
+ BETWEEN_SEMVER: 21,
24
+ IN_LIST_SEMVER: 22,
20
25
  };
21
26
 
22
27
  export const matcherDataTypes = {
@@ -1,8 +1,6 @@
1
1
  import { findIndex } from '../../utils/lang';
2
- import { ILogger } from '../../logger/types';
3
- import { ENGINE_MATCHER_PART_OF } from '../../logger/constants';
4
2
 
5
- export function partOfSetMatcherContext(log: ILogger, ruleAttr: string[]) /*: Function */ {
3
+ export function partOfSetMatcherContext(ruleAttr: string[]) {
6
4
  return function partOfMatcher(runtimeAttr: string[]): boolean {
7
5
  // To be part of the length should be minor or equal.
8
6
  let isPartOf = runtimeAttr.length <= ruleAttr.length;
@@ -12,8 +10,6 @@ export function partOfSetMatcherContext(log: ILogger, ruleAttr: string[]) /*: Fu
12
10
  if (findIndex(ruleAttr, e => e === runtimeAttr[i]) < 0) isPartOf = false;
13
11
  }
14
12
 
15
- log.debug(ENGINE_MATCHER_PART_OF, [runtimeAttr, ruleAttr, isPartOf]);
16
-
17
13
  return isPartOf;
18
14
  };
19
15
  }
@@ -1,25 +1,18 @@
1
1
  import { MaybeThenable } from '../../dtos/types';
2
2
  import { ISegmentsCacheBase } from '../../storages/types';
3
- import { ILogger } from '../../logger/types';
4
3
  import { thenable } from '../../utils/promise/thenable';
5
- import { ENGINE_MATCHER_SEGMENT } from '../../logger/constants';
6
4
 
7
- export function segmentMatcherContext(log: ILogger, segmentName: string, storage: { segments: ISegmentsCacheBase }) {
5
+ export function segmentMatcherContext(segmentName: string, storage: { segments: ISegmentsCacheBase }) {
8
6
 
9
7
  return function segmentMatcher(key: string): MaybeThenable<boolean> {
10
8
  const isInSegment = storage.segments.isInSegment(segmentName, key);
11
9
 
12
10
  if (thenable(isInSegment)) {
13
11
  isInSegment.then(result => {
14
- log.debug(ENGINE_MATCHER_SEGMENT, [segmentName, key, isInSegment]);
15
-
16
12
  return result;
17
13
  });
18
- } else {
19
- log.debug(ENGINE_MATCHER_SEGMENT, [segmentName, key, isInSegment]);
20
14
  }
21
15
 
22
16
  return isInSegment;
23
17
  };
24
-
25
18
  }
@@ -0,0 +1,15 @@
1
+ import { IBetweenStringMatcherData } from '../../dtos/types';
2
+ import { Semver } from '../../utils/Semver';
3
+
4
+ export function betweenSemverMatcherContext(ruleAttr: IBetweenStringMatcherData) {
5
+ const startSemver = new Semver(ruleAttr.start);
6
+ const endSemver = new Semver(ruleAttr.end);
7
+
8
+ return function betweenSemverMatcher(runtimeAttr: string): boolean {
9
+ const runtimeSemver = new Semver(runtimeAttr);
10
+
11
+ const isBetween = startSemver.compare(runtimeSemver) <= 0 && endSemver.compare(runtimeSemver) >= 0;
12
+
13
+ return isBetween;
14
+ };
15
+ }