@splitsoftware/splitio-commons 2.12.0 → 3.0.0-rc.1

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 (395) hide show
  1. package/CHANGES.txt +19 -1
  2. package/cjs/evaluator/condition/engineUtils.js +2 -2
  3. package/cjs/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +70 -0
  4. package/cjs/evaluator/fallbackConfigsCalculator/index.js +25 -0
  5. package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  6. package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +21 -32
  7. package/cjs/evaluator/index.js +73 -48
  8. package/cjs/evaluator/matchers/whitelist.js +1 -1
  9. package/cjs/integrations/pluggable.js +1 -1
  10. package/cjs/listeners/browser.js +4 -3
  11. package/cjs/listeners/node.js +4 -4
  12. package/cjs/logger/constants.js +15 -21
  13. package/cjs/logger/index.js +1 -1
  14. package/cjs/logger/messages/debug.js +6 -7
  15. package/cjs/logger/messages/error.js +4 -4
  16. package/cjs/logger/messages/info.js +2 -4
  17. package/cjs/logger/messages/warn.js +9 -10
  18. package/cjs/platform/browser.js +15 -0
  19. package/cjs/platform/getEventSource/browser.js +8 -0
  20. package/cjs/platform/getEventSource/eventsource.js +480 -0
  21. package/cjs/platform/getEventSource/node.js +26 -0
  22. package/cjs/platform/getFetch/browser.js +9 -0
  23. package/cjs/platform/getFetch/node.js +27 -0
  24. package/cjs/platform/getOptions/node.js +25 -0
  25. package/cjs/platform/node.js +17 -0
  26. package/cjs/readiness/constants.js +5 -4
  27. package/cjs/readiness/readinessManager.js +22 -22
  28. package/cjs/readiness/sdkReadinessManager.js +0 -16
  29. package/cjs/sdkClient/client.js +9 -35
  30. package/cjs/sdkClient/clientAttributesDecoration.js +3 -3
  31. package/cjs/sdkClient/clientInputValidation.js +38 -81
  32. package/cjs/sdkClient/identity.js +1 -1
  33. package/cjs/sdkClient/sdkClient.js +4 -49
  34. package/cjs/sdkClient/sdkLifecycle.js +71 -0
  35. package/cjs/sdkClient/trackMethod.js +56 -0
  36. package/cjs/sdkFactory/index.js +13 -50
  37. package/cjs/sdkManager/index.js +5 -5
  38. package/cjs/services/authProvider.js +67 -0
  39. package/cjs/services/secureSplitHttpClient.js +39 -0
  40. package/cjs/services/splitApi.js +24 -14
  41. package/cjs/services/splitHttpClient.js +1 -1
  42. package/cjs/storages/AbstractDefinitionsCacheAsync.js +51 -0
  43. package/cjs/storages/AbstractDefinitionsCacheSync.js +76 -0
  44. package/cjs/storages/KeyBuilder.js +16 -16
  45. package/cjs/storages/KeyBuilderCS.js +17 -17
  46. package/cjs/storages/KeyBuilderSS.js +16 -16
  47. package/cjs/storages/getRolloutPlan.js +4 -4
  48. package/cjs/storages/inLocalStorage/DefinitionsCacheInLocal.js +194 -0
  49. package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +1 -1
  50. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +10 -10
  51. package/cjs/storages/inLocalStorage/index.js +6 -6
  52. package/cjs/storages/inLocalStorage/validateCache.js +3 -3
  53. package/cjs/storages/inMemory/DefinitionsCacheInMemory.js +121 -0
  54. package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  55. package/cjs/storages/inMemory/InMemoryStorage.js +4 -4
  56. package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -5
  57. package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
  58. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +5 -5
  59. package/cjs/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  60. package/cjs/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  61. package/cjs/storages/inRedis/DefinitionsCacheInRedis.js +243 -0
  62. package/cjs/storages/inRedis/EventsCacheInRedis.js +1 -1
  63. package/cjs/storages/inRedis/ImpressionCountsCacheInRedis.js +5 -5
  64. package/cjs/storages/inRedis/ImpressionsCacheInRedis.js +1 -1
  65. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  66. package/cjs/storages/inRedis/RedisAdapter.js +8 -8
  67. package/cjs/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  68. package/cjs/storages/inRedis/UniqueKeysCacheInRedis.js +3 -3
  69. package/cjs/storages/inRedis/index.js +2 -2
  70. package/cjs/storages/pluggable/DefinitionsCachePluggable.js +212 -0
  71. package/cjs/storages/pluggable/EventsCachePluggable.js +1 -1
  72. package/cjs/storages/pluggable/ImpressionCountsCachePluggable.js +6 -6
  73. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  74. package/cjs/storages/pluggable/TelemetryCachePluggable.js +7 -7
  75. package/cjs/storages/pluggable/UniqueKeysCachePluggable.js +2 -2
  76. package/cjs/storages/pluggable/index.js +5 -5
  77. package/cjs/storages/pluggable/wrapperAdapter.js +1 -1
  78. package/cjs/storages/setRolloutPlan.js +6 -6
  79. package/cjs/storages/utils.js +6 -6
  80. package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
  81. package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +5 -5
  82. package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
  83. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +24 -15
  84. package/cjs/sync/polling/pollingManagerCS.js +18 -18
  85. package/cjs/sync/polling/pollingManagerSS.js +13 -13
  86. package/cjs/sync/polling/syncTasks/definitionsSyncTask.js +12 -0
  87. package/cjs/sync/polling/updaters/{splitChangesUpdater.js → definitionChangesUpdater.js} +72 -64
  88. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  89. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +6 -6
  90. package/cjs/sync/streaming/SSEClient/index.js +2 -2
  91. package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +1 -1
  92. package/cjs/sync/streaming/SSEHandler/index.js +1 -1
  93. package/cjs/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +18 -18
  94. package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  95. package/cjs/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  96. package/cjs/sync/streaming/constants.js +3 -3
  97. package/cjs/sync/streaming/parseUtils.js +12 -12
  98. package/cjs/sync/streaming/pushManager.js +14 -14
  99. package/cjs/sync/submitters/impressionsSubmitter.js +6 -6
  100. package/cjs/sync/submitters/submitter.js +1 -1
  101. package/cjs/sync/submitters/telemetrySubmitter.js +1 -2
  102. package/cjs/sync/syncManagerOnline.js +9 -6
  103. package/cjs/trackers/eventTracker.js +10 -12
  104. package/cjs/trackers/impressionObserver/buildKey.js +1 -1
  105. package/cjs/trackers/impressionsTracker.js +37 -20
  106. package/cjs/trackers/uniqueKeysTracker.js +1 -1
  107. package/cjs/utils/Backoff.js +20 -0
  108. package/cjs/utils/EventEmitter.js +391 -0
  109. package/cjs/utils/filter/bloomFilter.js +37 -0
  110. package/cjs/utils/inputValidation/apiKey.js +1 -1
  111. package/cjs/utils/inputValidation/attribute.js +2 -2
  112. package/cjs/utils/inputValidation/{split.js → definition.js} +10 -10
  113. package/cjs/utils/inputValidation/{splitExistence.js → definitionExistence.js} +6 -6
  114. package/cjs/utils/inputValidation/definitions.js +25 -0
  115. package/cjs/utils/inputValidation/eventProperties.js +1 -1
  116. package/cjs/utils/inputValidation/index.js +7 -7
  117. package/cjs/utils/inputValidation/isOperational.js +4 -4
  118. package/cjs/utils/inputValidation/target.js +22 -0
  119. package/cjs/utils/labels/index.js +3 -3
  120. package/cjs/utils/lang/index.js +1 -1
  121. package/cjs/utils/lang/sets.js +4 -4
  122. package/cjs/utils/promise/timeout.js +1 -1
  123. package/cjs/utils/settingsValidation/splitFilters.js +4 -4
  124. package/cjs/utils/settingsValidation/url.js +6 -6
  125. package/esm/evaluator/condition/engineUtils.js +2 -2
  126. package/esm/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.js +64 -0
  127. package/esm/evaluator/fallbackConfigsCalculator/index.js +21 -0
  128. package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +5 -8
  129. package/esm/evaluator/fallbackTreatmentsCalculator/index.js +21 -33
  130. package/esm/evaluator/index.js +72 -48
  131. package/esm/evaluator/matchers/whitelist.js +1 -1
  132. package/esm/integrations/pluggable.js +1 -1
  133. package/esm/listeners/browser.js +4 -3
  134. package/esm/listeners/node.js +4 -4
  135. package/esm/logger/constants.js +12 -18
  136. package/esm/logger/index.js +1 -1
  137. package/esm/logger/messages/debug.js +5 -6
  138. package/esm/logger/messages/error.js +3 -3
  139. package/esm/logger/messages/info.js +1 -3
  140. package/esm/logger/messages/warn.js +8 -9
  141. package/esm/platform/browser.js +12 -0
  142. package/esm/platform/getEventSource/browser.js +4 -0
  143. package/esm/platform/getEventSource/eventsource.js +480 -0
  144. package/esm/platform/getEventSource/node.js +20 -0
  145. package/esm/platform/getFetch/browser.js +5 -0
  146. package/esm/platform/getFetch/node.js +22 -0
  147. package/esm/platform/getOptions/node.js +20 -0
  148. package/esm/platform/node.js +14 -0
  149. package/esm/readiness/constants.js +4 -3
  150. package/esm/readiness/readinessManager.js +23 -23
  151. package/esm/readiness/sdkReadinessManager.js +1 -17
  152. package/esm/sdkClient/client.js +10 -37
  153. package/esm/sdkClient/clientAttributesDecoration.js +3 -3
  154. package/esm/sdkClient/clientInputValidation.js +40 -83
  155. package/esm/sdkClient/identity.js +1 -1
  156. package/esm/sdkClient/sdkClient.js +4 -49
  157. package/esm/sdkClient/sdkLifecycle.js +67 -0
  158. package/esm/sdkClient/trackMethod.js +52 -0
  159. package/esm/sdkFactory/index.js +14 -51
  160. package/esm/sdkManager/index.js +6 -6
  161. package/esm/services/authProvider.js +63 -0
  162. package/esm/services/secureSplitHttpClient.js +35 -0
  163. package/esm/services/splitApi.js +24 -14
  164. package/esm/services/splitHttpClient.js +1 -1
  165. package/esm/storages/AbstractDefinitionsCacheAsync.js +48 -0
  166. package/esm/storages/AbstractDefinitionsCacheSync.js +71 -0
  167. package/esm/storages/KeyBuilder.js +16 -16
  168. package/esm/storages/KeyBuilderCS.js +16 -16
  169. package/esm/storages/KeyBuilderSS.js +15 -15
  170. package/esm/storages/getRolloutPlan.js +4 -4
  171. package/esm/storages/inLocalStorage/DefinitionsCacheInLocal.js +191 -0
  172. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +7 -7
  173. package/esm/storages/inLocalStorage/index.js +6 -6
  174. package/esm/storages/inLocalStorage/validateCache.js +3 -3
  175. package/esm/storages/inMemory/DefinitionsCacheInMemory.js +118 -0
  176. package/esm/storages/inMemory/ImpressionCountsCacheInMemory.js +1 -1
  177. package/esm/storages/inMemory/InMemoryStorage.js +4 -4
  178. package/esm/storages/inMemory/InMemoryStorageCS.js +5 -5
  179. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +2 -2
  180. package/esm/storages/inMemory/SegmentsCacheInMemory.js +1 -1
  181. package/esm/storages/inMemory/TelemetryCacheInMemory.js +5 -5
  182. package/esm/storages/inRedis/DefinitionsCacheInRedis.js +240 -0
  183. package/esm/storages/inRedis/EventsCacheInRedis.js +1 -1
  184. package/esm/storages/inRedis/ImpressionCountsCacheInRedis.js +4 -4
  185. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +1 -1
  186. package/esm/storages/inRedis/RedisAdapter.js +7 -7
  187. package/esm/storages/inRedis/TelemetryCacheInRedis.js +7 -7
  188. package/esm/storages/inRedis/UniqueKeysCacheInRedis.js +1 -1
  189. package/esm/storages/inRedis/index.js +2 -2
  190. package/esm/storages/pluggable/DefinitionsCachePluggable.js +209 -0
  191. package/esm/storages/pluggable/EventsCachePluggable.js +1 -1
  192. package/esm/storages/pluggable/ImpressionCountsCachePluggable.js +5 -5
  193. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +1 -1
  194. package/esm/storages/pluggable/TelemetryCachePluggable.js +7 -7
  195. package/esm/storages/pluggable/UniqueKeysCachePluggable.js +1 -1
  196. package/esm/storages/pluggable/index.js +4 -4
  197. package/esm/storages/pluggable/wrapperAdapter.js +1 -1
  198. package/esm/storages/setRolloutPlan.js +6 -6
  199. package/esm/storages/utils.js +6 -6
  200. package/esm/sync/offline/splitsParser/parseCondition.js +1 -1
  201. package/esm/sync/offline/syncTasks/fromObjectSyncTask.js +6 -6
  202. package/esm/sync/polling/fetchers/splitChangesFetcher.js +25 -16
  203. package/esm/sync/polling/pollingManagerCS.js +15 -15
  204. package/esm/sync/polling/pollingManagerSS.js +13 -13
  205. package/esm/sync/polling/syncTasks/definitionsSyncTask.js +8 -0
  206. package/esm/sync/polling/updaters/definitionChangesUpdater.js +200 -0
  207. package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -3
  208. package/esm/sync/polling/updaters/segmentChangesUpdater.js +7 -7
  209. package/esm/sync/streaming/SSEClient/index.js +2 -2
  210. package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +2 -2
  211. package/esm/sync/streaming/SSEHandler/index.js +2 -2
  212. package/esm/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.js → DefinitionsUpdateWorker.js} +17 -17
  213. package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +2 -2
  214. package/esm/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.js +2 -2
  215. package/esm/sync/streaming/constants.js +2 -2
  216. package/esm/sync/streaming/parseUtils.js +10 -10
  217. package/esm/sync/streaming/pushManager.js +16 -16
  218. package/esm/sync/submitters/impressionsSubmitter.js +6 -6
  219. package/esm/sync/submitters/submitter.js +1 -1
  220. package/esm/sync/submitters/telemetrySubmitter.js +1 -2
  221. package/esm/sync/syncManagerOnline.js +8 -5
  222. package/esm/trackers/eventTracker.js +10 -12
  223. package/esm/trackers/impressionObserver/buildKey.js +1 -1
  224. package/esm/trackers/impressionsTracker.js +38 -21
  225. package/esm/trackers/uniqueKeysTracker.js +1 -1
  226. package/esm/utils/Backoff.js +20 -0
  227. package/esm/utils/EventEmitter.js +387 -0
  228. package/esm/utils/filter/bloomFilter.js +33 -0
  229. package/esm/utils/inputValidation/apiKey.js +1 -1
  230. package/esm/utils/inputValidation/attribute.js +2 -2
  231. package/esm/utils/inputValidation/{split.js → definition.js} +8 -8
  232. package/esm/utils/inputValidation/definitionExistence.js +15 -0
  233. package/esm/utils/inputValidation/definitions.js +21 -0
  234. package/esm/utils/inputValidation/index.js +3 -3
  235. package/esm/utils/inputValidation/isOperational.js +4 -4
  236. package/esm/utils/inputValidation/target.js +18 -0
  237. package/esm/utils/labels/index.js +2 -2
  238. package/esm/utils/lang/sets.js +4 -4
  239. package/esm/utils/promise/timeout.js +1 -1
  240. package/esm/utils/settingsValidation/splitFilters.js +4 -4
  241. package/esm/utils/settingsValidation/url.js +6 -6
  242. package/package.json +15 -6
  243. package/src/dtos/types.ts +65 -70
  244. package/src/evaluator/Engine.ts +4 -4
  245. package/src/evaluator/combiners/and.ts +3 -3
  246. package/src/evaluator/combiners/ifelseif.ts +2 -2
  247. package/src/evaluator/condition/engineUtils.ts +2 -2
  248. package/src/evaluator/condition/index.ts +3 -3
  249. package/src/evaluator/fallbackConfigsCalculator/fallbackSanitizer/index.ts +76 -0
  250. package/src/evaluator/fallbackConfigsCalculator/index.ts +24 -0
  251. package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +5 -7
  252. package/src/evaluator/fallbackTreatmentsCalculator/index.ts +27 -41
  253. package/src/evaluator/index.ts +86 -51
  254. package/src/evaluator/matchers/dependency.ts +2 -2
  255. package/src/evaluator/matchers/matcherTypes.ts +2 -2
  256. package/src/evaluator/matchers/prerequisites.ts +4 -4
  257. package/src/evaluator/matchers/rbsegment.ts +2 -2
  258. package/src/evaluator/matchers/whitelist.ts +2 -2
  259. package/src/evaluator/matchersTransform/index.ts +2 -2
  260. package/src/evaluator/matchersTransform/whitelist.ts +2 -2
  261. package/src/evaluator/parser/index.ts +4 -4
  262. package/src/evaluator/treatments/index.ts +2 -2
  263. package/src/evaluator/types.ts +6 -6
  264. package/src/evaluator/value/index.ts +1 -1
  265. package/src/integrations/pluggable.ts +1 -1
  266. package/src/listeners/browser.ts +11 -8
  267. package/src/listeners/node.ts +2 -5
  268. package/src/logger/constants.ts +12 -18
  269. package/src/logger/messages/debug.ts +5 -6
  270. package/src/logger/messages/error.ts +3 -3
  271. package/src/logger/messages/info.ts +1 -3
  272. package/src/logger/messages/warn.ts +8 -9
  273. package/src/platform/browser.ts +14 -0
  274. package/src/platform/getEventSource/browser.ts +4 -0
  275. package/src/platform/getEventSource/eventsource.js +519 -0
  276. package/src/platform/getEventSource/node.ts +23 -0
  277. package/src/platform/getFetch/browser.ts +5 -0
  278. package/src/platform/getFetch/node.ts +27 -0
  279. package/src/platform/getOptions/node.ts +24 -0
  280. package/src/platform/node.ts +16 -0
  281. package/src/readiness/constants.ts +4 -3
  282. package/src/readiness/readinessManager.ts +22 -22
  283. package/src/readiness/sdkReadinessManager.ts +1 -16
  284. package/src/readiness/types.ts +10 -16
  285. package/src/sdkClient/client.ts +11 -41
  286. package/src/sdkClient/clientInputValidation.ts +44 -84
  287. package/src/sdkClient/sdkClient.ts +5 -54
  288. package/src/sdkClient/sdkLifecycle.ts +79 -0
  289. package/src/sdkClient/trackMethod.ts +59 -0
  290. package/src/sdkFactory/index.ts +15 -59
  291. package/src/sdkFactory/types.ts +19 -16
  292. package/src/sdkManager/index.ts +15 -15
  293. package/src/services/authProvider.ts +86 -0
  294. package/src/services/secureSplitHttpClient.ts +44 -0
  295. package/src/services/splitApi.ts +14 -2
  296. package/src/services/types.ts +7 -2
  297. package/src/storages/AbstractDefinitionsCacheAsync.ts +63 -0
  298. package/src/storages/AbstractDefinitionsCacheSync.ts +95 -0
  299. package/src/storages/KeyBuilder.ts +6 -6
  300. package/src/storages/KeyBuilderCS.ts +6 -6
  301. package/src/storages/KeyBuilderSS.ts +2 -2
  302. package/src/storages/getRolloutPlan.ts +3 -3
  303. package/src/storages/inLocalStorage/DefinitionsCacheInLocal.ts +234 -0
  304. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +8 -8
  305. package/src/storages/inLocalStorage/index.ts +6 -6
  306. package/src/storages/inLocalStorage/validateCache.ts +4 -4
  307. package/src/storages/inMemory/DefinitionsCacheInMemory.ts +130 -0
  308. package/src/storages/inMemory/InMemoryStorage.ts +4 -4
  309. package/src/storages/inMemory/InMemoryStorageCS.ts +5 -5
  310. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +3 -3
  311. package/src/storages/inMemory/SegmentsCacheInMemory.ts +1 -1
  312. package/src/storages/inMemory/TelemetryCacheInMemory.ts +5 -5
  313. package/src/storages/inRedis/{SplitsCacheInRedis.ts → DefinitionsCacheInRedis.ts} +69 -69
  314. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +2 -2
  315. package/src/storages/inRedis/index.ts +2 -2
  316. package/src/storages/pluggable/DefinitionsCachePluggable.ts +230 -0
  317. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +2 -2
  318. package/src/storages/pluggable/index.ts +2 -2
  319. package/src/storages/setRolloutPlan.ts +7 -7
  320. package/src/storages/types.ts +34 -29
  321. package/src/sync/offline/splitsParser/parseCondition.ts +2 -2
  322. package/src/sync/offline/splitsParser/splitsParserFromSettings.ts +3 -3
  323. package/src/sync/offline/splitsParser/types.ts +6 -3
  324. package/src/sync/offline/syncManagerOffline.ts +2 -2
  325. package/src/sync/offline/syncTasks/fromObjectSyncTask.ts +14 -14
  326. package/src/sync/polling/fetchers/splitChangesFetcher.ts +58 -23
  327. package/src/sync/polling/fetchers/types.ts +5 -3
  328. package/src/sync/polling/pollingManagerCS.ts +16 -14
  329. package/src/sync/polling/pollingManagerSS.ts +15 -13
  330. package/src/sync/polling/syncTasks/{splitsSyncTask.ts → definitionsSyncTask.ts} +11 -12
  331. package/src/sync/polling/types.ts +3 -3
  332. package/src/sync/polling/updaters/definitionChangesUpdater.ts +239 -0
  333. package/src/sync/polling/updaters/mySegmentsUpdater.ts +3 -3
  334. package/src/sync/polling/updaters/segmentChangesUpdater.ts +7 -7
  335. package/src/sync/streaming/AuthClient/index.ts +2 -2
  336. package/src/sync/streaming/AuthClient/types.ts +14 -11
  337. package/src/sync/streaming/SSEClient/index.ts +2 -2
  338. package/src/sync/streaming/SSEClient/types.ts +2 -2
  339. package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +2 -2
  340. package/src/sync/streaming/SSEHandler/index.ts +2 -2
  341. package/src/sync/streaming/UpdateWorkers/{SplitsUpdateWorker.ts → DefinitionsUpdateWorker.ts} +21 -21
  342. package/src/sync/streaming/constants.ts +2 -2
  343. package/src/sync/streaming/parseUtils.ts +12 -12
  344. package/src/sync/streaming/pushManager.ts +18 -18
  345. package/src/sync/streaming/types.ts +2 -2
  346. package/src/sync/submitters/impressionsSubmitter.ts +9 -9
  347. package/src/sync/submitters/telemetrySubmitter.ts +1 -2
  348. package/src/sync/submitters/types.ts +3 -0
  349. package/src/sync/syncManagerOnline.ts +9 -5
  350. package/src/trackers/eventTracker.ts +7 -10
  351. package/src/trackers/impressionsTracker.ts +42 -26
  352. package/src/trackers/types.ts +3 -1
  353. package/src/utils/Backoff.ts +21 -0
  354. package/src/utils/EventEmitter.js +444 -0
  355. package/src/utils/filter/bloomFilter.ts +38 -0
  356. package/src/utils/inputValidation/definition.ts +27 -0
  357. package/src/utils/inputValidation/definitionExistence.ts +19 -0
  358. package/src/utils/inputValidation/definitions.ts +21 -0
  359. package/src/utils/inputValidation/index.ts +3 -3
  360. package/src/utils/inputValidation/isOperational.ts +4 -4
  361. package/src/utils/inputValidation/target.ts +21 -0
  362. package/src/utils/inputValidation/trafficTypeExistence.ts +2 -2
  363. package/src/utils/jwt/types.ts +1 -1
  364. package/src/utils/labels/index.ts +2 -2
  365. package/src/utils/lang/sets.ts +4 -2
  366. package/src/utils/settingsValidation/splitFilters.ts +3 -3
  367. package/src/utils/settingsValidation/url.ts +1 -1
  368. package/types/splitio.d.ts +222 -11
  369. package/cjs/storages/AbstractSplitsCacheAsync.js +0 -51
  370. package/cjs/storages/AbstractSplitsCacheSync.js +0 -76
  371. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +0 -194
  372. package/cjs/storages/inMemory/SplitsCacheInMemory.js +0 -121
  373. package/cjs/storages/inRedis/SplitsCacheInRedis.js +0 -243
  374. package/cjs/storages/pluggable/SplitsCachePluggable.js +0 -212
  375. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +0 -13
  376. package/cjs/utils/inputValidation/splits.js +0 -25
  377. package/esm/storages/AbstractSplitsCacheAsync.js +0 -48
  378. package/esm/storages/AbstractSplitsCacheSync.js +0 -71
  379. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +0 -191
  380. package/esm/storages/inMemory/SplitsCacheInMemory.js +0 -118
  381. package/esm/storages/inRedis/SplitsCacheInRedis.js +0 -240
  382. package/esm/storages/pluggable/SplitsCachePluggable.js +0 -209
  383. package/esm/sync/polling/syncTasks/splitsSyncTask.js +0 -9
  384. package/esm/sync/polling/updaters/splitChangesUpdater.js +0 -192
  385. package/esm/utils/inputValidation/splitExistence.js +0 -15
  386. package/esm/utils/inputValidation/splits.js +0 -21
  387. package/src/storages/AbstractSplitsCacheAsync.ts +0 -63
  388. package/src/storages/AbstractSplitsCacheSync.ts +0 -95
  389. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +0 -234
  390. package/src/storages/inMemory/SplitsCacheInMemory.ts +0 -130
  391. package/src/storages/pluggable/SplitsCachePluggable.ts +0 -230
  392. package/src/sync/polling/updaters/splitChangesUpdater.ts +0 -230
  393. package/src/utils/inputValidation/split.ts +0 -27
  394. package/src/utils/inputValidation/splitExistence.ts +0 -19
  395. package/src/utils/inputValidation/splits.ts +0 -21
