@featurevisor/core 2.26.1 → 3.0.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 (390) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/coverage/clover.xml +4991 -3130
  3. package/coverage/coverage-final.json +63 -39
  4. package/coverage/lcov-report/block-navigation.js +1 -1
  5. package/coverage/lcov-report/index.html +248 -98
  6. package/coverage/lcov-report/sorter.js +21 -7
  7. package/coverage/lcov-report/src/assess-distribution/index.html +116 -0
  8. package/coverage/lcov-report/src/assess-distribution/index.ts.html +754 -0
  9. package/coverage/lcov-report/{list → src/benchmark}/index.html +30 -30
  10. package/coverage/lcov-report/src/benchmark/index.ts.html +793 -0
  11. package/coverage/lcov-report/{builder → src/builder}/allocator.ts.html +38 -38
  12. package/coverage/lcov-report/{builder/buildScopedConditions.ts.html → src/builder/applyContextToConditions.ts.html} +80 -65
  13. package/coverage/lcov-report/{builder/buildScopedDatafile.ts.html → src/builder/applyContextToDatafile.ts.html} +92 -92
  14. package/coverage/lcov-report/{builder/buildScopedSegments.ts.html → src/builder/applyContextToSegments.ts.html} +103 -67
  15. package/coverage/lcov-report/{builder → src/builder}/buildDatafile.ts.html +336 -306
  16. package/coverage/lcov-report/src/builder/buildProject.ts.html +1117 -0
  17. package/coverage/lcov-report/src/builder/buildRuntimeDatafiles.ts.html +256 -0
  18. package/coverage/lcov-report/{builder → src/builder}/getFeatureRanges.ts.html +22 -22
  19. package/coverage/lcov-report/{builder → src/builder}/hashes.ts.html +50 -50
  20. package/coverage/lcov-report/{builder → src/builder}/index.html +114 -84
  21. package/coverage/lcov-report/{tester/cliFormat.ts.html → src/builder/index.ts.html} +17 -29
  22. package/coverage/lcov-report/{builder → src/builder}/mutateVariables.ts.html +55 -55
  23. package/coverage/lcov-report/{builder → src/builder}/mutator.ts.html +118 -118
  24. package/coverage/lcov-report/{builder → src/builder}/revision.ts.html +15 -15
  25. package/coverage/lcov-report/{builder → src/builder}/traffic.ts.html +86 -86
  26. package/coverage/lcov-report/src/cli/cli.ts.html +400 -0
  27. package/coverage/lcov-report/{tester → src/cli}/index.html +41 -41
  28. package/coverage/lcov-report/src/cli/plugins.ts.html +214 -0
  29. package/coverage/lcov-report/{config → src/config}/index.html +31 -31
  30. package/coverage/lcov-report/{config → src/config}/index.ts.html +12 -12
  31. package/coverage/lcov-report/{config → src/config}/projectConfig.ts.html +312 -96
  32. package/coverage/lcov-report/{datasource → src/datasource}/adapter.ts.html +28 -73
  33. package/coverage/lcov-report/{datasource → src/datasource}/datasource.ts.html +191 -104
  34. package/coverage/lcov-report/{datasource → src/datasource}/filesystemAdapter.ts.html +233 -635
  35. package/coverage/lcov-report/{datasource → src/datasource}/index.html +48 -48
  36. package/coverage/lcov-report/{datasource → src/datasource}/index.ts.html +14 -14
  37. package/coverage/lcov-report/src/evaluate/index.html +116 -0
  38. package/coverage/lcov-report/src/evaluate/index.ts.html +814 -0
  39. package/coverage/lcov-report/src/find-duplicate-segments/findDuplicateSegments.ts.html +313 -0
  40. package/coverage/lcov-report/src/find-duplicate-segments/index.html +131 -0
  41. package/coverage/lcov-report/src/find-duplicate-segments/index.ts.html +307 -0
  42. package/coverage/lcov-report/src/find-usage/index.html +116 -0
  43. package/coverage/lcov-report/src/find-usage/index.ts.html +1780 -0
  44. package/coverage/lcov-report/src/generate-code/index.html +131 -0
  45. package/coverage/lcov-report/src/generate-code/index.ts.html +403 -0
  46. package/coverage/lcov-report/{generate-code → src/generate-code}/typescript.ts.html +266 -1361
  47. package/coverage/lcov-report/{generate-code → src}/index.html +38 -23
  48. package/coverage/lcov-report/src/info/index.html +116 -0
  49. package/coverage/lcov-report/src/info/index.ts.html +472 -0
  50. package/coverage/lcov-report/src/init/index.html +116 -0
  51. package/coverage/lcov-report/src/init/index.ts.html +280 -0
  52. package/coverage/lcov-report/{linter → src/linter}/attributeSchema.ts.html +160 -157
  53. package/coverage/lcov-report/{linter → src/linter}/checkCircularDependency.ts.html +25 -25
  54. package/coverage/lcov-report/{linter → src/linter}/checkPercentageExceedingSlot.ts.html +42 -42
  55. package/coverage/lcov-report/{linter → src/linter}/conditionSchema.ts.html +207 -207
  56. package/coverage/lcov-report/{linter → src/linter}/featureSchema.ts.html +462 -471
  57. package/coverage/lcov-report/{linter → src/linter}/groupSchema.ts.html +25 -22
  58. package/coverage/lcov-report/{linter → src/linter}/index.html +129 -99
  59. package/coverage/lcov-report/src/linter/index.ts.html +88 -0
  60. package/coverage/lcov-report/{linter → src/linter}/lintProject.ts.html +740 -332
  61. package/coverage/lcov-report/{linter → src/linter}/mutationNotation.ts.html +130 -130
  62. package/coverage/lcov-report/{linter → src/linter}/printError.ts.html +27 -27
  63. package/coverage/lcov-report/{linter → src/linter}/schema.ts.html +153 -150
  64. package/coverage/lcov-report/{linter → src/linter}/segmentSchema.ts.html +18 -15
  65. package/coverage/lcov-report/src/linter/targetSchema.ts.html +223 -0
  66. package/coverage/lcov-report/{linter → src/linter}/testSchema.ts.html +54 -48
  67. package/coverage/lcov-report/{linter → src/linter}/zodHelpers.ts.html +17 -17
  68. package/coverage/lcov-report/src/list/index.html +131 -0
  69. package/coverage/lcov-report/src/list/index.ts.html +2065 -0
  70. package/coverage/lcov-report/{list → src/list}/matrix.ts.html +43 -58
  71. package/coverage/lcov-report/src/promoter/index.html +116 -0
  72. package/coverage/lcov-report/src/promoter/index.ts.html +3883 -0
  73. package/coverage/lcov-report/src/sets.ts.html +313 -0
  74. package/coverage/lcov-report/src/targeting.ts.html +403 -0
  75. package/coverage/lcov-report/src/tester/cliFormat.ts.html +133 -0
  76. package/coverage/lcov-report/{tester → src/tester}/helpers.ts.html +15 -15
  77. package/coverage/lcov-report/src/tester/index.html +206 -0
  78. package/coverage/lcov-report/src/tester/prettyDuration.ts.html +187 -0
  79. package/coverage/lcov-report/src/tester/printTestResult.ts.html +337 -0
  80. package/coverage/lcov-report/src/tester/testFeature.ts.html +1186 -0
  81. package/coverage/lcov-report/src/tester/testProject.ts.html +1018 -0
  82. package/coverage/lcov-report/src/tester/testSegment.ts.html +316 -0
  83. package/coverage/lcov-report/{utils → src/utils}/extractKeys.ts.html +68 -68
  84. package/coverage/lcov-report/{utils → src/utils}/git.ts.html +44 -68
  85. package/coverage/lcov-report/{utils → src/utils}/index.html +44 -44
  86. package/coverage/lcov-report/{utils → src/utils}/index.ts.html +14 -14
  87. package/coverage/lcov-report/{utils → src/utils}/pretty.ts.html +20 -20
  88. package/coverage/lcov.info +10121 -5723
  89. package/jest.config.js +13 -4
  90. package/lib/assess-distribution/index.d.ts +1 -1
  91. package/lib/assess-distribution/index.js +59 -40
  92. package/lib/assess-distribution/index.js.map +1 -1
  93. package/lib/benchmark/index.d.ts +8 -5
  94. package/lib/benchmark/index.js +82 -65
  95. package/lib/benchmark/index.js.map +1 -1
  96. package/lib/builder/applyContextToConditions.d.ts +5 -0
  97. package/lib/builder/{buildScopedConditions.js → applyContextToConditions.js} +19 -14
  98. package/lib/builder/applyContextToConditions.js.map +1 -0
  99. package/lib/builder/applyContextToDatafile.d.ts +2 -0
  100. package/lib/builder/{buildScopedDatafile.js → applyContextToDatafile.js} +26 -26
  101. package/lib/builder/applyContextToDatafile.js.map +1 -0
  102. package/lib/builder/applyContextToSegments.d.ts +5 -0
  103. package/lib/builder/{buildScopedSegments.js → applyContextToSegments.js} +19 -14
  104. package/lib/builder/applyContextToSegments.js.map +1 -0
  105. package/lib/builder/buildDatafile.d.ts +9 -6
  106. package/lib/builder/buildDatafile.js +86 -51
  107. package/lib/builder/buildDatafile.js.map +1 -1
  108. package/lib/builder/buildProject.d.ts +17 -3
  109. package/lib/builder/buildProject.js +151 -59
  110. package/lib/builder/buildProject.js.map +1 -1
  111. package/lib/builder/buildRuntimeDatafiles.d.ts +12 -0
  112. package/lib/builder/buildRuntimeDatafiles.js +35 -0
  113. package/lib/builder/buildRuntimeDatafiles.js.map +1 -0
  114. package/lib/builder/getFeatureRanges.js +34 -1
  115. package/lib/builder/getFeatureRanges.js.map +1 -1
  116. package/lib/builder/hashes.js +34 -1
  117. package/lib/builder/hashes.js.map +1 -1
  118. package/lib/builder/index.d.ts +0 -1
  119. package/lib/builder/index.js +0 -1
  120. package/lib/builder/index.js.map +1 -1
  121. package/lib/cli/cli.js +0 -4
  122. package/lib/cli/cli.js.map +1 -1
  123. package/lib/cli/plugins.js +7 -2
  124. package/lib/cli/plugins.js.map +1 -1
  125. package/lib/config/projectConfig.d.ts +17 -17
  126. package/lib/config/projectConfig.js +101 -15
  127. package/lib/config/projectConfig.js.map +1 -1
  128. package/lib/datasource/adapter.d.ts +7 -9
  129. package/lib/datasource/adapter.js +0 -7
  130. package/lib/datasource/adapter.js.map +1 -1
  131. package/lib/datasource/datasource.d.ts +15 -5
  132. package/lib/datasource/datasource.js +37 -9
  133. package/lib/datasource/datasource.js.map +1 -1
  134. package/lib/datasource/filesystemAdapter.d.ts +4 -10
  135. package/lib/datasource/filesystemAdapter.js +111 -149
  136. package/lib/datasource/filesystemAdapter.js.map +1 -1
  137. package/lib/evaluate/index.d.ts +1 -7
  138. package/lib/evaluate/index.js +81 -67
  139. package/lib/evaluate/index.js.map +1 -1
  140. package/lib/find-duplicate-segments/findDuplicateSegments.js +34 -1
  141. package/lib/find-duplicate-segments/findDuplicateSegments.js.map +1 -1
  142. package/lib/find-duplicate-segments/index.js +21 -13
  143. package/lib/find-duplicate-segments/index.js.map +1 -1
  144. package/lib/find-usage/index.js +57 -41
  145. package/lib/find-usage/index.js.map +1 -1
  146. package/lib/generate-code/index.d.ts +1 -1
  147. package/lib/generate-code/index.js +64 -21
  148. package/lib/generate-code/index.js.map +1 -1
  149. package/lib/generate-code/typescript.d.ts +1 -1
  150. package/lib/generate-code/typescript.js +59 -333
  151. package/lib/generate-code/typescript.js.map +1 -1
  152. package/lib/index.d.ts +2 -1
  153. package/lib/index.js +2 -1
  154. package/lib/index.js.map +1 -1
  155. package/lib/info/index.js +57 -16
  156. package/lib/info/index.js.map +1 -1
  157. package/lib/init/index.d.ts +2 -2
  158. package/lib/init/index.js +39 -3
  159. package/lib/init/index.js.map +1 -1
  160. package/lib/linter/attributeSchema.d.ts +1 -0
  161. package/lib/linter/attributeSchema.js +1 -0
  162. package/lib/linter/attributeSchema.js.map +1 -1
  163. package/lib/linter/conditionSchema.js +5 -5
  164. package/lib/linter/conditionSchema.js.map +1 -1
  165. package/lib/linter/featureSchema.d.ts +4 -1
  166. package/lib/linter/featureSchema.js +15 -13
  167. package/lib/linter/featureSchema.js.map +1 -1
  168. package/lib/linter/groupSchema.d.ts +1 -0
  169. package/lib/linter/groupSchema.js +1 -0
  170. package/lib/linter/groupSchema.js.map +1 -1
  171. package/lib/linter/lintProject.d.ts +1 -3
  172. package/lib/linter/lintProject.js +198 -68
  173. package/lib/linter/lintProject.js.map +1 -1
  174. package/lib/linter/schema.js +1 -0
  175. package/lib/linter/schema.js.map +1 -1
  176. package/lib/linter/segmentSchema.d.ts +1 -0
  177. package/lib/linter/segmentSchema.js +1 -0
  178. package/lib/linter/segmentSchema.js.map +1 -1
  179. package/lib/linter/targetSchema.d.ts +16 -0
  180. package/lib/linter/targetSchema.js +40 -0
  181. package/lib/linter/targetSchema.js.map +1 -0
  182. package/lib/linter/testSchema.d.ts +4 -3
  183. package/lib/linter/testSchema.js +9 -4
  184. package/lib/linter/testSchema.js.map +1 -1
  185. package/lib/list/index.d.ts +1 -0
  186. package/lib/list/index.js +131 -12
  187. package/lib/list/index.js.map +1 -1
  188. package/lib/list/matrix.js +3 -7
  189. package/lib/list/matrix.js.map +1 -1
  190. package/lib/promoter/index.d.ts +50 -0
  191. package/lib/promoter/index.js +880 -0
  192. package/lib/promoter/index.js.map +1 -0
  193. package/lib/sets.d.ts +11 -0
  194. package/lib/sets.js +81 -0
  195. package/lib/sets.js.map +1 -0
  196. package/lib/targeting.d.ts +14 -0
  197. package/lib/targeting.js +82 -0
  198. package/lib/targeting.js.map +1 -0
  199. package/lib/tester/cliFormat.d.ts +7 -1
  200. package/lib/tester/cliFormat.js +11 -2
  201. package/lib/tester/cliFormat.js.map +1 -1
  202. package/lib/tester/printTestResult.js +2 -2
  203. package/lib/tester/printTestResult.js.map +1 -1
  204. package/lib/tester/testFeature.d.ts +0 -1
  205. package/lib/tester/testFeature.js +8 -25
  206. package/lib/tester/testFeature.js.map +1 -1
  207. package/lib/tester/testProject.d.ts +2 -3
  208. package/lib/tester/testProject.js +93 -86
  209. package/lib/tester/testProject.js.map +1 -1
  210. package/lib/tester/testSegment.d.ts +1 -1
  211. package/lib/tester/testSegment.js +3 -21
  212. package/lib/tester/testSegment.js.map +1 -1
  213. package/lib/utils/git.js +45 -19
  214. package/lib/utils/git.js.map +1 -1
  215. package/package.json +12 -12
  216. package/src/assess-distribution/index.ts +72 -52
  217. package/src/benchmark/index.ts +124 -91
  218. package/src/builder/{buildScopedConditions.spec.ts → applyContextToConditions.spec.ts} +160 -142
  219. package/src/builder/{buildScopedConditions.ts → applyContextToConditions.ts} +19 -14
  220. package/src/builder/{buildScopedDatafile.spec.ts → applyContextToDatafile.spec.ts} +141 -81
  221. package/src/builder/{buildScopedDatafile.ts → applyContextToDatafile.ts} +33 -33
  222. package/src/builder/{buildScopedSegments.spec.ts → applyContextToSegments.spec.ts} +171 -151
  223. package/src/builder/{buildScopedSegments.ts → applyContextToSegments.ts} +26 -14
  224. package/src/builder/buildDatafile.spec.ts +192 -14
  225. package/src/builder/buildDatafile.ts +74 -64
  226. package/src/builder/buildProject.ts +171 -86
  227. package/src/builder/buildRuntimeDatafiles.ts +57 -0
  228. package/src/builder/index.ts +0 -1
  229. package/src/cli/cli.ts +0 -5
  230. package/src/cli/plugins.ts +7 -2
  231. package/src/config/projectConfig.spec.ts +171 -8
  232. package/src/config/projectConfig.ts +100 -28
  233. package/src/datasource/adapter.ts +8 -23
  234. package/src/datasource/datasource.ts +50 -21
  235. package/src/datasource/filesystemAdapter.spec.ts +133 -74
  236. package/src/datasource/filesystemAdapter.ts +93 -227
  237. package/src/evaluate/index.ts +109 -97
  238. package/src/find-duplicate-segments/index.ts +34 -16
  239. package/src/find-usage/index.ts +89 -44
  240. package/src/generate-code/index.ts +36 -24
  241. package/src/generate-code/typescript.spec.ts +106 -0
  242. package/src/generate-code/typescript.ts +33 -398
  243. package/src/index.ts +2 -1
  244. package/src/info/index.ts +72 -16
  245. package/src/init/index.ts +1 -1
  246. package/src/linter/attributeSchema.ts +1 -0
  247. package/src/linter/conditionSchema.spec.ts +23 -3
  248. package/src/linter/conditionSchema.ts +5 -5
  249. package/src/linter/featureSchema.spec.ts +107 -18
  250. package/src/linter/featureSchema.ts +25 -28
  251. package/src/linter/groupSchema.ts +1 -0
  252. package/src/linter/lintProject.spec.ts +131 -92
  253. package/src/linter/lintProject.ts +233 -97
  254. package/src/linter/schema.ts +1 -0
  255. package/src/linter/segmentSchema.spec.ts +5 -3
  256. package/src/linter/segmentSchema.ts +1 -0
  257. package/src/linter/targetSchema.spec.ts +159 -0
  258. package/src/linter/targetSchema.ts +46 -0
  259. package/src/linter/testSchema.spec.ts +70 -5
  260. package/src/linter/testSchema.ts +12 -10
  261. package/src/list/index.spec.ts +135 -0
  262. package/src/list/index.ts +188 -12
  263. package/src/list/matrix.ts +3 -8
  264. package/src/promoter/index.spec.ts +617 -0
  265. package/src/promoter/index.ts +1266 -0
  266. package/src/sets.ts +76 -0
  267. package/src/targeting.spec.ts +74 -0
  268. package/src/targeting.ts +106 -0
  269. package/src/tester/cliFormat.ts +11 -1
  270. package/src/tester/printTestResult.ts +12 -3
  271. package/src/tester/testFeature.ts +10 -36
  272. package/src/tester/testProject.spec.ts +50 -0
  273. package/src/tester/testProject.ts +89 -140
  274. package/src/tester/testSegment.ts +5 -22
  275. package/src/utils/git.ts +13 -21
  276. package/tsconfig.cjs.json +5 -1
  277. package/tsconfig.typecheck.json +9 -0
  278. package/coverage/lcov-report/builder/convertToV1.ts.html +0 -583
  279. package/lib/builder/allocator.spec.d.ts +0 -1
  280. package/lib/builder/allocator.spec.js +0 -85
  281. package/lib/builder/allocator.spec.js.map +0 -1
  282. package/lib/builder/buildDatafile.spec.d.ts +0 -1
  283. package/lib/builder/buildDatafile.spec.js +0 -233
  284. package/lib/builder/buildDatafile.spec.js.map +0 -1
  285. package/lib/builder/buildScopedConditions.d.ts +0 -5
  286. package/lib/builder/buildScopedConditions.js.map +0 -1
  287. package/lib/builder/buildScopedConditions.spec.d.ts +0 -1
  288. package/lib/builder/buildScopedConditions.spec.js +0 -2167
  289. package/lib/builder/buildScopedConditions.spec.js.map +0 -1
  290. package/lib/builder/buildScopedDatafile.d.ts +0 -2
  291. package/lib/builder/buildScopedDatafile.js.map +0 -1
  292. package/lib/builder/buildScopedDatafile.spec.d.ts +0 -1
  293. package/lib/builder/buildScopedDatafile.spec.js +0 -2277
  294. package/lib/builder/buildScopedDatafile.spec.js.map +0 -1
  295. package/lib/builder/buildScopedSegments.d.ts +0 -5
  296. package/lib/builder/buildScopedSegments.js.map +0 -1
  297. package/lib/builder/buildScopedSegments.spec.d.ts +0 -1
  298. package/lib/builder/buildScopedSegments.spec.js +0 -1062
  299. package/lib/builder/buildScopedSegments.spec.js.map +0 -1
  300. package/lib/builder/convertToV1.d.ts +0 -10
  301. package/lib/builder/convertToV1.js +0 -119
  302. package/lib/builder/convertToV1.js.map +0 -1
  303. package/lib/builder/mutateVariables.spec.d.ts +0 -1
  304. package/lib/builder/mutateVariables.spec.js +0 -1074
  305. package/lib/builder/mutateVariables.spec.js.map +0 -1
  306. package/lib/builder/mutator.spec.d.ts +0 -1
  307. package/lib/builder/mutator.spec.js +0 -368
  308. package/lib/builder/mutator.spec.js.map +0 -1
  309. package/lib/builder/revision.spec.d.ts +0 -1
  310. package/lib/builder/revision.spec.js +0 -21
  311. package/lib/builder/revision.spec.js.map +0 -1
  312. package/lib/builder/traffic.spec.d.ts +0 -1
  313. package/lib/builder/traffic.spec.js +0 -872
  314. package/lib/builder/traffic.spec.js.map +0 -1
  315. package/lib/config/projectConfig.spec.d.ts +0 -1
  316. package/lib/config/projectConfig.spec.js +0 -24
  317. package/lib/config/projectConfig.spec.js.map +0 -1
  318. package/lib/datasource/filesystemAdapter.spec.d.ts +0 -1
  319. package/lib/datasource/filesystemAdapter.spec.js +0 -88
  320. package/lib/datasource/filesystemAdapter.spec.js.map +0 -1
  321. package/lib/generate-code/typescript.spec.d.ts +0 -1
  322. package/lib/generate-code/typescript.spec.js +0 -78
  323. package/lib/generate-code/typescript.spec.js.map +0 -1
  324. package/lib/linter/attributeSchema.spec.d.ts +0 -1
  325. package/lib/linter/attributeSchema.spec.js +0 -266
  326. package/lib/linter/attributeSchema.spec.js.map +0 -1
  327. package/lib/linter/conditionSchema.spec.d.ts +0 -1
  328. package/lib/linter/conditionSchema.spec.js +0 -380
  329. package/lib/linter/conditionSchema.spec.js.map +0 -1
  330. package/lib/linter/featureSchema.spec.d.ts +0 -1
  331. package/lib/linter/featureSchema.spec.js +0 -1552
  332. package/lib/linter/featureSchema.spec.js.map +0 -1
  333. package/lib/linter/lintProject.spec.d.ts +0 -1
  334. package/lib/linter/lintProject.spec.js +0 -211
  335. package/lib/linter/lintProject.spec.js.map +0 -1
  336. package/lib/linter/mutationNotation.spec.d.ts +0 -1
  337. package/lib/linter/mutationNotation.spec.js +0 -598
  338. package/lib/linter/mutationNotation.spec.js.map +0 -1
  339. package/lib/linter/schema.spec.d.ts +0 -1
  340. package/lib/linter/schema.spec.js +0 -535
  341. package/lib/linter/schema.spec.js.map +0 -1
  342. package/lib/linter/segmentSchema.spec.d.ts +0 -1
  343. package/lib/linter/segmentSchema.spec.js +0 -303
  344. package/lib/linter/segmentSchema.spec.js.map +0 -1
  345. package/lib/linter/testSchema.spec.d.ts +0 -1
  346. package/lib/linter/testSchema.spec.js +0 -162
  347. package/lib/linter/testSchema.spec.js.map +0 -1
  348. package/lib/list/matrix.spec.d.ts +0 -1
  349. package/lib/list/matrix.spec.js +0 -42
  350. package/lib/list/matrix.spec.js.map +0 -1
  351. package/lib/site/exportSite.d.ts +0 -2
  352. package/lib/site/exportSite.js +0 -30
  353. package/lib/site/exportSite.js.map +0 -1
  354. package/lib/site/generateHistory.d.ts +0 -3
  355. package/lib/site/generateHistory.js +0 -31
  356. package/lib/site/generateHistory.js.map +0 -1
  357. package/lib/site/generateSiteSearchIndex.d.ts +0 -4
  358. package/lib/site/generateSiteSearchIndex.js +0 -195
  359. package/lib/site/generateSiteSearchIndex.js.map +0 -1
  360. package/lib/site/getLastModifiedFromHistory.d.ts +0 -2
  361. package/lib/site/getLastModifiedFromHistory.js +0 -18
  362. package/lib/site/getLastModifiedFromHistory.js.map +0 -1
  363. package/lib/site/getOwnerAndRepoFromUrl.d.ts +0 -4
  364. package/lib/site/getOwnerAndRepoFromUrl.js +0 -20
  365. package/lib/site/getOwnerAndRepoFromUrl.js.map +0 -1
  366. package/lib/site/getRelativePaths.d.ts +0 -6
  367. package/lib/site/getRelativePaths.js +0 -15
  368. package/lib/site/getRelativePaths.js.map +0 -1
  369. package/lib/site/getRepoDetails.d.ts +0 -8
  370. package/lib/site/getRepoDetails.js +0 -48
  371. package/lib/site/getRepoDetails.js.map +0 -1
  372. package/lib/site/index.d.ts +0 -2
  373. package/lib/site/index.js +0 -43
  374. package/lib/site/index.js.map +0 -1
  375. package/lib/site/serveSite.d.ts +0 -2
  376. package/lib/site/serveSite.js +0 -54
  377. package/lib/site/serveSite.js.map +0 -1
  378. package/lib/tester/helpers.spec.d.ts +0 -1
  379. package/lib/tester/helpers.spec.js +0 -115
  380. package/lib/tester/helpers.spec.js.map +0 -1
  381. package/src/builder/convertToV1.ts +0 -166
  382. package/src/site/exportSite.ts +0 -42
  383. package/src/site/generateHistory.ts +0 -40
  384. package/src/site/generateSiteSearchIndex.ts +0 -258
  385. package/src/site/getLastModifiedFromHistory.ts +0 -21
  386. package/src/site/getOwnerAndRepoFromUrl.ts +0 -17
  387. package/src/site/getRelativePaths.ts +0 -24
  388. package/src/site/getRepoDetails.ts +0 -62
  389. package/src/site/index.ts +0 -46
  390. package/src/site/serveSite.ts +0 -58
