@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
@@ -5,16 +5,22 @@ import type {
5
5
  NotGroupSegment,
6
6
  Context,
7
7
  } from "@featurevisor/types";
8
- import type { DatafileReader } from "@featurevisor/sdk";
8
+ import { allSegmentsAreMatched } from "@featurevisor/sdk";
9
+ import type { Featurevisor } from "@featurevisor/sdk";
9
10
 
10
- export function buildScopedSegments(
11
- datafileReader: DatafileReader,
11
+ export function applyContextToSegments(
12
+ featurevisor: Featurevisor,
12
13
  segments: GroupSegment | GroupSegment[],
13
14
  context: Context,
14
15
  removeSegments: string[] = [],
15
16
  ): GroupSegment | GroupSegment[] {
16
- const scoped = buildScopedGroupSegments(datafileReader, segments, context, removeSegments);
17
- const removed = removeRedundantGroupSegments(scoped);
17
+ const withContextApplied = applyContextToGroupSegments(
18
+ featurevisor,
19
+ segments,
20
+ context,
21
+ removeSegments,
22
+ );
23
+ const removed = removeRedundantGroupSegments(withContextApplied);
18
24
 
19
25
  return removed;
20
26
  }
@@ -80,9 +86,13 @@ export function removeRedundantGroupSegments(
80
86
  ) as GroupSegment[];
81
87
  const filtered = processed.filter((gs) => gs !== "*");
82
88
 
83
- // If all were "*", return "*"
89
+ // `not` negates the implicit AND of its children. Matched children are true
90
+ // and can be removed: not(true && X) becomes not(X). If every child was
91
+ // true, keep not("*") so it remains an always-false expression.
84
92
  if (filtered.length === 0) {
85
- return "*";
93
+ return {
94
+ not: ["*"],
95
+ } as NotGroupSegment;
86
96
  }
87
97
 
88
98
  return {
@@ -94,8 +104,8 @@ export function removeRedundantGroupSegments(
94
104
  return groupSegments;
95
105
  }
96
106
 
97
- export function buildScopedGroupSegments(
98
- datafileReader: DatafileReader,
107
+ export function applyContextToGroupSegments(
108
+ featurevisor: Featurevisor,
99
109
  groupSegments: GroupSegment | GroupSegment[],
100
110
  context: Context,
101
111
  removeSegments: string[] = [],
@@ -106,7 +116,7 @@ export function buildScopedGroupSegments(
106
116
 
107
117
  if (Array.isArray(groupSegments)) {
108
118
  return groupSegments.map((gs) =>
109
- buildScopedGroupSegments(datafileReader, gs, context, removeSegments),
119
+ applyContextToGroupSegments(featurevisor, gs, context, removeSegments),
110
120
  ) as GroupSegment[];
111
121
  }
112
122
 
@@ -115,7 +125,9 @@ export function buildScopedGroupSegments(
115
125
  return "*";
116
126
  }
117
127
 
118
- const matched = datafileReader.allSegmentsAreMatched(groupSegments, context);
128
+ const matched = allSegmentsAreMatched(groupSegments, context, (segmentKey) =>
129
+ featurevisor.getSegment(segmentKey),
130
+ );
119
131
 
120
132
  if (matched) {
121
133
  return "*";
@@ -127,7 +139,7 @@ export function buildScopedGroupSegments(
127
139
  if ("and" in groupSegments) {
128
140
  return {
129
141
  and: groupSegments.and.map((gs) =>
130
- buildScopedGroupSegments(datafileReader, gs, context, removeSegments),
142
+ applyContextToGroupSegments(featurevisor, gs, context, removeSegments),
131
143
  ) as GroupSegment[],
132
144
  } as AndGroupSegment;
133
145
  }
@@ -135,7 +147,7 @@ export function buildScopedGroupSegments(
135
147
  if ("or" in groupSegments) {
136
148
  return {
137
149
  or: groupSegments.or.map((gs) =>
138
- buildScopedGroupSegments(datafileReader, gs, context, removeSegments),
150
+ applyContextToGroupSegments(featurevisor, gs, context, removeSegments),
139
151
  ) as GroupSegment[],
140
152
  } as OrGroupSegment;
141
153
  }
@@ -143,7 +155,7 @@ export function buildScopedGroupSegments(
143
155
  if ("not" in groupSegments) {
144
156
  return {
145
157
  not: groupSegments.not.map((gs) =>
146
- buildScopedGroupSegments(datafileReader, gs, context, removeSegments),
158
+ applyContextToGroupSegments(featurevisor, gs, context, removeSegments),
147
159
  ) as GroupSegment[],
148
160
  } as NotGroupSegment;
149
161
  }
@@ -2,11 +2,12 @@ import * as fs from "fs";
2
2
  import * as os from "os";
3
3
  import * as path from "path";
4
4
 
5
- import type { DatafileContent, ExistingState, ParsedFeature } from "@featurevisor/types";
5
+ import type { DatafileContent, ExistingState, ParsedFeature, Segment } from "@featurevisor/types";
6
6
  import { parsers } from "@featurevisor/parsers";
7
7
 
8
8
  import type { ProjectConfig } from "../config";
9
9
  import { buildDatafile } from "./buildDatafile";
10
+ import { buildTargetDatafile } from "./buildProject";
10
11
 
11
12
  function createProjectConfig(root: string, stringify = true): ProjectConfig {
12
13
  return {
@@ -15,17 +16,18 @@ function createProjectConfig(root: string, stringify = true): ProjectConfig {
15
16
  attributesDirectoryPath: path.join(root, "attributes-missing"),
16
17
  groupsDirectoryPath: path.join(root, "groups-missing"),
17
18
  schemasDirectoryPath: path.join(root, "schemas-missing"),
19
+ targetsDirectoryPath: path.join(root, "targets-missing"),
18
20
  testsDirectoryPath: path.join(root, "tests-missing"),
19
21
  stateDirectoryPath: path.join(root, ".featurevisor"),
20
22
  datafilesDirectoryPath: path.join(root, "datafiles"),
21
23
  datafileNamePattern: "featurevisor-%s.json",
22
24
  revisionFileName: "REVISION",
23
- siteExportDirectoryPath: path.join(root, "out"),
24
- environmentsDirectoryPath: path.join(root, "environments"),
25
+ catalogDirectoryPath: path.join(root, "catalog"),
26
+ setsDirectoryPath: path.join(root, "sets"),
25
27
  environments: ["staging", "production"],
26
- splitByEnvironment: false,
28
+ sets: false,
29
+ namespaceCharacter: ".",
27
30
  tags: ["all"],
28
- scopes: [],
29
31
  adapter: {},
30
32
  plugins: [],
31
33
  defaultBucketBy: "userId",
@@ -37,18 +39,33 @@ function createProjectConfig(root: string, stringify = true): ProjectConfig {
37
39
  };
38
40
  }
39
41
 
40
- function createMockDatasource(feature: ParsedFeature) {
42
+ function isParsedFeature(
43
+ feature: ParsedFeature | Record<string, ParsedFeature>,
44
+ ): feature is ParsedFeature {
45
+ return typeof (feature as ParsedFeature).description === "string";
46
+ }
47
+
48
+ function createMockDatasource(
49
+ feature: ParsedFeature | Record<string, ParsedFeature>,
50
+ segmentsByKey: Record<string, Segment> = {},
51
+ ) {
52
+ let featuresByKey: Record<string, ParsedFeature>;
53
+
54
+ if (isParsedFeature(feature)) {
55
+ featuresByKey = { [feature.key]: feature };
56
+ } else {
57
+ featuresByKey = feature;
58
+ }
59
+
41
60
  return {
42
61
  listSchemas: async () => [],
43
62
  readSchema: async () => {
44
63
  throw new Error("readSchema should not be called");
45
64
  },
46
- listFeatures: async () => ["withRuleOverrides"],
47
- readFeature: async () => feature,
48
- listSegments: async () => [],
49
- readSegment: async () => {
50
- throw new Error("readSegment should not be called");
51
- },
65
+ listFeatures: async () => Object.keys(featuresByKey),
66
+ readFeature: async (key: string) => featuresByKey[key],
67
+ listSegments: async () => Object.keys(segmentsByKey),
68
+ readSegment: async (key: string) => segmentsByKey[key],
52
69
  listAttributes: async () => [],
53
70
  readAttribute: async () => {
54
71
  throw new Error("readAttribute should not be called");
@@ -162,6 +179,7 @@ describe("core: buildDatafile", function () {
162
179
  beforeEach(function () {
163
180
  root = fs.mkdtempSync(path.join(os.tmpdir(), "featurevisor-buildDatafile-"));
164
181
  fs.mkdirSync(path.join(root, "features"), { recursive: true });
182
+ fs.mkdirSync(path.join(root, "segments-missing"), { recursive: true });
165
183
  existingState = { features: {} };
166
184
  });
167
185
 
@@ -177,13 +195,14 @@ describe("core: buildDatafile", function () {
177
195
  config,
178
196
  datasource,
179
197
  {
180
- schemaVersion: "2",
181
198
  revision: "1",
182
199
  environment: "staging",
183
200
  },
184
201
  existingState,
185
202
  )) as DatafileContent;
186
203
 
204
+ expect(result.schemaVersion).toBe("2");
205
+
187
206
  const trafficRule = result.features.withRuleOverrides.traffic.find((t) => t.key === "rule1");
188
207
 
189
208
  expect(trafficRule).toBeDefined();
@@ -248,7 +267,6 @@ describe("core: buildDatafile", function () {
248
267
  config,
249
268
  datasource,
250
269
  {
251
- schemaVersion: "2",
252
270
  revision: "1",
253
271
  environment: "staging",
254
272
  },
@@ -264,4 +282,164 @@ describe("core: buildDatafile", function () {
264
282
  { attribute: "country", operator: "equals", value: "de" },
265
283
  ]);
266
284
  });
285
+
286
+ test("includes features with missing tags when no tag filter is provided", async function () {
287
+ const config = createProjectConfig(root, true);
288
+ const feature = createFeatureFixture();
289
+ delete feature.tags;
290
+ const datasource = createMockDatasource(feature);
291
+
292
+ const result = (await buildDatafile(
293
+ config,
294
+ datasource,
295
+ {
296
+ revision: "1",
297
+ environment: "staging",
298
+ },
299
+ existingState,
300
+ )) as DatafileContent;
301
+
302
+ expect(result.features.withRuleOverrides).toBeDefined();
303
+ });
304
+
305
+ test("excludes features with missing tags when tag filter is provided", async function () {
306
+ const config = createProjectConfig(root, true);
307
+ const feature = createFeatureFixture();
308
+ delete feature.tags;
309
+ const datasource = createMockDatasource(feature);
310
+
311
+ const result = (await buildDatafile(
312
+ config,
313
+ datasource,
314
+ {
315
+ revision: "1",
316
+ environment: "staging",
317
+ tag: "all",
318
+ },
319
+ existingState,
320
+ )) as DatafileContent;
321
+
322
+ expect(result.features.withRuleOverrides).toBeUndefined();
323
+ });
324
+
325
+ test("filters target features by include/exclude patterns and combines them with tags using AND", async function () {
326
+ const config = createProjectConfig(root, true);
327
+ const createFeature = (key: string, tags: string[]) => ({
328
+ ...createFeatureFixture(),
329
+ key,
330
+ description: key,
331
+ tags,
332
+ });
333
+ const datasource = createMockDatasource({
334
+ "checkout.web": createFeature("checkout.web", ["all", "web"]),
335
+ "checkout.mobile": createFeature("checkout.mobile", ["all", "mobile"]),
336
+ "admin.web": createFeature("admin.web", ["all", "web"]),
337
+ "admin.internal": createFeature("admin.internal", ["all", "web"]),
338
+ });
339
+
340
+ const filtered = await buildTargetDatafile({
341
+ projectConfig: config,
342
+ datasource,
343
+ target: {
344
+ description: "Selected web features",
345
+ tag: "web",
346
+ includeFeatures: ["checkout*", "admin*"],
347
+ excludeFeatures: ["admin.internal"],
348
+ },
349
+ environment: "staging",
350
+ existingState,
351
+ revision: "1",
352
+ });
353
+
354
+ expect(Object.keys(filtered.features).sort()).toEqual(["admin.web", "checkout.web"]);
355
+
356
+ const all = await buildTargetDatafile({
357
+ projectConfig: config,
358
+ datasource,
359
+ target: {
360
+ description: "All except admin features",
361
+ includeFeatures: "*",
362
+ excludeFeatures: ["admin*"],
363
+ },
364
+ environment: "staging",
365
+ existingState,
366
+ revision: "1",
367
+ });
368
+
369
+ expect(Object.keys(all.features).sort()).toEqual(["checkout.mobile", "checkout.web"]);
370
+ });
371
+
372
+ test("builds target datafiles without broadening NOT segment rules", async function () {
373
+ const config = createProjectConfig(root, false);
374
+ const feature: ParsedFeature = {
375
+ key: "targeted",
376
+ description: "Targeted feature",
377
+ tags: ["all"],
378
+ bucketBy: "userId",
379
+ rules: {
380
+ staging: [
381
+ {
382
+ key: "not-web",
383
+ segments: {
384
+ not: ["web"],
385
+ },
386
+ percentage: 100,
387
+ },
388
+ {
389
+ key: "not-web-and-chrome",
390
+ segments: {
391
+ not: ["web", "chrome"],
392
+ },
393
+ percentage: 100,
394
+ },
395
+ ],
396
+ },
397
+ } as ParsedFeature;
398
+ const datasource = createMockDatasource(feature, {
399
+ web: {
400
+ conditions: [{ attribute: "platform", operator: "equals", value: "web" }],
401
+ },
402
+ chrome: {
403
+ conditions: [{ attribute: "browser", operator: "equals", value: "chrome" }],
404
+ },
405
+ });
406
+
407
+ const webDatafile = await buildTargetDatafile({
408
+ projectConfig: config,
409
+ datasource,
410
+ target: {
411
+ description: "Web target",
412
+ context: { platform: "web" },
413
+ },
414
+ environment: "staging",
415
+ existingState,
416
+ revision: "1",
417
+ });
418
+
419
+ expect(webDatafile.features.targeted.traffic[0].segments).toEqual({
420
+ not: ["*"],
421
+ });
422
+ expect(webDatafile.features.targeted.traffic[1].segments).toEqual({
423
+ not: ["chrome"],
424
+ });
425
+
426
+ const webChromeDatafile = await buildTargetDatafile({
427
+ projectConfig: config,
428
+ datasource,
429
+ target: {
430
+ description: "Web Chrome target",
431
+ context: { platform: "web", browser: "chrome" },
432
+ },
433
+ environment: "staging",
434
+ existingState,
435
+ revision: "1",
436
+ });
437
+
438
+ expect(webChromeDatafile.features.targeted.traffic[0].segments).toEqual({
439
+ not: ["*"],
440
+ });
441
+ expect(webChromeDatafile.features.targeted.traffic[1].segments).toEqual({
442
+ not: ["*"],
443
+ });
444
+ });
267
445
  });
@@ -5,7 +5,6 @@ import {
5
5
  Segment,
6
6
  Feature,
7
7
  DatafileContent,
8
- DatafileContentV1,
9
8
  Variation,
10
9
  VariableOverride,
11
10
  Traffic,
@@ -22,14 +21,13 @@ import {
22
21
  Force,
23
22
  } from "@featurevisor/types";
24
23
 
25
- import { ProjectConfig, SCHEMA_VERSION } from "../config";
24
+ import { ProjectConfig } from "../config";
26
25
  import { Datasource } from "../datasource";
27
26
  import { extractAttributeKeysFromConditions, extractSegmentKeysFromGroupSegments } from "../utils";
28
27
  import { generateHashForDatafile, generateHashForFeature, getSegmentHashes } from "./hashes";
29
28
 
30
29
  import { getTraffic } from "./traffic";
31
30
  import { getFeatureRanges } from "./getFeatureRanges";
32
- import { convertToV1 } from "./convertToV1";
33
31
  import {
34
32
  resolveMutationsForMultipleVariables,
35
33
  resolveMutationsForSingleVariable,
@@ -37,19 +35,19 @@ import {
37
35
 
38
36
  export interface CustomDatafileOptions {
39
37
  featureKey?: string;
40
- environment: string;
38
+ environment: string | false;
41
39
  projectConfig: ProjectConfig;
42
40
  datasource: Datasource;
43
41
  revision?: string;
44
- schemaVersion?: string;
45
42
  inflate?: number;
46
43
  tag?: string;
47
44
  tags?: BuildTags;
45
+ includeFeatures?: "*" | FeatureKey[];
46
+ excludeFeatures?: "*" | FeatureKey[];
47
+ featurevisorVersion?: string;
48
48
  }
49
49
 
50
- export async function getCustomDatafile(
51
- options: CustomDatafileOptions,
52
- ): Promise<DatafileContent | DatafileContentV1> {
50
+ export async function getCustomDatafile(options: CustomDatafileOptions): Promise<DatafileContent> {
53
51
  let featuresToInclude;
54
52
 
55
53
  if (options.featureKey) {
@@ -62,13 +60,15 @@ export async function getCustomDatafile(
62
60
  options.projectConfig,
63
61
  options.datasource,
64
62
  {
65
- schemaVersion: options.schemaVersion || SCHEMA_VERSION,
66
63
  revision: options.revision || "tester",
67
64
  environment: options.environment,
68
65
  features: featuresToInclude,
69
66
  inflate: options.inflate,
70
67
  tag: options.tag,
71
68
  tags: options.tags,
69
+ includeFeatures: options.includeFeatures,
70
+ excludeFeatures: options.excludeFeatures,
71
+ featurevisorVersion: options.featurevisorVersion,
72
72
  },
73
73
  existingState,
74
74
  );
@@ -86,14 +86,48 @@ export interface BuildAndTags {
86
86
 
87
87
  export type BuildTags = BuildOrTags | BuildAndTags | string[];
88
88
 
89
+ function matchesBuildTags(candidateTags: string[], buildTags?: BuildTags): boolean {
90
+ if (!buildTags) {
91
+ return true;
92
+ }
93
+
94
+ if (Array.isArray(buildTags)) {
95
+ return buildTags.some((searchTag) => candidateTags.indexOf(searchTag) !== -1);
96
+ }
97
+
98
+ if ("or" in buildTags) {
99
+ return buildTags.or.some((searchTag) => candidateTags.indexOf(searchTag) !== -1);
100
+ }
101
+
102
+ if ("and" in buildTags) {
103
+ return buildTags.and.every((searchTag) => candidateTags.indexOf(searchTag) !== -1);
104
+ }
105
+
106
+ return true;
107
+ }
108
+
109
+ function matchesFeaturePatterns(featureKey: FeatureKey, patterns?: "*" | FeatureKey[]): boolean {
110
+ if (!patterns) {
111
+ return false;
112
+ }
113
+
114
+ const normalizedPatterns = patterns === "*" ? [patterns] : patterns;
115
+
116
+ return normalizedPatterns.some((pattern) => {
117
+ const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
118
+ return new RegExp(`^${escaped}$`).test(featureKey);
119
+ });
120
+ }
121
+
89
122
  export interface BuildOptions {
90
- schemaVersion: string;
91
123
  revision: string;
92
124
  featurevisorVersion?: string;
93
125
  revisionFromHash?: boolean;
94
126
  environment: string | false;
95
127
  tag?: string;
96
128
  tags?: BuildTags;
129
+ includeFeatures?: "*" | FeatureKey[];
130
+ excludeFeatures?: "*" | FeatureKey[];
97
131
  features?: FeatureKey[];
98
132
  inflate?: number;
99
133
  }
@@ -103,7 +137,7 @@ export async function buildDatafile(
103
137
  datasource: Datasource,
104
138
  options: BuildOptions,
105
139
  existingState: ExistingState,
106
- ): Promise<DatafileContent | DatafileContentV1> {
140
+ ): Promise<DatafileContent> {
107
141
  const segmentKeysUsedByTag = new Set<SegmentKey>();
108
142
  const attributeKeysUsedByTag = new Set<AttributeKey>();
109
143
  const { featureRanges, featureIsInGroup } = await getFeatureRanges(projectConfig, datasource);
@@ -133,40 +167,25 @@ export async function buildDatafile(
133
167
  continue;
134
168
  }
135
169
 
136
- if (options.tag && parsedFeature.tags.indexOf(options.tag) === -1) {
170
+ const featureTags = parsedFeature.tags || [];
171
+
172
+ if (options.tag && featureTags.indexOf(options.tag) === -1) {
137
173
  continue;
138
174
  }
139
175
 
140
- if (options.tags) {
141
- // plain array of tags: treat as OR tags
142
- if (Array.isArray(options.tags)) {
143
- if (
144
- options.tags.some((searchTag) => parsedFeature.tags.indexOf(searchTag) !== -1) === false
145
- ) {
146
- continue;
147
- }
148
- } else {
149
- // OR tags
150
- const orTags = options.tags as BuildOrTags;
151
- if (orTags.or) {
152
- if (
153
- orTags.or.some((searchTag) => parsedFeature.tags.indexOf(searchTag) !== -1) === false
154
- ) {
155
- continue;
156
- }
157
- }
176
+ if (options.tags && matchesBuildTags(featureTags, options.tags) === false) {
177
+ continue;
178
+ }
158
179
 
159
- // AND tags
160
- const andTags = options.tags as BuildAndTags;
161
- if (andTags.and) {
162
- if (
163
- andTags.and.every((searchTag) => parsedFeature.tags.indexOf(searchTag) !== -1) ===
164
- false
165
- ) {
166
- continue;
167
- }
168
- }
169
- }
180
+ if (
181
+ options.includeFeatures &&
182
+ matchesFeaturePatterns(featureKey, options.includeFeatures) === false
183
+ ) {
184
+ continue;
185
+ }
186
+
187
+ if (options.excludeFeatures && matchesFeaturePatterns(featureKey, options.excludeFeatures)) {
188
+ continue;
170
189
  }
171
190
 
172
191
  if (options.features && options.features.indexOf(featureKey) === -1) {
@@ -197,6 +216,10 @@ export async function buildDatafile(
197
216
  if (options.tag && exposeTags.indexOf(options.tag) === -1) {
198
217
  continue;
199
218
  }
219
+
220
+ if (options.tags && matchesBuildTags(exposeTags, options.tags) === false) {
221
+ continue;
222
+ }
200
223
  }
201
224
 
202
225
  for (const parsedRule of rules) {
@@ -569,19 +592,7 @@ export async function buildDatafile(
569
592
  }
570
593
  }
571
594
 
572
- // schema v1
573
- if (options.schemaVersion === "1") {
574
- return convertToV1({
575
- revision: options.revision,
576
- projectConfig,
577
- attributes,
578
- features,
579
- segments,
580
- });
581
- }
582
-
583
- // schema v2
584
- const datafileContentV2: DatafileContent = {
595
+ const datafileContent: DatafileContent = {
585
596
  schemaVersion: "2",
586
597
  featurevisorVersion: options.featurevisorVersion,
587
598
  revision: options.revision,
@@ -589,8 +600,7 @@ export async function buildDatafile(
589
600
  features: {},
590
601
  };
591
602
 
592
- datafileContentV2.segments = segments.reduce((acc, segment) => {
593
- // key check needed for supporting v1 datafile generation
603
+ datafileContent.segments = segments.reduce((acc, segment) => {
594
604
  if (segment.key) {
595
605
  acc[segment.key] = segment;
596
606
  delete acc[segment.key].key; // remove key from segment, as it is not needed in v2 datafile
@@ -599,7 +609,7 @@ export async function buildDatafile(
599
609
  return acc;
600
610
  }, {});
601
611
 
602
- datafileContentV2.features = features.reduce((acc, feature) => {
612
+ datafileContent.features = features.reduce((acc, feature) => {
603
613
  if (!feature.key) {
604
614
  return acc;
605
615
  }
@@ -625,11 +635,11 @@ export async function buildDatafile(
625
635
  }, {});
626
636
 
627
637
  // add feature hashes for change detection
628
- const segmentHashes = getSegmentHashes(datafileContentV2.segments);
629
- Object.keys(datafileContentV2.features).forEach((featureKey) => {
630
- const hash = generateHashForFeature(featureKey, datafileContentV2.features, segmentHashes);
638
+ const segmentHashes = getSegmentHashes(datafileContent.segments);
639
+ Object.keys(datafileContent.features).forEach((featureKey) => {
640
+ const hash = generateHashForFeature(featureKey, datafileContent.features, segmentHashes);
631
641
 
632
- datafileContentV2.features[featureKey].hash = hash;
642
+ datafileContent.features[featureKey].hash = hash;
633
643
 
634
644
  // check needed to support --inflate option
635
645
  if (existingState.features[featureKey]) {
@@ -638,9 +648,9 @@ export async function buildDatafile(
638
648
  });
639
649
 
640
650
  if (options.revisionFromHash) {
641
- const datafileHash = generateHashForDatafile(datafileContentV2);
642
- datafileContentV2.revision = `${datafileHash}`;
651
+ const datafileHash = generateHashForDatafile(datafileContent);
652
+ datafileContent.revision = `${datafileHash}`;
643
653
  }
644
654
 
645
- return datafileContentV2;
655
+ return datafileContent;
646
656
  }