@@ -1,6 +1,6 @@
1
1
  var telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/;
2
2
  var eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
3
- var authEndpointMatcher = /^\/v2\/auth/;
3
+ var authEndpointMatcher = /^\/(v2|v3)\/auth/;
4
4
  var streamingEndpointMatcher = /^\/(sse|event-stream)/;
5
5
  /**
6
6
  * Get URL based on a given target (path).
@@ -12,16 +12,16 @@ var streamingEndpointMatcher = /^\/(sse|event-stream)/;
12
12
  */
13
13
  export function url(settings, target) {
14
14
  if (telemetryEndpointMatcher.test(target)) {
15
- return "" + settings.urls.telemetry + target;
15
+ return "".concat(settings.urls.telemetry).concat(target);
16
16
  }
17
17
  if (eventsEndpointMatcher.test(target)) {
18
- return "" + settings.urls.events + target;
18
+ return "".concat(settings.urls.events).concat(target);
19
19
  }
20
20
  if (authEndpointMatcher.test(target)) {
21
- return "" + settings.urls.auth + target;
21
+ return "".concat(settings.urls.auth).concat(target);
22
22
  }
23
23
  if (streamingEndpointMatcher.test(target)) {
24
- return "" + settings.urls.streaming + target;
24
+ return "".concat(settings.urls.streaming).concat(target);
25
25
  }
26
- return "" + settings.urls.sdk + target;
26
+ return "".concat(settings.urls.sdk).concat(target);
27
27
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "2.12.0",
3
+ "version": "3.0.0-rc.1",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -49,21 +49,30 @@
49
49
  "tslib": "^2.3.1"
50
50
  },