@@ -1,2277 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const buildScopedDatafile_1 = require("./buildScopedDatafile");
4
- describe("core: buildScopedDatafile", function () {
5
- test("buildScopedDatafile is a function", function () {
6
- expect(buildScopedDatafile_1.buildScopedDatafile).toBeInstanceOf(Function);
7
- });
8
- describe("basic functionality", function () {
9
- test("empty datafile", function () {
10
- const datafile = {
11
- schemaVersion: "2",
12
- revision: "unknown",
13
- segments: {},
14
- features: {},
15
- };
16
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
17
- expect(result).toEqual(datafile);
18
- });
19
- test("datafile with no segments", function () {
20
- const datafile = {
21
- schemaVersion: "2",
22
- revision: "unknown",
23
- segments: {},
24
- features: {
25
- feature1: {
26
- bucketBy: ["userId"],
27
- traffic: [
28
- {
29
- key: "rule1",
30
- segments: "*",
31
- percentage: 100000,
32
- },
33
- ],
34
- },
35
- },
36
- };
37
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
38
- expect(result.segments).toEqual({});
39
- expect(result.features.feature1).toBeDefined();
40
- });
41
- test("datafile with no features", function () {
42
- const datafile = {
43
- schemaVersion: "2",
44
- revision: "unknown",
45
- segments: {
46
- web: {
47
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
48
- },
49
- },
50
- features: {},
51
- };
52
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
53
- expect(result.segments).toEqual({});
54
- expect(result.features).toEqual({});
55
- });
56
- });
57
- describe("segments processing", function () {
58
- test("segment with matching condition becomes * and is removed", function () {
59
- const datafile = {
60
- schemaVersion: "2",
61
- revision: "unknown",
62
- segments: {
63
- web: {
64
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
65
- },
66
- },
67
- features: {},
68
- };
69
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
70
- expect(result.segments).toEqual({});
71
- });
72
- test("segment with non-matching condition remains", function () {
73
- const datafile = {
74
- schemaVersion: "2",
75
- revision: "unknown",
76
- segments: {
77
- web: {
78
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
79
- },
80
- },
81
- features: {},
82
- };
83
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
84
- expect(result.segments.web).toBeDefined();
85
- expect(result.segments.web.conditions).toEqual([
86
- { attribute: "platform", operator: "equals", value: "web" },
87
- ]);
88
- });
89
- test("segment with * condition is removed", function () {
90
- const datafile = {
91
- schemaVersion: "2",
92
- revision: "unknown",
93
- segments: {
94
- all: {
95
- conditions: "*",
96
- },
97
- },
98
- features: {},
99
- };
100
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
101
- expect(result.segments).toEqual({});
102
- });
103
- test("multiple segments - some match, some don't", function () {
104
- const datafile = {
105
- schemaVersion: "2",
106
- revision: "unknown",
107
- segments: {
108
- web: {
109
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
110
- },
111
- mobile: {
112
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
113
- },
114
- chrome: {
115
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
116
- },
117
- },
118
- features: {},
119
- };
120
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
121
- expect(result.segments.web).toBeUndefined();
122
- expect(result.segments.mobile).toBeDefined();
123
- expect(result.segments.chrome).toBeUndefined();
124
- });
125
- test("segment with AND conditions - all match", function () {
126
- const datafile = {
127
- schemaVersion: "2",
128
- revision: "unknown",
129
- segments: {
130
- premium: {
131
- conditions: {
132
- and: [
133
- { attribute: "tier", operator: "equals", value: "premium" },
134
- { attribute: "status", operator: "equals", value: "active" },
135
- ],
136
- },
137
- },
138
- },
139
- features: {},
140
- };
141
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { tier: "premium", status: "active" });
142
- expect(result.segments).toEqual({});
143
- });
144
- test("segment with AND conditions - partial match", function () {
145
- const datafile = {
146
- schemaVersion: "2",
147
- revision: "unknown",
148
- segments: {
149
- premium: {
150
- conditions: {
151
- and: [
152
- { attribute: "tier", operator: "equals", value: "premium" },
153
- { attribute: "status", operator: "equals", value: "active" },
154
- ],
155
- },
156
- },
157
- },
158
- features: {},
159
- };
160
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { tier: "premium" });
161
- expect(result.segments.premium).toBeDefined();
162
- expect(result.segments.premium.conditions).toEqual({
163
- and: [{ attribute: "status", operator: "equals", value: "active" }],
164
- });
165
- });
166
- test("segment with OR conditions - one matches", function () {
167
- const datafile = {
168
- schemaVersion: "2",
169
- revision: "unknown",
170
- segments: {
171
- browser: {
172
- conditions: {
173
- or: [
174
- { attribute: "browser", operator: "equals", value: "chrome" },
175
- { attribute: "browser", operator: "equals", value: "firefox" },
176
- ],
177
- },
178
- },
179
- },
180
- features: {},
181
- };
182
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { browser: "chrome" });
183
- expect(result.segments).toEqual({
184
- browser: {
185
- conditions: {
186
- // @TODO: this OR (with only one child) can become a single (AND) condition
187
- or: [
188
- {
189
- attribute: "browser",
190
- operator: "equals",
191
- value: "firefox",
192
- },
193
- ],
194
- },
195
- },
196
- });
197
- });
198
- test("segment with array of conditions - all match", function () {
199
- const datafile = {
200
- schemaVersion: "2",
201
- revision: "unknown",
202
- segments: {
203
- combined: {
204
- conditions: [
205
- { attribute: "platform", operator: "equals", value: "web" },
206
- { attribute: "browser", operator: "equals", value: "chrome" },
207
- ],
208
- },
209
- },
210
- features: {},
211
- };
212
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
213
- expect(result.segments).toEqual({});
214
- });
215
- test("segment with array of conditions - partial match", function () {
216
- const datafile = {
217
- schemaVersion: "2",
218
- revision: "unknown",
219
- segments: {
220
- combined: {
221
- conditions: [
222
- { attribute: "platform", operator: "equals", value: "web" },
223
- { attribute: "browser", operator: "equals", value: "chrome" },
224
- ],
225
- },
226
- },
227
- features: {},
228
- };
229
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
230
- expect(result.segments.combined).toBeDefined();
231
- expect(result.segments.combined.conditions).toEqual([
232
- { attribute: "browser", operator: "equals", value: "chrome" },
233
- ]);
234
- });
235
- });
236
- describe("features with force entries", function () {
237
- test("force with matching segments becomes *", function () {
238
- const datafile = {
239
- schemaVersion: "2",
240
- revision: "unknown",
241
- segments: {
242
- web: {
243
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
244
- },
245
- },
246
- features: {
247
- feature1: {
248
- bucketBy: ["userId"],
249
- traffic: [],
250
- force: [
251
- {
252
- segments: "web",
253
- variation: "treatment",
254
- },
255
- ],
256
- },
257
- },
258
- };
259
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
260
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
261
- });
262
- test("force with non-matching segments remains", function () {
263
- const datafile = {
264
- schemaVersion: "2",
265
- revision: "unknown",
266
- segments: {
267
- web: {
268
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
269
- },
270
- },
271
- features: {
272
- feature1: {
273
- bucketBy: ["userId"],
274
- traffic: [],
275
- force: [
276
- {
277
- segments: "web",
278
- variation: "treatment",
279
- },
280
- ],
281
- },
282
- },
283
- };
284
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
285
- expect(result.features.feature1.force?.[0].segments).toEqual("web");
286
- });
287
- test("force with matching conditions becomes *", function () {
288
- const datafile = {
289
- schemaVersion: "2",
290
- revision: "unknown",
291
- segments: {},
292
- features: {
293
- feature1: {
294
- bucketBy: ["userId"],
295
- traffic: [],
296
- force: [
297
- {
298
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
299
- variation: "treatment",
300
- },
301
- ],
302
- },
303
- },
304
- };
305
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
306
- expect(result.features.feature1.force?.[0].conditions).toEqual("*");
307
- });
308
- test("force with non-matching conditions remains", function () {
309
- const datafile = {
310
- schemaVersion: "2",
311
- revision: "unknown",
312
- segments: {},
313
- features: {
314
- feature1: {
315
- bucketBy: ["userId"],
316
- traffic: [],
317
- force: [
318
- {
319
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
320
- variation: "treatment",
321
- },
322
- ],
323
- },
324
- },
325
- };
326
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
327
- expect(result.features.feature1.force?.[0].conditions).toEqual([
328
- { attribute: "platform", operator: "equals", value: "web" },
329
- ]);
330
- });
331
- test("force with array of segments - all match", function () {
332
- const datafile = {
333
- schemaVersion: "2",
334
- revision: "unknown",
335
- segments: {
336
- web: {
337
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
338
- },
339
- chrome: {
340
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
341
- },
342
- },
343
- features: {
344
- feature1: {
345
- bucketBy: ["userId"],
346
- traffic: [],
347
- force: [
348
- {
349
- segments: ["web", "chrome"],
350
- variation: "treatment",
351
- },
352
- ],
353
- },
354
- },
355
- };
356
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
357
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
358
- });
359
- test("force with array of segments - partial match", function () {
360
- const datafile = {
361
- schemaVersion: "2",
362
- revision: "unknown",
363
- segments: {
364
- web: {
365
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
366
- },
367
- chrome: {
368
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
369
- },
370
- },
371
- features: {
372
- feature1: {
373
- bucketBy: ["userId"],
374
- traffic: [],
375
- force: [
376
- {
377
- segments: ["web", "chrome"],
378
- variation: "treatment",
379
- },
380
- ],
381
- },
382
- },
383
- };
384
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
385
- expect(result.features.feature1.force?.[0].segments).toEqual(["chrome"]);
386
- });
387
- test("force with AND group segments", function () {
388
- const datafile = {
389
- schemaVersion: "2",
390
- revision: "unknown",
391
- segments: {
392
- web: {
393
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
394
- },
395
- chrome: {
396
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
397
- },
398
- },
399
- features: {
400
- feature1: {
401
- bucketBy: ["userId"],
402
- traffic: [],
403
- force: [
404
- {
405
- segments: { and: ["web", "chrome"] },
406
- variation: "treatment",
407
- },
408
- ],
409
- },
410
- },
411
- };
412
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
413
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
414
- });
415
- test("force with OR group segments", function () {
416
- const datafile = {
417
- schemaVersion: "2",
418
- revision: "unknown",
419
- segments: {
420
- web: {
421
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
422
- },
423
- mobile: {
424
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
425
- },
426
- },
427
- features: {
428
- feature1: {
429
- bucketBy: ["userId"],
430
- traffic: [],
431
- force: [
432
- {
433
- segments: { or: ["web", "mobile"] },
434
- variation: "treatment",
435
- },
436
- ],
437
- },
438
- },
439
- };
440
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
441
- expect(result.features.feature1.force?.[0].segments).toEqual({ or: ["mobile"] });
442
- });
443
- test("force with AND conditions", function () {
444
- const datafile = {
445
- schemaVersion: "2",
446
- revision: "unknown",
447
- segments: {},
448
- features: {
449
- feature1: {
450
- bucketBy: ["userId"],
451
- traffic: [],
452
- force: [
453
- {
454
- conditions: {
455
- and: [
456
- { attribute: "platform", operator: "equals", value: "web" },
457
- { attribute: "browser", operator: "equals", value: "chrome" },
458
- ],
459
- },
460
- variation: "treatment",
461
- },
462
- ],
463
- },
464
- },
465
- };
466
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
467
- expect(result.features.feature1.force?.[0].conditions).toEqual("*");
468
- });
469
- test("force with OR conditions", function () {
470
- const datafile = {
471
- schemaVersion: "2",
472
- revision: "unknown",
473
- segments: {},
474
- features: {
475
- feature1: {
476
- bucketBy: ["userId"],
477
- traffic: [],
478
- force: [
479
- {
480
- conditions: {
481
- or: [
482
- { attribute: "platform", operator: "equals", value: "web" },
483
- { attribute: "platform", operator: "equals", value: "mobile" },
484
- ],
485
- },
486
- variation: "treatment",
487
- },
488
- ],
489
- },
490
- },
491
- };
492
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
493
- expect(result.features.feature1.force?.[0].conditions).toEqual({
494
- or: [{ attribute: "platform", operator: "equals", value: "mobile" }],
495
- });
496
- });
497
- test("multiple force entries", function () {
498
- const datafile = {
499
- schemaVersion: "2",
500
- revision: "unknown",
501
- segments: {
502
- web: {
503
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
504
- },
505
- mobile: {
506
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
507
- },
508
- },
509
- features: {
510
- feature1: {
511
- bucketBy: ["userId"],
512
- traffic: [],
513
- force: [
514
- {
515
- segments: "web",
516
- variation: "treatment",
517
- },
518
- {
519
- segments: "mobile",
520
- variation: "control",
521
- },
522
- ],
523
- },
524
- },
525
- };
526
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
527
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
528
- expect(result.features.feature1.force?.[1].segments).toEqual("mobile");
529
- });
530
- });
531
- describe("features with traffic entries", function () {
532
- test("traffic with matching segments becomes *", function () {
533
- const datafile = {
534
- schemaVersion: "2",
535
- revision: "unknown",
536
- segments: {
537
- web: {
538
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
539
- },
540
- },
541
- features: {
542
- feature1: {
543
- bucketBy: ["userId"],
544
- traffic: [
545
- {
546
- key: "rule1",
547
- segments: "web",
548
- percentage: 100000,
549
- },
550
- ],
551
- },
552
- },
553
- };
554
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
555
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
556
- });
557
- test("traffic with non-matching segments remains", function () {
558
- const datafile = {
559
- schemaVersion: "2",
560
- revision: "unknown",
561
- segments: {
562
- web: {
563
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
564
- },
565
- },
566
- features: {
567
- feature1: {
568
- bucketBy: ["userId"],
569
- traffic: [
570
- {
571
- key: "rule1",
572
- segments: "web",
573
- percentage: 100000,
574
- },
575
- ],
576
- },
577
- },
578
- };
579
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
580
- expect(result.features.feature1.traffic[0].segments).toEqual("web");
581
- });
582
- test("traffic with array of segments - all match", function () {
583
- const datafile = {
584
- schemaVersion: "2",
585
- revision: "unknown",
586
- segments: {
587
- web: {
588
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
589
- },
590
- chrome: {
591
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
592
- },
593
- },
594
- features: {
595
- feature1: {
596
- bucketBy: ["userId"],
597
- traffic: [
598
- {
599
- key: "rule1",
600
- segments: ["web", "chrome"],
601
- percentage: 100000,
602
- },
603
- ],
604
- },
605
- },
606
- };
607
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
608
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
609
- });
610
- test("traffic with array of segments - partial match", function () {
611
- const datafile = {
612
- schemaVersion: "2",
613
- revision: "unknown",
614
- segments: {
615
- web: {
616
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
617
- },
618
- chrome: {
619
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
620
- },
621
- },
622
- features: {
623
- feature1: {
624
- bucketBy: ["userId"],
625
- traffic: [
626
- {
627
- key: "rule1",
628
- segments: ["web", "chrome"],
629
- percentage: 100000,
630
- },
631
- ],
632
- },
633
- },
634
- };
635
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
636
- expect(result.features.feature1.traffic[0].segments).toEqual(["chrome"]);
637
- });
638
- test("traffic with AND group segments", function () {
639
- const datafile = {
640
- schemaVersion: "2",
641
- revision: "unknown",
642
- segments: {
643
- web: {
644
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
645
- },
646
- chrome: {
647
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
648
- },
649
- },
650
- features: {
651
- feature1: {
652
- bucketBy: ["userId"],
653
- traffic: [
654
- {
655
- key: "rule1",
656
- segments: { and: ["web", "chrome"] },
657
- percentage: 100000,
658
- },
659
- ],
660
- },
661
- },
662
- };
663
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
664
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
665
- });
666
- test("traffic with OR group segments", function () {
667
- const datafile = {
668
- schemaVersion: "2",
669
- revision: "unknown",
670
- segments: {
671
- web: {
672
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
673
- },
674
- mobile: {
675
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
676
- },
677
- },
678
- features: {
679
- feature1: {
680
- bucketBy: ["userId"],
681
- traffic: [
682
- {
683
- key: "rule1",
684
- segments: { or: ["web", "mobile"] },
685
- percentage: 100000,
686
- },
687
- ],
688
- },
689
- },
690
- };
691
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
692
- expect(result.features.feature1.traffic[0].segments).toEqual({ or: ["mobile"] });
693
- });
694
- test("multiple traffic entries", function () {
695
- const datafile = {
696
- schemaVersion: "2",
697
- revision: "unknown",
698
- segments: {
699
- web: {
700
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
701
- },
702
- mobile: {
703
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
704
- },
705
- },
706
- features: {
707
- feature1: {
708
- bucketBy: ["userId"],
709
- traffic: [
710
- {
711
- key: "rule1",
712
- segments: "web",
713
- percentage: 50000,
714
- },
715
- {
716
- key: "rule2",
717
- segments: "mobile",
718
- percentage: 50000,
719
- },
720
- ],
721
- },
722
- },
723
- };
724
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
725
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
726
- expect(result.features.feature1.traffic[1].segments).toEqual("mobile");
727
- });
728
- test("consecutive traffic entries with * segments - second is removed", function () {
729
- const datafile = {
730
- schemaVersion: "2",
731
- revision: "unknown",
732
- segments: {
733
- web: {
734
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
735
- },
736
- },
737
- features: {
738
- feature1: {
739
- bucketBy: ["userId"],
740
- traffic: [
741
- {
742
- key: "rule1",
743
- segments: "*",
744
- percentage: 50000,
745
- },
746
- {
747
- key: "rule2",
748
- segments: "*",
749
- percentage: 50000,
750
- },
751
- ],
752
- },
753
- },
754
- };
755
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
756
- expect(result.features.feature1.traffic).toHaveLength(1);
757
- expect(result.features.feature1.traffic[0].key).toEqual("rule1");
758
- });
759
- test("consecutive traffic entries with * segments - multiple consecutive removed", function () {
760
- const datafile = {
761
- schemaVersion: "2",
762
- revision: "unknown",
763
- segments: {
764
- web: {
765
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
766
- },
767
- },
768
- features: {
769
- feature1: {
770
- bucketBy: ["userId"],
771
- traffic: [
772
- {
773
- key: "rule1",
774
- segments: "*",
775
- percentage: 25000,
776
- },
777
- ],
778
- },
779
- },
780
- };
781
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
782
- expect(result.features.feature1.traffic).toHaveLength(1);
783
- expect(result.features.feature1.traffic[0].key).toEqual("rule1");
784
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
785
- });
786
- test("non-consecutive traffic entries with * segments - both remain", function () {
787
- const datafile = {
788
- schemaVersion: "2",
789
- revision: "unknown",
790
- segments: {
791
- web: {
792
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
793
- },
794
- mobile: {
795
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
796
- },
797
- },
798
- features: {
799
- feature1: {
800
- bucketBy: ["userId"],
801
- traffic: [
802
- {
803
- key: "rule1",
804
- segments: "*",
805
- percentage: 33333,
806
- },
807
- {
808
- key: "rule2",
809
- segments: "mobile",
810
- percentage: 33333,
811
- },
812
- {
813
- key: "rule3",
814
- segments: "*",
815
- percentage: 33334,
816
- },
817
- ],
818
- },
819
- },
820
- };
821
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
822
- expect(result.features.feature1.traffic).toHaveLength(3);
823
- });
824
- test("traffic entry that becomes * after scoping - consecutive removal works", function () {
825
- const datafile = {
826
- schemaVersion: "2",
827
- revision: "unknown",
828
- segments: {
829
- web: {
830
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
831
- },
832
- },
833
- features: {
834
- feature1: {
835
- bucketBy: ["userId"],
836
- traffic: [
837
- {
838
- key: "rule1",
839
- segments: "*",
840
- percentage: 50000,
841
- },
842
- {
843
- key: "rule2",
844
- segments: "web",
845
- percentage: 50000,
846
- },
847
- ],
848
- },
849
- },
850
- };
851
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
852
- expect(result.features.feature1.traffic).toHaveLength(1);
853
- expect(result.features.feature1.traffic[0].key).toEqual("rule1");
854
- });
855
- });
856
- describe("features with traffic and variableOverrides", function () {
857
- test("traffic variableOverride with matching segments becomes *", function () {
858
- const datafile = {
859
- schemaVersion: "2",
860
- revision: "unknown",
861
- segments: {
862
- mobile: {
863
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
864
- },
865
- },
866
- features: {
867
- feature1: {
868
- bucketBy: ["userId"],
869
- traffic: [
870
- {
871
- key: "rule1",
872
- segments: "*",
873
- percentage: 100000,
874
- variableOverrides: {
875
- config: [{ segments: "mobile", value: { source: "mobile" } }],
876
- },
877
- },
878
- ],
879
- },
880
- },
881
- };
882
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { device: "mobile" });
883
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].segments).toEqual("*");
884
- });
885
- test("traffic variableOverride with non-matching segments remains", function () {
886
- const datafile = {
887
- schemaVersion: "2",
888
- revision: "unknown",
889
- segments: {
890
- mobile: {
891
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
892
- },
893
- },
894
- features: {
895
- feature1: {
896
- bucketBy: ["userId"],
897
- traffic: [
898
- {
899
- key: "rule1",
900
- segments: "*",
901
- percentage: 100000,
902
- variableOverrides: {
903
- config: [{ segments: "mobile", value: { source: "mobile" } }],
904
- },
905
- },
906
- ],
907
- },
908
- },
909
- };
910
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { device: "desktop" });
911
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].segments).toEqual("mobile");
912
- });
913
- test("traffic variableOverride with matching conditions becomes *", function () {
914
- const datafile = {
915
- schemaVersion: "2",
916
- revision: "unknown",
917
- segments: {},
918
- features: {
919
- feature1: {
920
- bucketBy: ["userId"],
921
- traffic: [
922
- {
923
- key: "rule1",
924
- segments: "*",
925
- percentage: 100000,
926
- variableOverrides: {
927
- config: [
928
- {
929
- conditions: [{ attribute: "country", operator: "equals", value: "nl" }],
930
- value: { source: "nl" },
931
- },
932
- ],
933
- },
934
- },
935
- ],
936
- },
937
- },
938
- };
939
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { country: "nl" });
940
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].conditions).toEqual("*");
941
- });
942
- test("traffic variableOverride with non-matching conditions remains", function () {
943
- const datafile = {
944
- schemaVersion: "2",
945
- revision: "unknown",
946
- segments: {},
947
- features: {
948
- feature1: {
949
- bucketBy: ["userId"],
950
- traffic: [
951
- {
952
- key: "rule1",
953
- segments: "*",
954
- percentage: 100000,
955
- variableOverrides: {
956
- config: [
957
- {
958
- conditions: [{ attribute: "country", operator: "equals", value: "nl" }],
959
- value: { source: "nl" },
960
- },
961
- ],
962
- },
963
- },
964
- ],
965
- },
966
- },
967
- };
968
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { country: "de" });
969
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].conditions).toEqual([
970
- { attribute: "country", operator: "equals", value: "nl" },
971
- ]);
972
- });
973
- test("traffic variableOverride supports array/group segments and conditions", function () {
974
- const datafile = {
975
- schemaVersion: "2",
976
- revision: "unknown",
977
- segments: {
978
- mobile: {
979
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
980
- },
981
- touch: {
982
- conditions: [{ attribute: "touch", operator: "equals", value: true }],
983
- },
984
- },
985
- features: {
986
- feature1: {
987
- bucketBy: ["userId"],
988
- traffic: [
989
- {
990
- key: "rule1",
991
- segments: "*",
992
- percentage: 100000,
993
- variableOverrides: {
994
- config: [
995
- {
996
- segments: { and: ["mobile", "touch"] },
997
- value: { source: "group-segments" },
998
- },
999
- {
1000
- conditions: {
1001
- and: [
1002
- { attribute: "country", operator: "equals", value: "nl" },
1003
- { attribute: "tier", operator: "equals", value: "premium" },
1004
- ],
1005
- },
1006
- value: { source: "group-conditions" },
1007
- },
1008
- ],
1009
- },
1010
- },
1011
- ],
1012
- },
1013
- },
1014
- };
1015
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {
1016
- device: "mobile",
1017
- touch: true,
1018
- country: "nl",
1019
- tier: "premium",
1020
- });
1021
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].segments).toEqual("*");
1022
- expect(result.features.feature1.traffic[0].variableOverrides?.config[1].conditions).toEqual("*");
1023
- });
1024
- test("traffic variableOverride supports stringified segments and conditions", function () {
1025
- const datafile = {
1026
- schemaVersion: "2",
1027
- revision: "unknown",
1028
- segments: {
1029
- mobile: {
1030
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
1031
- },
1032
- touch: {
1033
- conditions: [{ attribute: "touch", operator: "equals", value: true }],
1034
- },
1035
- },
1036
- features: {
1037
- feature1: {
1038
- bucketBy: ["userId"],
1039
- traffic: [
1040
- {
1041
- key: "rule1",
1042
- segments: "*",
1043
- percentage: 100000,
1044
- variableOverrides: {
1045
- config: [
1046
- {
1047
- segments: JSON.stringify({ and: ["mobile", "touch"] }),
1048
- value: { source: "stringified-segments" },
1049
- },
1050
- {
1051
- conditions: JSON.stringify([
1052
- { attribute: "country", operator: "equals", value: "nl" },
1053
- ]),
1054
- value: { source: "stringified-conditions" },
1055
- },
1056
- ],
1057
- },
1058
- },
1059
- ],
1060
- },
1061
- },
1062
- };
1063
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {
1064
- device: "mobile",
1065
- touch: true,
1066
- country: "nl",
1067
- });
1068
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].segments).toEqual("*");
1069
- expect(result.features.feature1.traffic[0].variableOverrides?.config[1].conditions).toEqual("*");
1070
- });
1071
- test("multiple traffic entries still apply consecutive * dedupe", function () {
1072
- const datafile = {
1073
- schemaVersion: "2",
1074
- revision: "unknown",
1075
- segments: {
1076
- web: {
1077
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1078
- },
1079
- mobile: {
1080
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
1081
- },
1082
- },
1083
- features: {
1084
- feature1: {
1085
- bucketBy: ["userId"],
1086
- traffic: [
1087
- {
1088
- key: "rule1",
1089
- segments: "web",
1090
- percentage: 50000,
1091
- variableOverrides: {
1092
- config: [{ segments: "mobile", value: { source: "rule1" } }],
1093
- },
1094
- },
1095
- {
1096
- key: "rule2",
1097
- segments: "web",
1098
- percentage: 50000,
1099
- variableOverrides: {
1100
- config: [{ segments: "mobile", value: { source: "rule2" } }],
1101
- },
1102
- },
1103
- ],
1104
- },
1105
- },
1106
- };
1107
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {
1108
- platform: "web",
1109
- device: "mobile",
1110
- });
1111
- expect(result.features.feature1.traffic).toHaveLength(1);
1112
- expect(result.features.feature1.traffic[0].key).toEqual("rule1");
1113
- expect(result.features.feature1.traffic[0].variableOverrides?.config[0].segments).toEqual("*");
1114
- });
1115
- test("does not mutate original datafile traffic variableOverrides", function () {
1116
- const datafile = {
1117
- schemaVersion: "2",
1118
- revision: "unknown",
1119
- segments: {
1120
- mobile: {
1121
- conditions: [{ attribute: "device", operator: "equals", value: "mobile" }],
1122
- },
1123
- },
1124
- features: {
1125
- feature1: {
1126
- bucketBy: ["userId"],
1127
- traffic: [
1128
- {
1129
- key: "rule1",
1130
- segments: "*",
1131
- percentage: 100000,
1132
- variableOverrides: {
1133
- config: [{ segments: "mobile", value: { source: "mobile" } }],
1134
- },
1135
- },
1136
- ],
1137
- },
1138
- },
1139
- };
1140
- const original = JSON.stringify(datafile);
1141
- (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { device: "mobile" });
1142
- expect(JSON.stringify(datafile)).toEqual(original);
1143
- });
1144
- });
1145
- describe("features with variations and variableOverrides", function () {
1146
- test("variableOverride with matching segments becomes *", function () {
1147
- const datafile = {
1148
- schemaVersion: "2",
1149
- revision: "unknown",
1150
- segments: {
1151
- web: {
1152
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1153
- },
1154
- },
1155
- features: {
1156
- feature1: {
1157
- bucketBy: ["userId"],
1158
- traffic: [],
1159
- variations: [
1160
- {
1161
- value: "control",
1162
- variableOverrides: {
1163
- color: [
1164
- {
1165
- value: "red",
1166
- segments: "web",
1167
- },
1168
- ],
1169
- },
1170
- },
1171
- ],
1172
- },
1173
- },
1174
- };
1175
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1176
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1177
- });
1178
- test("variableOverride with non-matching segments remains", function () {
1179
- const datafile = {
1180
- schemaVersion: "2",
1181
- revision: "unknown",
1182
- segments: {
1183
- web: {
1184
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1185
- },
1186
- },
1187
- features: {
1188
- feature1: {
1189
- bucketBy: ["userId"],
1190
- traffic: [],
1191
- variations: [
1192
- {
1193
- value: "control",
1194
- variableOverrides: {
1195
- color: [
1196
- {
1197
- value: "red",
1198
- segments: "web",
1199
- },
1200
- ],
1201
- },
1202
- },
1203
- ],
1204
- },
1205
- },
1206
- };
1207
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
1208
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("web");
1209
- });
1210
- test("variableOverride with matching conditions becomes *", function () {
1211
- const datafile = {
1212
- schemaVersion: "2",
1213
- revision: "unknown",
1214
- segments: {},
1215
- features: {
1216
- feature1: {
1217
- bucketBy: ["userId"],
1218
- traffic: [],
1219
- variations: [
1220
- {
1221
- value: "control",
1222
- variableOverrides: {
1223
- color: [
1224
- {
1225
- value: "red",
1226
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1227
- },
1228
- ],
1229
- },
1230
- },
1231
- ],
1232
- },
1233
- },
1234
- };
1235
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1236
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].conditions).toEqual("*");
1237
- });
1238
- test("variableOverride with non-matching conditions remains", function () {
1239
- const datafile = {
1240
- schemaVersion: "2",
1241
- revision: "unknown",
1242
- segments: {},
1243
- features: {
1244
- feature1: {
1245
- bucketBy: ["userId"],
1246
- traffic: [],
1247
- variations: [
1248
- {
1249
- value: "control",
1250
- variableOverrides: {
1251
- color: [
1252
- {
1253
- value: "red",
1254
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1255
- },
1256
- ],
1257
- },
1258
- },
1259
- ],
1260
- },
1261
- },
1262
- };
1263
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile" });
1264
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].conditions).toEqual([{ attribute: "platform", operator: "equals", value: "web" }]);
1265
- });
1266
- test("variableOverride with array of segments", function () {
1267
- const datafile = {
1268
- schemaVersion: "2",
1269
- revision: "unknown",
1270
- segments: {
1271
- web: {
1272
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1273
- },
1274
- chrome: {
1275
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
1276
- },
1277
- },
1278
- features: {
1279
- feature1: {
1280
- bucketBy: ["userId"],
1281
- traffic: [],
1282
- variations: [
1283
- {
1284
- value: "control",
1285
- variableOverrides: {
1286
- color: [
1287
- {
1288
- value: "red",
1289
- segments: ["web", "chrome"],
1290
- },
1291
- ],
1292
- },
1293
- },
1294
- ],
1295
- },
1296
- },
1297
- };
1298
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1299
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1300
- });
1301
- test("variableOverride with AND group segments", function () {
1302
- const datafile = {
1303
- schemaVersion: "2",
1304
- revision: "unknown",
1305
- segments: {
1306
- web: {
1307
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1308
- },
1309
- chrome: {
1310
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
1311
- },
1312
- },
1313
- features: {
1314
- feature1: {
1315
- bucketBy: ["userId"],
1316
- traffic: [],
1317
- variations: [
1318
- {
1319
- value: "control",
1320
- variableOverrides: {
1321
- color: [
1322
- {
1323
- value: "red",
1324
- segments: { and: ["web", "chrome"] },
1325
- },
1326
- ],
1327
- },
1328
- },
1329
- ],
1330
- },
1331
- },
1332
- };
1333
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1334
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1335
- });
1336
- test("variableOverride with OR group segments", function () {
1337
- const datafile = {
1338
- schemaVersion: "2",
1339
- revision: "unknown",
1340
- segments: {
1341
- web: {
1342
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1343
- },
1344
- mobile: {
1345
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1346
- },
1347
- },
1348
- features: {
1349
- feature1: {
1350
- bucketBy: ["userId"],
1351
- traffic: [],
1352
- variations: [
1353
- {
1354
- value: "control",
1355
- variableOverrides: {
1356
- color: [
1357
- {
1358
- value: "red",
1359
- segments: { or: ["web", "mobile"] },
1360
- },
1361
- ],
1362
- },
1363
- },
1364
- ],
1365
- },
1366
- },
1367
- };
1368
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1369
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual({ or: ["mobile"] });
1370
- });
1371
- test("variableOverride with AND conditions", function () {
1372
- const datafile = {
1373
- schemaVersion: "2",
1374
- revision: "unknown",
1375
- segments: {},
1376
- features: {
1377
- feature1: {
1378
- bucketBy: ["userId"],
1379
- traffic: [],
1380
- variations: [
1381
- {
1382
- value: "control",
1383
- variableOverrides: {
1384
- color: [
1385
- {
1386
- value: "red",
1387
- conditions: {
1388
- and: [
1389
- { attribute: "platform", operator: "equals", value: "web" },
1390
- { attribute: "browser", operator: "equals", value: "chrome" },
1391
- ],
1392
- },
1393
- },
1394
- ],
1395
- },
1396
- },
1397
- ],
1398
- },
1399
- },
1400
- };
1401
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1402
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].conditions).toEqual("*");
1403
- });
1404
- test("variableOverride with OR conditions", function () {
1405
- const datafile = {
1406
- schemaVersion: "2",
1407
- revision: "unknown",
1408
- segments: {},
1409
- features: {
1410
- feature1: {
1411
- bucketBy: ["userId"],
1412
- traffic: [],
1413
- variations: [
1414
- {
1415
- value: "control",
1416
- variableOverrides: {
1417
- color: [
1418
- {
1419
- value: "red",
1420
- conditions: {
1421
- or: [
1422
- { attribute: "platform", operator: "equals", value: "web" },
1423
- { attribute: "platform", operator: "equals", value: "mobile" },
1424
- ],
1425
- },
1426
- },
1427
- ],
1428
- },
1429
- },
1430
- ],
1431
- },
1432
- },
1433
- };
1434
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1435
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].conditions).toEqual({
1436
- or: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1437
- });
1438
- });
1439
- test("multiple variableOverrides for same variable", function () {
1440
- const datafile = {
1441
- schemaVersion: "2",
1442
- revision: "unknown",
1443
- segments: {
1444
- web: {
1445
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1446
- },
1447
- mobile: {
1448
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1449
- },
1450
- },
1451
- features: {
1452
- feature1: {
1453
- bucketBy: ["userId"],
1454
- traffic: [],
1455
- variations: [
1456
- {
1457
- value: "control",
1458
- variableOverrides: {
1459
- color: [
1460
- {
1461
- value: "red",
1462
- segments: "web",
1463
- },
1464
- {
1465
- value: "blue",
1466
- segments: "mobile",
1467
- },
1468
- ],
1469
- },
1470
- },
1471
- ],
1472
- },
1473
- },
1474
- };
1475
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1476
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1477
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[1].segments).toEqual("mobile");
1478
- });
1479
- test("multiple variables with variableOverrides", function () {
1480
- const datafile = {
1481
- schemaVersion: "2",
1482
- revision: "unknown",
1483
- segments: {
1484
- web: {
1485
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1486
- },
1487
- },
1488
- features: {
1489
- feature1: {
1490
- bucketBy: ["userId"],
1491
- traffic: [],
1492
- variations: [
1493
- {
1494
- value: "control",
1495
- variableOverrides: {
1496
- color: [
1497
- {
1498
- value: "red",
1499
- segments: "web",
1500
- },
1501
- ],
1502
- size: [
1503
- {
1504
- value: "large",
1505
- segments: "web",
1506
- },
1507
- ],
1508
- },
1509
- },
1510
- ],
1511
- },
1512
- },
1513
- };
1514
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1515
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1516
- expect(result.features.feature1.variations?.[0].variableOverrides?.size[0].segments).toEqual("*");
1517
- });
1518
- test("multiple variations with variableOverrides", function () {
1519
- const datafile = {
1520
- schemaVersion: "2",
1521
- revision: "unknown",
1522
- segments: {
1523
- web: {
1524
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1525
- },
1526
- mobile: {
1527
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1528
- },
1529
- },
1530
- features: {
1531
- feature1: {
1532
- bucketBy: ["userId"],
1533
- traffic: [],
1534
- variations: [
1535
- {
1536
- value: "control",
1537
- variableOverrides: {
1538
- color: [
1539
- {
1540
- value: "red",
1541
- segments: "web",
1542
- },
1543
- ],
1544
- },
1545
- },
1546
- {
1547
- value: "treatment",
1548
- variableOverrides: {
1549
- color: [
1550
- {
1551
- value: "blue",
1552
- segments: "mobile",
1553
- },
1554
- ],
1555
- },
1556
- },
1557
- ],
1558
- },
1559
- },
1560
- };
1561
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1562
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1563
- expect(result.features.feature1.variations?.[1].variableOverrides?.color[0].segments).toEqual("mobile");
1564
- });
1565
- });
1566
- describe("complex nested scenarios", function () {
1567
- test("feature with force, traffic, and variations", function () {
1568
- const datafile = {
1569
- schemaVersion: "2",
1570
- revision: "unknown",
1571
- segments: {
1572
- web: {
1573
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1574
- },
1575
- chrome: {
1576
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
1577
- },
1578
- },
1579
- features: {
1580
- feature1: {
1581
- bucketBy: ["userId"],
1582
- traffic: [
1583
- {
1584
- key: "rule1",
1585
- segments: "web",
1586
- percentage: 100000,
1587
- },
1588
- ],
1589
- force: [
1590
- {
1591
- segments: "chrome",
1592
- variation: "treatment",
1593
- },
1594
- ],
1595
- variations: [
1596
- {
1597
- value: "control",
1598
- variableOverrides: {
1599
- color: [
1600
- {
1601
- value: "red",
1602
- segments: "web",
1603
- },
1604
- ],
1605
- },
1606
- },
1607
- ],
1608
- },
1609
- },
1610
- };
1611
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1612
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
1613
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
1614
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1615
- });
1616
- test("multiple features with different scoping results", function () {
1617
- const datafile = {
1618
- schemaVersion: "2",
1619
- revision: "unknown",
1620
- segments: {
1621
- web: {
1622
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1623
- },
1624
- mobile: {
1625
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1626
- },
1627
- },
1628
- features: {
1629
- feature1: {
1630
- bucketBy: ["userId"],
1631
- traffic: [
1632
- {
1633
- key: "rule1",
1634
- segments: "web",
1635
- percentage: 100000,
1636
- },
1637
- ],
1638
- },
1639
- feature2: {
1640
- bucketBy: ["userId"],
1641
- traffic: [
1642
- {
1643
- key: "rule1",
1644
- segments: "mobile",
1645
- percentage: 100000,
1646
- },
1647
- ],
1648
- },
1649
- },
1650
- };
1651
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1652
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
1653
- expect(result.features.feature2.traffic[0].segments).toEqual("mobile");
1654
- });
1655
- test("segment used in multiple places - all scoped correctly", function () {
1656
- const datafile = {
1657
- schemaVersion: "2",
1658
- revision: "unknown",
1659
- segments: {
1660
- web: {
1661
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1662
- },
1663
- },
1664
- features: {
1665
- feature1: {
1666
- bucketBy: ["userId"],
1667
- traffic: [
1668
- {
1669
- key: "rule1",
1670
- segments: "web",
1671
- percentage: 100000,
1672
- },
1673
- ],
1674
- force: [
1675
- {
1676
- segments: "web",
1677
- variation: "treatment",
1678
- },
1679
- ],
1680
- variations: [
1681
- {
1682
- value: "control",
1683
- variableOverrides: {
1684
- color: [
1685
- {
1686
- value: "red",
1687
- segments: "web",
1688
- },
1689
- ],
1690
- },
1691
- },
1692
- ],
1693
- },
1694
- },
1695
- };
1696
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1697
- expect(result.segments).toEqual({});
1698
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
1699
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
1700
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1701
- });
1702
- test("nested AND/OR segments in force and traffic", function () {
1703
- const datafile = {
1704
- schemaVersion: "2",
1705
- revision: "unknown",
1706
- segments: {
1707
- web: {
1708
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1709
- },
1710
- chrome: {
1711
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
1712
- },
1713
- mobile: {
1714
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1715
- },
1716
- },
1717
- features: {
1718
- feature1: {
1719
- bucketBy: ["userId"],
1720
- traffic: [
1721
- {
1722
- key: "rule1",
1723
- segments: {
1724
- and: ["web", "chrome"],
1725
- },
1726
- percentage: 100000,
1727
- },
1728
- ],
1729
- force: [
1730
- {
1731
- segments: {
1732
- or: ["web", "mobile"],
1733
- },
1734
- variation: "treatment",
1735
- },
1736
- ],
1737
- },
1738
- },
1739
- };
1740
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1741
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
1742
- expect(result.features.feature1.force?.[0].segments).toEqual({ or: ["mobile"] });
1743
- });
1744
- test("nested AND/OR conditions in force and variableOverrides", function () {
1745
- const datafile = {
1746
- schemaVersion: "2",
1747
- revision: "unknown",
1748
- segments: {},
1749
- features: {
1750
- feature1: {
1751
- bucketBy: ["userId"],
1752
- traffic: [],
1753
- force: [
1754
- {
1755
- conditions: {
1756
- and: [
1757
- { attribute: "platform", operator: "equals", value: "web" },
1758
- { attribute: "browser", operator: "equals", value: "chrome" },
1759
- ],
1760
- },
1761
- variation: "treatment",
1762
- },
1763
- ],
1764
- variations: [
1765
- {
1766
- value: "control",
1767
- variableOverrides: {
1768
- color: [
1769
- {
1770
- value: "red",
1771
- conditions: {
1772
- or: [
1773
- { attribute: "platform", operator: "equals", value: "web" },
1774
- { attribute: "platform", operator: "equals", value: "mobile" },
1775
- ],
1776
- },
1777
- },
1778
- ],
1779
- },
1780
- },
1781
- ],
1782
- },
1783
- },
1784
- };
1785
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
1786
- expect(result.features.feature1.force?.[0].conditions).toEqual("*");
1787
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].conditions).toEqual({
1788
- or: [{ attribute: "platform", operator: "equals", value: "mobile" }],
1789
- });
1790
- });
1791
- });
1792
- describe("edge cases", function () {
1793
- test("feature without force, traffic, or variations", function () {
1794
- const datafile = {
1795
- schemaVersion: "2",
1796
- revision: "unknown",
1797
- segments: {},
1798
- features: {
1799
- feature1: {
1800
- bucketBy: ["userId"],
1801
- traffic: [],
1802
- },
1803
- },
1804
- };
1805
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1806
- expect(result.features.feature1).toBeDefined();
1807
- expect(result.features.feature1.traffic).toEqual([]);
1808
- });
1809
- test("feature with empty force array", function () {
1810
- const datafile = {
1811
- schemaVersion: "2",
1812
- revision: "unknown",
1813
- segments: {},
1814
- features: {
1815
- feature1: {
1816
- bucketBy: ["userId"],
1817
- traffic: [],
1818
- force: [],
1819
- },
1820
- },
1821
- };
1822
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1823
- expect(result.features.feature1.force).toEqual([]);
1824
- });
1825
- test("feature with empty variations array", function () {
1826
- const datafile = {
1827
- schemaVersion: "2",
1828
- revision: "unknown",
1829
- segments: {},
1830
- features: {
1831
- feature1: {
1832
- bucketBy: ["userId"],
1833
- traffic: [],
1834
- variations: [],
1835
- },
1836
- },
1837
- };
1838
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1839
- expect(result.features.feature1.variations).toEqual([]);
1840
- });
1841
- test("variation without variableOverrides", function () {
1842
- const datafile = {
1843
- schemaVersion: "2",
1844
- revision: "unknown",
1845
- segments: {},
1846
- features: {
1847
- feature1: {
1848
- bucketBy: ["userId"],
1849
- traffic: [],
1850
- variations: [
1851
- {
1852
- value: "control",
1853
- },
1854
- ],
1855
- },
1856
- },
1857
- };
1858
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1859
- expect(result.features.feature1.variations?.[0].variableOverrides).toBeUndefined();
1860
- });
1861
- test("variation with empty variableOverrides object", function () {
1862
- const datafile = {
1863
- schemaVersion: "2",
1864
- revision: "unknown",
1865
- segments: {},
1866
- features: {
1867
- feature1: {
1868
- bucketBy: ["userId"],
1869
- traffic: [],
1870
- variations: [
1871
- {
1872
- value: "control",
1873
- variableOverrides: {},
1874
- },
1875
- ],
1876
- },
1877
- },
1878
- };
1879
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1880
- expect(result.features.feature1.variations?.[0].variableOverrides).toEqual({});
1881
- });
1882
- test("variableOverride with empty segments array", function () {
1883
- const datafile = {
1884
- schemaVersion: "2",
1885
- revision: "unknown",
1886
- segments: {},
1887
- features: {
1888
- feature1: {
1889
- bucketBy: ["userId"],
1890
- traffic: [],
1891
- variations: [
1892
- {
1893
- value: "control",
1894
- variableOverrides: {
1895
- color: [
1896
- {
1897
- value: "red",
1898
- segments: [],
1899
- },
1900
- ],
1901
- },
1902
- },
1903
- ],
1904
- },
1905
- },
1906
- };
1907
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1908
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
1909
- });
1910
- test("force with both segments and conditions - segments take precedence", function () {
1911
- const datafile = {
1912
- schemaVersion: "2",
1913
- revision: "unknown",
1914
- segments: {
1915
- web: {
1916
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1917
- },
1918
- },
1919
- features: {
1920
- feature1: {
1921
- bucketBy: ["userId"],
1922
- traffic: [],
1923
- force: [
1924
- {
1925
- segments: "web",
1926
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
1927
- variation: "treatment",
1928
- },
1929
- ],
1930
- },
1931
- },
1932
- };
1933
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1934
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
1935
- expect(result.features.feature1.force?.[0].conditions).toBeDefined();
1936
- });
1937
- test("traffic with * segments initially - consecutive removal still works", function () {
1938
- const datafile = {
1939
- schemaVersion: "2",
1940
- revision: "unknown",
1941
- segments: {},
1942
- features: {
1943
- feature1: {
1944
- bucketBy: ["userId"],
1945
- traffic: [
1946
- {
1947
- key: "rule1",
1948
- segments: "*",
1949
- percentage: 50000,
1950
- },
1951
- {
1952
- key: "rule2",
1953
- segments: "*",
1954
- percentage: 50000,
1955
- },
1956
- ],
1957
- },
1958
- },
1959
- };
1960
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {});
1961
- expect(result.features.feature1.traffic).toHaveLength(1);
1962
- });
1963
- test("segment that becomes * is removed even if referenced elsewhere", function () {
1964
- const datafile = {
1965
- schemaVersion: "2",
1966
- revision: "unknown",
1967
- segments: {
1968
- web: {
1969
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1970
- },
1971
- },
1972
- features: {
1973
- feature1: {
1974
- bucketBy: ["userId"],
1975
- traffic: [
1976
- {
1977
- key: "rule1",
1978
- segments: "web",
1979
- percentage: 100000,
1980
- },
1981
- ],
1982
- },
1983
- },
1984
- };
1985
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
1986
- expect(result.segments).toEqual({});
1987
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
1988
- });
1989
- test("context with extra attributes not in segments", function () {
1990
- const datafile = {
1991
- schemaVersion: "2",
1992
- revision: "unknown",
1993
- segments: {
1994
- web: {
1995
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
1996
- },
1997
- },
1998
- features: {},
1999
- };
2000
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, {
2001
- platform: "web",
2002
- extraAttribute: "extraValue",
2003
- });
2004
- expect(result.segments).toEqual({});
2005
- });
2006
- test("datafile with all segments matching context", function () {
2007
- const datafile = {
2008
- schemaVersion: "2",
2009
- revision: "unknown",
2010
- segments: {
2011
- web: {
2012
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2013
- },
2014
- chrome: {
2015
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
2016
- },
2017
- },
2018
- features: {},
2019
- };
2020
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
2021
- expect(result.segments).toEqual({});
2022
- });
2023
- test("datafile with no segments matching context", function () {
2024
- const datafile = {
2025
- schemaVersion: "2",
2026
- revision: "unknown",
2027
- segments: {
2028
- web: {
2029
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2030
- },
2031
- chrome: {
2032
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
2033
- },
2034
- },
2035
- features: {},
2036
- };
2037
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "mobile", browser: "safari" });
2038
- expect(result.segments.web).toBeDefined();
2039
- expect(result.segments.chrome).toBeDefined();
2040
- });
2041
- test("feature with multiple traffic entries becoming * consecutively", function () {
2042
- const datafile = {
2043
- schemaVersion: "2",
2044
- revision: "unknown",
2045
- segments: {
2046
- web: {
2047
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2048
- },
2049
- },
2050
- features: {
2051
- feature1: {
2052
- bucketBy: ["userId"],
2053
- traffic: [
2054
- {
2055
- key: "rule1",
2056
- segments: "web",
2057
- percentage: 25000,
2058
- },
2059
- {
2060
- key: "rule2",
2061
- segments: "web",
2062
- percentage: 25000,
2063
- },
2064
- {
2065
- key: "rule3",
2066
- segments: "web",
2067
- percentage: 25000,
2068
- },
2069
- {
2070
- key: "rule4",
2071
- segments: "web",
2072
- percentage: 25000,
2073
- },
2074
- ],
2075
- },
2076
- },
2077
- };
2078
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
2079
- expect(result.features.feature1.traffic).toHaveLength(1);
2080
- expect(result.features.feature1.traffic[0].key).toEqual("rule1");
2081
- });
2082
- test("variableOverride with segments that become * after segment removal", function () {
2083
- const datafile = {
2084
- schemaVersion: "2",
2085
- revision: "unknown",
2086
- segments: {
2087
- web: {
2088
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2089
- },
2090
- },
2091
- features: {
2092
- feature1: {
2093
- bucketBy: ["userId"],
2094
- traffic: [],
2095
- variations: [
2096
- {
2097
- value: "control",
2098
- variableOverrides: {
2099
- color: [
2100
- {
2101
- value: "red",
2102
- segments: "web",
2103
- },
2104
- ],
2105
- },
2106
- },
2107
- ],
2108
- },
2109
- },
2110
- };
2111
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
2112
- expect(result.segments).toEqual({});
2113
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
2114
- });
2115
- });
2116
- describe("integration scenarios", function () {
2117
- test("complete datafile with all feature types", function () {
2118
- const datafile = {
2119
- schemaVersion: "2",
2120
- revision: "unknown",
2121
- segments: {
2122
- web: {
2123
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2124
- },
2125
- chrome: {
2126
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
2127
- },
2128
- mobile: {
2129
- conditions: [{ attribute: "platform", operator: "equals", value: "mobile" }],
2130
- },
2131
- },
2132
- features: {
2133
- feature1: {
2134
- bucketBy: ["userId"],
2135
- traffic: [
2136
- {
2137
- key: "rule1",
2138
- segments: "web",
2139
- percentage: 100000,
2140
- },
2141
- ],
2142
- force: [
2143
- {
2144
- segments: "chrome",
2145
- variation: "treatment",
2146
- },
2147
- ],
2148
- variations: [
2149
- {
2150
- value: "control",
2151
- variableOverrides: {
2152
- color: [
2153
- {
2154
- value: "red",
2155
- segments: "web",
2156
- },
2157
- ],
2158
- },
2159
- },
2160
- ],
2161
- },
2162
- feature2: {
2163
- bucketBy: ["userId"],
2164
- traffic: [
2165
- {
2166
- key: "rule1",
2167
- segments: "mobile",
2168
- percentage: 100000,
2169
- },
2170
- ],
2171
- },
2172
- },
2173
- };
2174
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
2175
- expect(result.segments.web).toBeUndefined();
2176
- expect(result.segments.chrome).toBeUndefined();
2177
- expect(result.segments.mobile).toBeDefined();
2178
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
2179
- expect(result.features.feature1.force?.[0].segments).toEqual("*");
2180
- expect(result.features.feature1.variations?.[0].variableOverrides?.color[0].segments).toEqual("*");
2181
- expect(result.features.feature2.traffic[0].segments).toEqual("mobile");
2182
- });
2183
- test("datafile with deeply nested conditions and segments", function () {
2184
- const datafile = {
2185
- schemaVersion: "2",
2186
- revision: "unknown",
2187
- segments: {
2188
- web: {
2189
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2190
- },
2191
- chrome: {
2192
- conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
2193
- },
2194
- },
2195
- features: {
2196
- feature1: {
2197
- bucketBy: ["userId"],
2198
- traffic: [
2199
- {
2200
- key: "rule1",
2201
- segments: {
2202
- and: [
2203
- "web",
2204
- {
2205
- or: ["chrome", "web"],
2206
- },
2207
- ],
2208
- },
2209
- percentage: 100000,
2210
- },
2211
- ],
2212
- force: [
2213
- {
2214
- conditions: {
2215
- and: [
2216
- { attribute: "platform", operator: "equals", value: "web" },
2217
- {
2218
- or: [
2219
- { attribute: "browser", operator: "equals", value: "chrome" },
2220
- { attribute: "browser", operator: "equals", value: "firefox" },
2221
- ],
2222
- },
2223
- ],
2224
- },
2225
- variation: "treatment",
2226
- },
2227
- ],
2228
- },
2229
- },
2230
- };
2231
- const result = (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web", browser: "chrome" });
2232
- expect(result.features.feature1.traffic[0].segments).toEqual("*");
2233
- expect(result.features.feature1.force?.[0].conditions).toEqual({
2234
- and: [
2235
- {
2236
- or: [
2237
- {
2238
- attribute: "browser",
2239
- operator: "equals",
2240
- value: "firefox",
2241
- },
2242
- ],
2243
- },
2244
- ],
2245
- });
2246
- });
2247
- test("datafile immutability - original not modified", function () {
2248
- const datafile = {
2249
- schemaVersion: "2",
2250
- revision: "unknown",
2251
- segments: {
2252
- web: {
2253
- conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
2254
- },
2255
- },
2256
- features: {
2257
- feature1: {
2258
- bucketBy: ["userId"],
2259
- traffic: [
2260
- {
2261
- key: "rule1",
2262
- segments: "web",
2263
- percentage: 100000,
2264
- },
2265
- ],
2266
- },
2267
- },
2268
- };
2269
- const originalSegments = JSON.stringify(datafile.segments);
2270
- const originalTraffic = JSON.stringify(datafile.features.feature1.traffic);
2271
- (0, buildScopedDatafile_1.buildScopedDatafile)(datafile, { platform: "web" });
2272
- expect(JSON.stringify(datafile.segments)).toEqual(originalSegments);
2273
- expect(JSON.stringify(datafile.features.feature1.traffic)).toEqual(originalTraffic);
2274
- });
2275
- });
2276
- });
2277
- //# sourceMappingURL=buildScopedDatafile.spec.js.map