51
51
  "peerDependencies": {
52
- "ioredis": "^4.28.0 || ^5.0.0"
52
+ "bloom-filters": "^3.0.0",
53
+ "ioredis": "^4.28.0 || ^5.0.0",
54
+ "node-fetch": "^2.7.0"
53
55
  },
54
56
  "peerDependenciesMeta": {
57
+ "bloom-filters": {
58
+ "optional": true
59
+ },
55
60
  "ioredis": {
56
61
  "optional": true
62
+ },
63
+ "node-fetch": {
64
+ "optional": true
57
65
  }
58
66
  },
59
67
  "devDependencies": {
60
68
  "@types/ioredis": "^4.28.0",
61
69
  "@types/jest": "^27.0.0",
62
70
  "@types/lodash": "^4.14.162",
63
- "@typescript-eslint/eslint-plugin": "^6.6.0",
64
- "@typescript-eslint/parser": "^6.6.0",
71
+ "@typescript-eslint/eslint-plugin": "^7.18.0",
72
+ "@typescript-eslint/parser": "^7.18.0",
73
+ "bloom-filters": "^3.0.4",
65
74
  "cross-env": "^7.0.2",
66
- "eslint": "^8.48.0",
75
+ "eslint": "^8.56.0",
67
76
  "eslint-plugin-compat": "^6.0.1",
68
77
  "eslint-plugin-import": "^2.25.3",
69
78
  "eslint-plugin-tsdoc": "^0.3.0",
@@ -76,7 +85,7 @@
76
85
  "redis-server": "1.2.2",
77
86
  "rimraf": "^3.0.2",
78
87
  "ts-jest": "^27.0.5",
79
- "typescript": "4.4.4"
88
+ "typescript": "4.7.4"
80
89
  },
81
90
  "sideEffects": false
82
91
  }
package/src/dtos/types.ts CHANGED
@@ -2,8 +2,6 @@ import SplitIO from '../../types/splitio';
2
2
 
3
3
  export type MaybeThenable<T> = T | Promise<T>
4
4
 
5
- /** Split Matchers */
6
-
7
5
  export type IMatcherDataType = null | 'DATETIME' | 'NUMBER'
8
6
 
9
7
  export interface IUnaryNumericMatcherData {
@@ -23,7 +21,7 @@ export interface IBetweenStringMatcherData {
23
21
  }
24
22
 
25
23
  export interface IWhitelistMatcherData {
26
- whitelist: string[]
24
+ whitelist?: string[] | null
27
25
  }
28
26
 
29
27
  export interface IInSegmentMatcherData {
@@ -39,12 +37,12 @@ export interface IDependencyMatcherData {
39
37
  treatments: string[]
40
38
  }
41
39
 
42
- interface ISplitMatcherBase {
40
+ interface IDefinitionMatcherBase {
43
41
  matcherType: string
44
- negate: boolean
45
- keySelector: null | {
42
+ negate?: boolean
43
+ keySelector?: null | {
46
44
  trafficType: string,
47
- attribute: string | null
45
+ attribute?: string | null
48
46
  }
49
47
  userDefinedSegmentMatcherData?: null | IInSegmentMatcherData
50
48
  userDefinedLargeSegmentMatcherData?: null | IInLargeSegmentMatcherData
@@ -57,144 +55,143 @@ interface ISplitMatcherBase {
57
55
  betweenStringMatcherData?: null | IBetweenStringMatcherData
58
56
  }
59
57
 
60
- interface IAllKeysMatcher extends ISplitMatcherBase {
58
+ interface IAllKeysMatcher extends IDefinitionMatcherBase {
61
59
  matcherType: 'ALL_KEYS'
62
60
  }
63
61
 
64
- interface IInSegmentMatcher extends ISplitMatcherBase {
62
+ interface IInSegmentMatcher extends IDefinitionMatcherBase {
65
63
  matcherType: 'IN_SEGMENT',
66
64
  userDefinedSegmentMatcherData: IInSegmentMatcherData
67
65
  }
68
66
 
69
- interface IInRBSegmentMatcher extends ISplitMatcherBase {
67
+ interface IInRBSegmentMatcher extends IDefinitionMatcherBase {
70
68
  matcherType: 'IN_RULE_BASED_SEGMENT',
71
69
  userDefinedSegmentMatcherData: IInSegmentMatcherData
72
70
  }
73
71
 
74
- interface IInLargeSegmentMatcher extends ISplitMatcherBase {
72
+ interface IInLargeSegmentMatcher extends IDefinitionMatcherBase {
75
73
  matcherType: 'IN_LARGE_SEGMENT',
76
74
  userDefinedLargeSegmentMatcherData: IInLargeSegmentMatcherData
77
75
  }
78
76
 
79
- interface IWhitelistMatcher extends ISplitMatcherBase {
77
+ interface IWhitelistMatcher extends IDefinitionMatcherBase {
80
78
  matcherType: 'WHITELIST',
81
79
  whitelistMatcherData: IWhitelistMatcherData
82
80
  }
83
81
 
84
- interface IEqualToMatcher extends ISplitMatcherBase {
82
+ interface IEqualToMatcher extends IDefinitionMatcherBase {
85
83
  matcherType: 'EQUAL_TO',
86
84
  unaryNumericMatcherData: IUnaryNumericMatcherData
87
85
  }
88
86
 
89
- interface IGreaterThanOrEqualToMatcher extends ISplitMatcherBase {
87
+ interface IGreaterThanOrEqualToMatcher extends IDefinitionMatcherBase {
90
88
  matcherType: 'GREATER_THAN_OR_EQUAL_TO',
91
89
  unaryNumericMatcherData: IUnaryNumericMatcherData
92
90
  }
93
91
 
94
- interface ILessThanOrEqualToMatcher extends ISplitMatcherBase {
92
+ interface ILessThanOrEqualToMatcher extends IDefinitionMatcherBase {
95
93
  matcherType: 'LESS_THAN_OR_EQUAL_TO',
96
94
  unaryNumericMatcherData: IUnaryNumericMatcherData
97
95
  }
98
96
 
99
- interface IBetweenMatcher extends ISplitMatcherBase {
97
+ interface IBetweenMatcher extends IDefinitionMatcherBase {
100
98
  matcherType: 'BETWEEN'
101
99
  betweenMatcherData: IBetweenMatcherData
102
100
  }
103
101
 
104
- interface IEqualToSetMatcher extends ISplitMatcherBase {
102
+ interface IEqualToSetMatcher extends IDefinitionMatcherBase {
105
103
  matcherType: 'EQUAL_TO_SET',
106
104
  whitelistMatcherData: IWhitelistMatcherData
107
105
  }
108
106
 
109
- interface IContainsAnyOfSetMatcher extends ISplitMatcherBase {
107
+ interface IContainsAnyOfSetMatcher extends IDefinitionMatcherBase {
110
108
  matcherType: 'CONTAINS_ANY_OF_SET',
111
109
  whitelistMatcherData: IWhitelistMatcherData
112
110
  }
113
111
 
114
- interface IContainsAllOfSetMatcher extends ISplitMatcherBase {
112
+ interface IContainsAllOfSetMatcher extends IDefinitionMatcherBase {
115
113
  matcherType: 'CONTAINS_ALL_OF_SET',
116
114
  whitelistMatcherData: IWhitelistMatcherData
117
115
  }
118
116
 
119
- interface IPartOfSetMatcher extends ISplitMatcherBase {
117
+ interface IPartOfSetMatcher extends IDefinitionMatcherBase {
120
118
  matcherType: 'PART_OF_SET',
121
119
  whitelistMatcherData: IWhitelistMatcherData
122
120
  }
123
121
 
124
- interface IStartsWithMatcher extends ISplitMatcherBase {
122
+ interface IStartsWithMatcher extends IDefinitionMatcherBase {
125
123
  matcherType: 'STARTS_WITH',
126
124
  whitelistMatcherData: IWhitelistMatcherData
127
125
  }
128
126
 
129
- interface IEndsWithMatcher extends ISplitMatcherBase {
127
+ interface IEndsWithMatcher extends IDefinitionMatcherBase {
130
128
  matcherType: 'ENDS_WITH',
131
129
  whitelistMatcherData: IWhitelistMatcherData
132
130
  }
133
131
 
134
- interface IContainsStringMatcher extends ISplitMatcherBase {
132
+ interface IContainsStringMatcher extends IDefinitionMatcherBase {
135
133
  matcherType: 'CONTAINS_STRING',
136
134
  whitelistMatcherData: IWhitelistMatcherData
137
135
  }
138
136
 
139
- interface IInSplitTreatmentMatcher extends ISplitMatcherBase {
137
+ interface IInSplitTreatmentMatcher extends IDefinitionMatcherBase {
140
138
  matcherType: 'IN_SPLIT_TREATMENT',
141
139
  dependencyMatcherData: IDependencyMatcherData,
142
140
  }
143
141
 
144
- interface IEqualToBooleanMatcher extends ISplitMatcherBase {
142
+ interface IEqualToBooleanMatcher extends IDefinitionMatcherBase {
145
143
  matcherType: 'EQUAL_TO_BOOLEAN',
146
144
  booleanMatcherData: boolean
147
145
  }
148
146
 
149
- interface IMatchesStringMatcher extends ISplitMatcherBase {
147
+ interface IMatchesStringMatcher extends IDefinitionMatcherBase {
150
148
  matcherType: 'MATCHES_STRING',
151
149
  stringMatcherData: string
152
150
  }
153
151
 
154
- interface IEqualToSemverMatcher extends ISplitMatcherBase {
152
+ interface IEqualToSemverMatcher extends IDefinitionMatcherBase {
155
153
  matcherType: 'EQUAL_TO_SEMVER',
156
154
  stringMatcherData: string
157
155
  }
158
156
 
159
- interface IGreaterThanOrEqualToSemverMatcher extends ISplitMatcherBase {
157
+ interface IGreaterThanOrEqualToSemverMatcher extends IDefinitionMatcherBase {
160
158
  matcherType: 'GREATER_THAN_OR_EQUAL_TO_SEMVER',
161
159
  stringMatcherData: string
162
160
  }
163
161
 
164
162
 
165
- interface ILessThanOrEqualToSemverMatcher extends ISplitMatcherBase {
163
+ interface ILessThanOrEqualToSemverMatcher extends IDefinitionMatcherBase {
166
164
  matcherType: 'LESS_THAN_OR_EQUAL_TO_SEMVER',
167
165
  stringMatcherData: string
168
166
  }
169
167
 
170
- interface IBetweenSemverMatcher extends ISplitMatcherBase {
168
+ interface IBetweenSemverMatcher extends IDefinitionMatcherBase {
171
169
  matcherType: 'BETWEEN_SEMVER'
172
170
  betweenStringMatcherData: IBetweenStringMatcherData
173
171
  }
174
172
 
175
- interface IInListSemverMatcher extends ISplitMatcherBase {
173
+ interface IInListSemverMatcher extends IDefinitionMatcherBase {
176
174
  matcherType: 'IN_LIST_SEMVER',
177
175
  whitelistMatcherData: IWhitelistMatcherData
178
176
  }
179
177
 
180
- export type ISplitMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher |
178
+ export type IDefinitionMatcher = IAllKeysMatcher | IInSegmentMatcher | IWhitelistMatcher | IEqualToMatcher | IGreaterThanOrEqualToMatcher |
181
179
  ILessThanOrEqualToMatcher | IBetweenMatcher | IEqualToSetMatcher | IContainsAnyOfSetMatcher | IContainsAllOfSetMatcher | IPartOfSetMatcher |
182
180
  IStartsWithMatcher | IEndsWithMatcher | IContainsStringMatcher | IInSplitTreatmentMatcher | IEqualToBooleanMatcher | IMatchesStringMatcher |
183
181
  IEqualToSemverMatcher | IGreaterThanOrEqualToSemverMatcher | ILessThanOrEqualToSemverMatcher | IBetweenSemverMatcher | IInListSemverMatcher |
184
182
  IInLargeSegmentMatcher | IInRBSegmentMatcher
185
183
 
186
- /** Split object */
187
- export interface ISplitPartition {
184
+ export interface IDefinitionPartition {
188
185
  treatment: string
189
186
  size: number
190
187
  }
191
188
 
192
- export interface ISplitCondition {
189
+ export interface IDefinitionCondition {
193
190
  matcherGroup: {
194
191
  combiner: 'AND',
195
- matchers: ISplitMatcher[]
192
+ matchers: IDefinitionMatcher[]
196
193
  }
197
- partitions?: ISplitPartition[]
194
+ partitions?: IDefinitionPartition[]
198
195
  label?: string
199
196
  conditionType?: 'ROLLOUT' | 'WHITELIST'
200
197
  }
@@ -204,53 +201,51 @@ export interface IExcludedSegment {
204
201
  name: string,
205
202
  }
206
203
 
207
- export interface IRBSegment {
208
- name: string,
209
- changeNumber: number,
210
- status: 'ACTIVE' | 'ARCHIVED',
211
- conditions?: ISplitCondition[],
204
+ export interface TargetingEntity {
205
+ name: string;
206
+ changeNumber: number;
207
+ status?: 'ACTIVE' | 'ARCHIVED';
208
+ conditions: IDefinitionCondition[];
209
+ }
210
+
211
+ export interface IRBSegment extends TargetingEntity {
212
212
  excluded?: {
213
213
  keys?: string[] | null,
214
214
  segments?: IExcludedSegment[] | null
215
- }
215
+ } | null
216
216
  }
217
217
 
218
- export interface ISplit {
219
- name: string,
220
- changeNumber: number,
221
- status: 'ACTIVE' | 'ARCHIVED',
222
- conditions: ISplitCondition[],
218
+ export interface IDefinition extends TargetingEntity {
219
+ trafficTypeName: string;
220
+ sets?: string[] | null;
221
+ impressionsDisabled?: boolean;
223
222
  prerequisites?: null | {
224
223
  n: string,
225
224
  ts: string[]
226
- }[]
227
- killed: boolean,
228
- defaultTreatment: string,
229
- trafficTypeName: string,
230
- seed: number,
231
- trafficAllocation?: number,
232
- trafficAllocationSeed?: number
225
+ }[];
226
+ killed: boolean;
227
+ defaultTreatment: string;
228
+ seed: number;
229
+ trafficAllocation?: number;
230
+ trafficAllocationSeed?: number;
233
231
  configurations?: {
234
- [treatmentName: string]: string
235
- },
236
- sets?: string[],
237
- impressionsDisabled?: boolean
232
+ [treatmentName: string]: string | SplitIO.JsonObject
233
+ } | null;
238
234
  }
239
235
 
240
- // Split definition used in offline mode
241
- export type ISplitPartial = Pick<ISplit, 'conditions' | 'configurations' | 'trafficTypeName'>
242
-
243
236
  /** Interface of the parsed JSON response of `/splitChanges` */
244
- export interface ISplitChangesResponse {
245
- ff?: {
246
- t: number,
247
- s?: number,
248
- d: ISplit[]
237
+ export interface IDefinitionChangesResponse {
238
+ d?: {
239
+ till: number,
240
+ since?: number | null,
241
+ updated: IDefinition[],
242
+ removed: string[],
249
243
  },
250
244
  rbs?: {
251
- t: number,
252
- s?: number,
253
- d: IRBSegment[]
245
+ till: number,
246
+ since?: number | null,
247
+ updated: IRBSegment[],
248
+ removed: string[],
254
249
  }
255
250
  }
256
251
 
@@ -4,10 +4,10 @@ import { keyParser } from '../utils/key';
4
4
  import { thenable } from '../utils/promise/thenable';
5
5
  import { NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED, PREREQUISITES_NOT_MET } from '../utils/labels';
6
6
  import { CONTROL } from '../utils/constants';
7
- import { ISplit, MaybeThenable } from '../dtos/types';
7
+ import { IDefinition, MaybeThenable } from '../dtos/types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { IStorageAsync, IStorageSync } from '../storages/types';
10
- import { IEvaluation, IEvaluationResult, ISplitEvaluator } from './types';
10
+ import { IEvaluation, IEvaluationResult, IDefinitionEvaluator } from './types';
11
11
  import { ILogger } from '../logger/types';
12
12
  import { ENGINE_DEFAULT } from '../logger/constants';
13
13
  import { prerequisitesMatcherContext } from './matchers/prerequisites';
@@ -19,7 +19,7 @@ function evaluationResult(result: IEvaluation | undefined, defaultTreatment: str
19
19
  };
20
20
  }
21
21
 
22
- export function engineParser(log: ILogger, split: ISplit, storage: IStorageSync | IStorageAsync) {
22
+ export function engineParser(log: ILogger, split: IDefinition, storage: IStorageSync | IStorageAsync) {
23
23
  const { killed, seed, trafficAllocation, trafficAllocationSeed, status, conditions, prerequisites } = split;
24
24
 
25
25
  const defaultTreatment = isString(split.defaultTreatment) ? split.defaultTreatment : CONTROL;
@@ -29,7 +29,7 @@ export function engineParser(log: ILogger, split: ISplit, storage: IStorageSync
29
29
 
30
30
  return {
31
31
 
32
- getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: ISplitEvaluator): MaybeThenable<IEvaluationResult> {
32
+ getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: IDefinitionEvaluator): MaybeThenable<IEvaluationResult> {
33
33
 
34
34
  const parsedKey = keyParser(key);
35
35
 
@@ -2,11 +2,11 @@ import { findIndex } from '../../utils/lang';
2
2
  import { ILogger } from '../../logger/types';
3
3
  import { thenable } from '../../utils/promise/thenable';
4
4
  import { MaybeThenable } from '../../dtos/types';
5
- import { ISplitEvaluator } from '../types';
5
+ import { IDefinitionEvaluator } from '../types';
6
6
  import { ENGINE_COMBINER_AND } from '../../logger/constants';
7
7
  import SplitIO from '../../../types/splitio';
8
8
 
9
- export function andCombinerContext(log: ILogger, matchers: Array<(key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) => MaybeThenable<boolean>>) {
9
+ export function andCombinerContext(log: ILogger, matchers: Array<(key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) => MaybeThenable<boolean>>) {
10
10
 
11
11
  function andResults(results: boolean[]): boolean {
12
12
  // Array.prototype.every is supported by target environments
@@ -16,7 +16,7 @@ export function andCombinerContext(log: ILogger, matchers: Array<(key: SplitIO.S
16
16
  return hasMatchedAll;
17
17
  }
18
18
 
19
- return function andCombiner(key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator): MaybeThenable<boolean> {
19
+ return function andCombiner(key: SplitIO.SplitKey, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator): MaybeThenable<boolean> {
20
20
  const matcherResults = matchers.map(matcher => matcher(key, attributes, splitEvaluator));
21
21
 
22
22
  // If any matching result is a thenable we should use Promise.all
@@ -4,7 +4,7 @@ import { thenable } from '../../utils/promise/thenable';
4
4
  import { UNSUPPORTED_MATCHER_TYPE } from '../../utils/labels';
5
5
  import { CONTROL } from '../../utils/constants';
6
6
  import SplitIO from '../../../types/splitio';
7
- import { IEvaluation, IEvaluator, ISplitEvaluator } from '../types';
7
+ import { IEvaluation, IEvaluator, IDefinitionEvaluator } from '../types';
8
8
  import { ENGINE_COMBINER_IFELSEIF, ENGINE_COMBINER_IFELSEIF_NO_TREATMENT, ERROR_ENGINE_COMBINER_IFELSEIF } from '../../logger/constants';
9
9
 
10
10
  export function ifElseIfCombinerContext(log: ILogger, predicates: IEvaluator[]): IEvaluator {
@@ -33,7 +33,7 @@ export function ifElseIfCombinerContext(log: ILogger, predicates: IEvaluator[]):
33
33
  return undefined;
34
34
  }
35
35
 
36
- function ifElseIfCombiner(key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) {
36
+ function ifElseIfCombiner(key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) {
37
37
  // In Async environments we are going to have async predicates. There is none way to know
38
38
  // before hand so we need to evaluate all the predicates, verify for thenables, and finally,
39
39
  // define how to return the treatment (wrap result into a Promise or not).
@@ -18,10 +18,10 @@ export function getTreatment(log: ILogger, key: string, seed: number | undefined
18
18
  /**
19
19
  * Evaluates the traffic allocation to see if we should apply rollout conditions or not.
20
20
  */
21
- export function shouldApplyRollout(trafficAllocation: number, key: string, trafficAllocationSeed: number) {
21
+ export function shouldApplyRollout(trafficAllocation: number, bucketingKey: string, trafficAllocationSeed: number) {
22
22
  // For rollout, if traffic allocation for splits is 100%, we don't need to filter it because everything should evaluate the rollout.
23
23
  if (trafficAllocation < 100) {
24
- const _bucket = bucket(key, trafficAllocationSeed);
24
+ const _bucket = bucket(bucketingKey, trafficAllocationSeed);
25
25
 
26
26
  if (_bucket > trafficAllocation) {
27
27
  return false;
@@ -2,7 +2,7 @@ import { getTreatment, shouldApplyRollout } from './engineUtils';
2
2
  import { thenable } from '../../utils/promise/thenable';
3
3
  import { NOT_IN_SPLIT } from '../../utils/labels';
4
4
  import { MaybeThenable } from '../../dtos/types';
5
- import { IEvaluation, IEvaluator, ISplitEvaluator } from '../types';
5
+ import { IEvaluation, IEvaluator, IDefinitionEvaluator } from '../types';
6
6
  import SplitIO from '../../../types/splitio';
7
7
  import { ILogger } from '../../logger/types';
8
8
 
@@ -22,9 +22,9 @@ function match(log: ILogger, matchingResult: boolean, bucketingKey: string | und
22
22
  }
23
23
 
24
24
  // Condition factory
25
- export function conditionContext(log: ILogger, matcherEvaluator: (key: SplitIO.SplitKeyObject, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) => MaybeThenable<boolean>, treatments?: { getTreatmentFor: (x: number) => string }, label?: string, conditionType?: 'ROLLOUT' | 'WHITELIST'): IEvaluator {
25
+ export function conditionContext(log: ILogger, matcherEvaluator: (key: SplitIO.SplitKeyObject, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) => MaybeThenable<boolean>, treatments?: { getTreatmentFor: (x: number) => string }, label?: string, conditionType?: 'ROLLOUT' | 'WHITELIST'): IEvaluator {
26
26
 
27
- return function conditionEvaluator(key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: ISplitEvaluator) {
27
+ return function conditionEvaluator(key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) {
28
28
 
29
29
  // Whitelisting has more priority than traffic allocation, so we don't apply this filtering to those conditions.
30
30
  if (conditionType === 'ROLLOUT' && !shouldApplyRollout(trafficAllocation!, key.bucketingKey, trafficAllocationSeed!)) {
@@ -0,0 +1,76 @@
1
+ import SplitIO from '../../../../types/splitio';
2
+ import { ILogger } from '../../../logger/types';
3
+ import { isObject, isString } from '../../../utils/lang';
4
+
5
+ const CONFIG_NAME_DISCARD_REASON = 'Invalid config name (max 100 chars, no spaces)';
6
+ const VARIANT_DISCARD_REASON = 'Invalid variant (max 100 chars and must match pattern)';
7
+ const VALUE_DISCARD_REASON = 'Invalid value (must be an object)';
8
+
9
+ const VARIANT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
10
+
11
+ export function isValidConfigName(name: string): boolean {
12
+ return name.length <= 100 && !name.includes(' ');
13
+ }
14
+
15
+ export function isValidConfig(config?: SplitIO.Config): boolean {
16
+ if (!isObject(config)) return false;
17
+ if (!isString(config!.variant) || config!.variant.length > 100 || !VARIANT_PATTERN.test(config!.variant)) return false;
18
+ if (!isObject(config!.value)) return false;
19
+ return true;
20
+ }
21
+
22
+ function sanitizeGlobal(logger: ILogger, config?: SplitIO.Config): SplitIO.Config | undefined {
23
+ if (config === undefined) return undefined;
24
+ if (!isValidConfig(config)) {
25
+ if (!isObject(config) || !isString(config!.variant) || config!.variant.length > 100 || !VARIANT_PATTERN.test(config!.variant)) {
26
+ logger.error(`Fallback configs - Discarded fallback: ${VARIANT_DISCARD_REASON}`);
27
+ } else {
28
+ logger.error(`Fallback configs - Discarded fallback: ${VALUE_DISCARD_REASON}`);
29
+ }
30
+ return undefined;
31
+ }
32
+ return config;
33
+ }
34
+
35
+ function sanitizeByName(
36
+ logger: ILogger,
37
+ byNameFallbacks?: Record<string, SplitIO.Config>
38
+ ): Record<string, SplitIO.Config> {
39
+ const sanitizedByName: Record<string, SplitIO.Config> = {};
40
+
41
+ if (!isObject(byNameFallbacks)) return sanitizedByName;
42
+
43
+ Object.keys(byNameFallbacks!).forEach((configName) => {
44
+ const config = byNameFallbacks![configName];
45
+
46
+ if (!isValidConfigName(configName)) {
47
+ logger.error(`Fallback configs - Discarded config '${configName}': ${CONFIG_NAME_DISCARD_REASON}`);
48
+ return;
49
+ }
50
+
51
+ if (!isValidConfig(config)) {
52
+ if (!isObject(config) || !isString(config.variant) || config.variant.length > 100 || !VARIANT_PATTERN.test(config.variant)) {
53
+ logger.error(`Fallback configs - Discarded config '${configName}': ${VARIANT_DISCARD_REASON}`);
54
+ } else {
55
+ logger.error(`Fallback configs - Discarded config '${configName}': ${VALUE_DISCARD_REASON}`);
56
+ }
57
+ return;
58
+ }
59
+
60
+ sanitizedByName[configName] = config;
61
+ });
62
+
63
+ return sanitizedByName;
64
+ }
65
+
66
+ export function sanitizeFallbacks(logger: ILogger, fallbacks: SplitIO.FallbackConfigs): SplitIO.FallbackConfigs | undefined {
67
+ if (!isObject(fallbacks)) {
68
+ logger.error('Fallback configs - Discarded configuration: it must be an object with optional `global` and `byName` properties');
69
+ return;
70
+ }
71
+
72
+ return {
73
+ global: sanitizeGlobal(logger, fallbacks.global),
74
+ byName: sanitizeByName(logger, fallbacks.byName)
75
+ };
76
+ }
@@ -0,0 +1,24 @@
1
+ import { IFallbackCalculator } from '../fallbackTreatmentsCalculator/index';
2
+ import { CONTROL } from '../../utils/constants';
3
+ import SplitIO from '../../../types/splitio';
4
+
5
+ export const FALLBACK_PREFIX = 'fallback - ';
6
+
7
+ export function FallbackConfigsCalculator(fallbacks: SplitIO.FallbackConfigs = {}): IFallbackCalculator {
8
+
9
+ return (configName: string, label = '') => {
10
+ const fallback = fallbacks.byName?.[configName] || fallbacks.global;
11
+
12
+ return fallback ?
13
+ {
14
+ treatment: fallback.variant,
15
+ config: fallback.value,
16
+ label: `${FALLBACK_PREFIX}${label}`,
17
+ } :
18
+ {
19
+ treatment: CONTROL,
20
+ config: null,
21
+ label,
22
+ };
23
+ };
24
+ }
@@ -2,10 +2,8 @@ import { FallbackTreatmentConfiguration, Treatment, TreatmentWithConfig } from '
2
2
  import { ILogger } from '../../../logger/types';
3
3
  import { isObject, isString } from '../../../utils/lang';
4
4
 
5
- enum FallbackDiscardReason {
6
- FlagName = 'Invalid flag name (max 100 chars, no spaces)',
7
- Treatment = 'Invalid treatment (max 100 chars and must match pattern)',
8
- }
5
+ const FLAG_NAME_DISCARD_REASON = 'Invalid flag name (max 100 chars, no spaces)';
6
+ const TREATMENT_DISCARD_REASON = 'Invalid treatment (max 100 chars and must match pattern)';
9
7
 
10
8
  const TREATMENT_PATTERN = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
11
9
 
@@ -25,7 +23,7 @@ export function isValidTreatment(t?: Treatment | TreatmentWithConfig): boolean {
25
23
  function sanitizeGlobal(logger: ILogger, treatment?: Treatment | TreatmentWithConfig): Treatment | TreatmentWithConfig | undefined {
26
24
  if (treatment === undefined) return undefined;
27
25
  if (!isValidTreatment(treatment)) {
28
- logger.error(`Fallback treatments - Discarded fallback: ${FallbackDiscardReason.Treatment}`);
26
+ logger.error(`Fallback treatments - Discarded fallback: ${TREATMENT_DISCARD_REASON}`);
29
27
  return undefined;
30
28
  }
31
29
  return treatment;
@@ -43,12 +41,12 @@ function sanitizeByFlag(
43
41
  const t = byFlagFallbacks![flag];
44
42
 
45
43
  if (!isValidFlagName(flag)) {
46
- logger.error(`Fallback treatments - Discarded flag '${flag}': ${FallbackDiscardReason.FlagName}`);
44
+ logger.error(`Fallback treatments - Discarded flag '${flag}': ${FLAG_NAME_DISCARD_REASON}`);
47
45
  return;
48
46
  }
49
47
 
50
48
  if (!isValidTreatment(t)) {
51
- logger.error(`Fallback treatments - Discarded treatment for flag '${flag}': ${FallbackDiscardReason.Treatment}`);
49
+ logger.error(`Fallback treatments - Discarded treatment for flag '${flag}': ${TREATMENT_DISCARD_REASON}`);
52
50
  return;
53
51
  }
54
52