@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,6 +1,7 @@
1
1
  import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import { execSync, spawn } from "child_process";
4
+ import { gzipSync } from "zlib";
4
5
 
5
6
  import type {
6
7
  ExistingState,
@@ -11,28 +12,13 @@ import type {
11
12
  Commit,
12
13
  CommitHash,
13
14
  HistoryEntity,
14
- ParsedFeature,
15
- Expose,
16
- Force,
17
- Rule,
18
15
  } from "@featurevisor/types";
19
16
  import type { CustomParser } from "@featurevisor/parsers";
20
17
 
21
- import { Adapter, DatafileOptions } from "./adapter";
18
+ import { Adapter, DatafileFile, DatafileOptions } from "./adapter";
22
19
  import { ProjectConfig } from "../config";
23
20
  import { getCommit } from "../utils/git";
24
-
25
- const FEATURE_ENVIRONMENT_ALLOWED_KEYS = ["rules", "force", "expose"];
26
-
27
- class FeatureSplitConfigError extends Error {
28
- featurevisorFilePath: string;
29
-
30
- constructor(filePath: string, message: string) {
31
- super(message);
32
- this.featurevisorFilePath = filePath;
33
- this.name = "FeatureSplitConfigError";
34
- }
35
- }
21
+ import { CLI_COLOR_CYAN, CLI_COLOR_GREEN, colorize } from "../tester/cliFormat";
36
22
 
37
23
  export function getExistingStateFilePath(
38
24
  projectConfig: ProjectConfig,
@@ -47,7 +33,7 @@ export function getRevisionFilePath(projectConfig: ProjectConfig): string {
47
33
  return path.join(projectConfig.stateDirectoryPath, projectConfig.revisionFileName);
48
34
  }
49
35
 
50
- export function getAllEntityFilePathsRecursively(directoryPath, extension) {
36
+ export function getAllEntityFilePathsRecursively(directoryPath, extension?: string) {
51
37
  let entities: string[] = [];
52
38
 
53
39
  if (!fs.existsSync(directoryPath)) {
@@ -62,7 +48,7 @@ export function getAllEntityFilePathsRecursively(directoryPath, extension) {
62
48
 
63
49
  if (fs.statSync(filePath).isDirectory()) {
64
50
  entities = entities.concat(getAllEntityFilePathsRecursively(filePath, extension));
65
- } else if (file.endsWith(`.${extension}`)) {
51
+ } else if (!extension || file.endsWith(`.${extension}`)) {
66
52
  entities.push(filePath);
67
53
  }
68
54
  }
@@ -76,6 +62,26 @@ function isWithinDirectory(directoryPath: string, fileDirectoryPath: string): bo
76
62
  );
77
63
  }
78
64
 
65
+ function getPathSegmentsFromKey(
66
+ namespaceCharacter: string,
67
+ key: string,
68
+ entityType?: EntityType,
69
+ ): string[] {
70
+ const pathSegments = namespaceCharacter ? key.split(namespaceCharacter) : [key];
71
+
72
+ if (
73
+ entityType === "test" &&
74
+ pathSegments.length > 1 &&
75
+ ["spec", "feature", "segment"].includes(pathSegments[pathSegments.length - 1])
76
+ ) {
77
+ const suffix = pathSegments[pathSegments.length - 1];
78
+ pathSegments[pathSegments.length - 2] = `${pathSegments[pathSegments.length - 2]}.${suffix}`;
79
+ pathSegments.pop();
80
+ }
81
+
82
+ return pathSegments;
83
+ }
84
+
79
85
  export class FilesystemAdapter extends Adapter {
80
86
  private parser: CustomParser;
81
87
 
@@ -97,6 +103,8 @@ export class FilesystemAdapter extends Adapter {
97
103
  return this.config.segmentsDirectoryPath;
98
104
  } else if (entityType === "schema") {
99
105
  return this.config.schemasDirectoryPath;
106
+ } else if (entityType === "target") {
107
+ return this.config.targetsDirectoryPath;
100
108
  } else if (entityType === "test") {
101
109
  return this.config.testsDirectoryPath;
102
110
  }
@@ -104,64 +112,29 @@ export class FilesystemAdapter extends Adapter {
104
112
  return this.config.attributesDirectoryPath;
105
113
  }
106
114
 
107
- getEntityPath(entityType: EntityType, entityKey: string): string {
108
- const basePath = this.getEntityDirectoryPath(entityType);
115
+ async listSets(): Promise<string[]> {
116
+ if (!this.config.sets || !fs.existsSync(this.config.setsDirectoryPath)) {
117
+ return [];
118
+ }
109
119
 
110
- // taking care of windows paths
111
- const relativeEntityPath = entityKey.replace(/\//g, path.sep);
120
+ const entries = await fs.promises.readdir(this.config.setsDirectoryPath, {
121
+ withFileTypes: true,
122
+ });
112
123
 
113
- return path.join(basePath, `${relativeEntityPath}.${this.parser.extension}`);
124
+ return entries
125
+ .filter((entry) => entry.isDirectory())
126
+ .map((entry) => entry.name)
127
+ .sort();
114
128
  }
115
129
 
116
- getFeatureEnvironmentPath(featureKey: string, environment: string): string {
117
- const relativeEntityPath = featureKey.replace(/\//g, path.sep);
118
-
119
- return path.join(
120
- this.config.environmentsDirectoryPath,
121
- environment,
122
- `${relativeEntityPath}.${this.parser.extension}`,
130
+ getEntityPath(entityType: EntityType, entityKey: string): string {
131
+ const basePath = this.getEntityDirectoryPath(entityType);
132
+ const pathSegments = getPathSegmentsFromKey(
133
+ this.config.namespaceCharacter,
134
+ entityKey,
135
+ entityType,
123
136
  );
124
- }
125
-
126
- private assertSplitByEnvironmentIsValidFeatureBase(
127
- baseFeature: ParsedFeature,
128
- featurePath: string,
129
- ) {
130
- if (
131
- typeof baseFeature.rules !== "undefined" ||
132
- typeof baseFeature.force !== "undefined" ||
133
- typeof baseFeature.expose !== "undefined"
134
- ) {
135
- throw new FeatureSplitConfigError(
136
- featurePath,
137
- `Feature "${baseFeature.key}" base file must not define rules, force, or expose when splitByEnvironment=true`,
138
- );
139
- }
140
- }
141
-
142
- private readFeatureEnvironmentEntity(featureKey: string, environment: string) {
143
- const featureEnvironmentPath = this.getFeatureEnvironmentPath(featureKey, environment);
144
-
145
- if (!fs.existsSync(featureEnvironmentPath)) {
146
- throw new FeatureSplitConfigError(
147
- featureEnvironmentPath,
148
- `Missing environment feature file: environments/${environment}/${featureKey}.${this.parser.extension}`,
149
- );
150
- }
151
-
152
- const content = fs.readFileSync(featureEnvironmentPath, "utf8");
153
- const parsed = this.parser.parse<Record<string, unknown>>(content, featureEnvironmentPath);
154
- const keys = Object.keys(parsed);
155
- const unknownKeys = keys.filter((key) => FEATURE_ENVIRONMENT_ALLOWED_KEYS.indexOf(key) === -1);
156
-
157
- if (unknownKeys.length > 0) {
158
- throw new FeatureSplitConfigError(
159
- featureEnvironmentPath,
160
- `Unknown key(s) in environment feature file: ${unknownKeys.join(", ")}`,
161
- );
162
- }
163
-
164
- return parsed;
137
+ return path.join(basePath, ...pathSegments) + `.${this.parser.extension}`;
165
138
  }
166
139
 
167
140
  async listEntities(entityType: EntityType): Promise<string[]> {
@@ -179,8 +152,8 @@ export class FilesystemAdapter extends Adapter {
179
152
  // remove the extension from the end
180
153
  .map((filterPath) => filterPath.replace(`.${this.parser.extension}`, ""))
181
154
 
182
- // take care of windows paths
183
- .map((filterPath) => filterPath.replace(/\\/g, "/"))
155
+ // take care of windows paths and apply namespace character
156
+ .map((filterPath) => filterPath.split(path.sep).join(this.config.namespaceCharacter))
184
157
  );
185
158
  }
186
159
 
@@ -191,50 +164,6 @@ export class FilesystemAdapter extends Adapter {
191
164
  }
192
165
 
193
166
  async readEntity<T>(entityType: EntityType, entityKey: string): Promise<T> {
194
- if (entityType === "feature" && this.config.splitByEnvironment) {
195
- const featurePath = this.getEntityPath(entityType, entityKey);
196
- const featureContent = fs.readFileSync(featurePath, "utf8");
197
- const baseFeature = this.parser.parse<ParsedFeature>(featureContent, featurePath);
198
-
199
- this.assertSplitByEnvironmentIsValidFeatureBase(baseFeature, featurePath);
200
-
201
- if (!Array.isArray(this.config.environments)) {
202
- throw new FeatureSplitConfigError(
203
- featurePath,
204
- "splitByEnvironment=true requires environments to be configured as an array",
205
- );
206
- }
207
-
208
- const rulesByEnvironment: Record<string, Rule[]> = {};
209
- const forceByEnvironment: Record<string, Force[]> = {};
210
- const exposeByEnvironment: Record<string, Expose> = {};
211
-
212
- for (const environment of this.config.environments) {
213
- const envFeature = this.readFeatureEnvironmentEntity(entityKey, environment);
214
-
215
- if (typeof envFeature.rules !== "undefined") {
216
- rulesByEnvironment[environment] = envFeature.rules as Rule[];
217
- }
218
-
219
- if (typeof envFeature.force !== "undefined") {
220
- forceByEnvironment[environment] = envFeature.force as Force[];
221
- }
222
-
223
- if (typeof envFeature.expose !== "undefined") {
224
- exposeByEnvironment[environment] = envFeature.expose as Expose;
225
- }
226
- }
227
-
228
- const mergedFeature: ParsedFeature = {
229
- ...baseFeature,
230
- rules: Object.keys(rulesByEnvironment).length > 0 ? rulesByEnvironment : undefined,
231
- force: Object.keys(forceByEnvironment).length > 0 ? forceByEnvironment : undefined,
232
- expose: Object.keys(exposeByEnvironment).length > 0 ? exposeByEnvironment : undefined,
233
- };
234
-
235
- return mergedFeature as T;
236
- }
237
-
238
167
  const filePath = this.getEntityPath(entityType, entityKey);
239
168
  const entityContent = fs.readFileSync(filePath, "utf8");
240
169
 
@@ -244,8 +173,8 @@ export class FilesystemAdapter extends Adapter {
244
173
  async writeEntity<T>(entityType: EntityType, entityKey: string, entity: T): Promise<T> {
245
174
  const filePath = this.getEntityPath(entityType, entityKey);
246
175
 
247
- if (!fs.existsSync(this.getEntityDirectoryPath(entityType))) {
248
- fs.mkdirSync(this.getEntityDirectoryPath(entityType), { recursive: true });
176
+ if (!fs.existsSync(path.dirname(filePath))) {
177
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
249
178
  }
250
179
 
251
180
  fs.writeFileSync(filePath, this.parser.stringify(entity, filePath));
@@ -290,8 +219,6 @@ export class FilesystemAdapter extends Adapter {
290
219
  ? JSON.stringify(existingState, null, 2)
291
220
  : JSON.stringify(existingState),
292
221
  );
293
-
294
- fs.writeFileSync(filePath, JSON.stringify(existingState, null, 2));
295
222
  }
296
223
 
297
224
  /**
@@ -304,20 +231,7 @@ export class FilesystemAdapter extends Adapter {
304
231
  return fs.readFileSync(filePath, "utf8");
305
232
  }
306
233
 
307
- // maintain backwards compatibility
308
- try {
309
- const pkg = require(path.join(this.rootDirectoryPath as string, "package.json"));
310
- const pkgVersion = pkg.version;
311
-
312
- if (pkgVersion) {
313
- return pkgVersion;
314
- }
315
-
316
- return "0";
317
- // eslint-disable-next-line
318
- } catch (e) {
319
- return "0";
320
- }
234
+ return "0";
321
235
  }
322
236
 
323
237
  async writeRevision(revision: string): Promise<void> {
@@ -340,20 +254,43 @@ export class FilesystemAdapter extends Adapter {
340
254
  /**
341
255
  * Datafile
342
256
  */
257
+ async listDatafiles(): Promise<DatafileFile[]> {
258
+ const directoryPath = this.config.datafilesDirectoryPath;
259
+
260
+ return getAllEntityFilePathsRecursively(directoryPath)
261
+ .filter((filePath) => path.basename(filePath) !== this.config.revisionFileName)
262
+ .filter((filePath) => !path.basename(filePath).startsWith("."))
263
+ .map((filePath) => {
264
+ const content = fs.readFileSync(filePath);
265
+
266
+ return {
267
+ path: path.relative(directoryPath, filePath).split(path.sep).join("/"),
268
+ size: content.length,
269
+ gzipSize: gzipSync(content).length,
270
+ };
271
+ })
272
+ .sort((a, b) => a.path.localeCompare(b.path));
273
+ }
274
+
343
275
  getDatafilePath(options: DatafileOptions): string {
344
276
  const pattern = this.config.datafileNamePattern || "featurevisor-%s.json";
345
277
 
346
- const fileName = options.scope
347
- ? pattern.replace("%s", `scope-${options.scope.name}`)
348
- : pattern.replace("%s", `tag-${options.tag}`);
278
+ if (!options.target) {
279
+ throw new Error("Datafile target is required.");
280
+ }
281
+
282
+ const targetPathSegments = options.target.split(this.config.namespaceCharacter);
283
+ const targetFileKey = targetPathSegments.pop() || options.target;
284
+ const fileName = pattern.replace("%s", targetFileKey);
285
+ const targetDirectory = targetPathSegments.length > 0 ? path.join(...targetPathSegments) : "";
349
286
 
350
287
  const dir = options.datafilesDir || this.config.datafilesDirectoryPath;
351
288
 
352
289
  if (options.environment) {
353
- return path.join(dir, options.environment, fileName);
290
+ return path.join(dir, options.environment, targetDirectory, fileName);
354
291
  }
355
292
 
356
- return path.join(dir, fileName);
293
+ return path.join(dir, targetDirectory, fileName);
357
294
  }
358
295
 
359
296
  async readDatafile(options: DatafileOptions): Promise<DatafileContent> {
@@ -367,12 +304,8 @@ export class FilesystemAdapter extends Adapter {
367
304
  async writeDatafile(datafileContent: DatafileContent, options: DatafileOptions): Promise<void> {
368
305
  const dir = options.datafilesDir || this.config.datafilesDirectoryPath;
369
306
 
370
- const outputEnvironmentDirPath = options.environment
371
- ? path.join(dir, options.environment)
372
- : dir;
373
- fs.mkdirSync(outputEnvironmentDirPath, { recursive: true });
374
-
375
307
  const outputFilePath = this.getDatafilePath(options);
308
+ fs.mkdirSync(path.dirname(outputFilePath), { recursive: true });
376
309
 
377
310
  fs.writeFileSync(
378
311
  outputFilePath,
@@ -384,7 +317,7 @@ export class FilesystemAdapter extends Adapter {
384
317
  const root = path.resolve(dir, "..");
385
318
 
386
319
  const shortPath = outputFilePath.replace(root + path.sep, "");
387
- console.log(` Datafile generated: ${shortPath}`);
320
+ console.log(` ${colorize("✔", CLI_COLOR_GREEN)} ${colorize(shortPath, CLI_COLOR_CYAN)}`);
388
321
  }
389
322
 
390
323
  /**
@@ -423,16 +356,6 @@ export class FilesystemAdapter extends Adapter {
423
356
 
424
357
  if (entityType && entityKey) {
425
358
  pathPatterns = [this.getEntityPath(entityType, entityKey)];
426
-
427
- if (
428
- entityType === "feature" &&
429
- this.config.splitByEnvironment &&
430
- Array.isArray(this.config.environments)
431
- ) {
432
- for (const environment of this.config.environments) {
433
- pathPatterns.push(this.getFeatureEnvironmentPath(entityKey, environment));
434
- }
435
- }
436
359
  } else if (entityType) {
437
360
  if (entityType === "attribute") {
438
361
  pathPatterns = [this.config.attributesDirectoryPath];
@@ -440,24 +363,23 @@ export class FilesystemAdapter extends Adapter {
440
363
  pathPatterns = [this.config.segmentsDirectoryPath];
441
364
  } else if (entityType === "feature") {
442
365
  pathPatterns = [this.config.featuresDirectoryPath];
443
- if (this.config.splitByEnvironment) {
444
- pathPatterns.push(this.config.environmentsDirectoryPath);
445
- }
446
366
  } else if (entityType === "group") {
447
367
  pathPatterns = [this.config.groupsDirectoryPath];
448
368
  } else if (entityType === "schema") {
449
369
  pathPatterns = [this.config.schemasDirectoryPath];
370
+ } else if (entityType === "target") {
371
+ pathPatterns = [this.config.targetsDirectoryPath];
450
372
  } else if (entityType === "test") {
451
373
  pathPatterns = [this.config.testsDirectoryPath];
452
374
  }
453
375
  } else {
454
376
  pathPatterns = [
455
377
  this.config.featuresDirectoryPath,
456
- ...(this.config.splitByEnvironment ? [this.config.environmentsDirectoryPath] : []),
457
378
  this.config.attributesDirectoryPath,
458
379
  this.config.segmentsDirectoryPath,
459
380
  this.config.groupsDirectoryPath,
460
381
  this.config.schemasDirectoryPath,
382
+ this.config.targetsDirectoryPath,
461
383
  this.config.testsDirectoryPath,
462
384
  ];
463
385
  }
@@ -465,34 +387,6 @@ export class FilesystemAdapter extends Adapter {
465
387
  return pathPatterns.map((p) => p.replace((this.rootDirectoryPath as string) + path.sep, ""));
466
388
  }
467
389
 
468
- async getFeatureSourcePaths(featureKey: string) {
469
- const baseFilePath = this.getEntityPath("feature", featureKey);
470
- const environmentFilePaths: Record<string, string> = {};
471
-
472
- if (this.config.splitByEnvironment && Array.isArray(this.config.environments)) {
473
- for (const environment of this.config.environments) {
474
- environmentFilePaths[environment] = this.getFeatureEnvironmentPath(featureKey, environment);
475
- }
476
- }
477
-
478
- return {
479
- baseFilePath,
480
- environmentFilePaths,
481
- };
482
- }
483
-
484
- async getFeaturePropertySourcePath(
485
- featureKey: string,
486
- _property: "rules" | "force" | "expose",
487
- environment?: string,
488
- ) {
489
- if (this.config.splitByEnvironment && environment) {
490
- return this.getFeatureEnvironmentPath(featureKey, environment);
491
- }
492
-
493
- return this.getEntityPath("feature", featureKey);
494
- }
495
-
496
390
  async listHistoryEntries(entityType?: EntityType, entityKey?: string): Promise<HistoryEntry[]> {
497
391
  const pathPatterns = this.getPathPatterns(entityType, entityKey);
498
392
  const rawHistory = await this.getRawHistory(pathPatterns);
@@ -530,56 +424,28 @@ export class FilesystemAdapter extends Adapter {
530
424
  type = "segment";
531
425
  } else if (isWithinDirectory(this.config.featuresDirectoryPath, relativeDir)) {
532
426
  type = "feature";
533
- } else if (
534
- this.config.splitByEnvironment &&
535
- isWithinDirectory(this.config.environmentsDirectoryPath, relativeDir)
536
- ) {
537
- type = "feature";
538
427
  } else if (isWithinDirectory(this.config.groupsDirectoryPath, relativeDir)) {
539
428
  type = "group";
540
429
  } else if (isWithinDirectory(this.config.schemasDirectoryPath, relativeDir)) {
541
430
  type = "schema";
431
+ } else if (isWithinDirectory(this.config.targetsDirectoryPath, relativeDir)) {
432
+ type = "target";
542
433
  } else if (isWithinDirectory(this.config.testsDirectoryPath, relativeDir)) {
543
434
  type = "test";
544
435
  } else {
545
436
  continue;
546
437
  }
547
438
 
548
- if (type === "feature") {
549
- if (
550
- this.config.splitByEnvironment &&
551
- relativePath.startsWith(
552
- this.config.environmentsDirectoryPath.replace(
553
- (this.rootDirectoryPath as string) + path.sep,
554
- "",
555
- ) + path.sep,
556
- )
557
- ) {
558
- const featureRelativePath = relativePath
559
- .replace(
560
- this.config.environmentsDirectoryPath.replace(
561
- (this.rootDirectoryPath as string) + path.sep,
562
- "",
563
- ) + path.sep,
564
- "",
565
- )
566
- .split(path.sep)
567
- .slice(1)
568
- .join(path.sep)
569
- .replace(extensionWithDot, "");
570
-
571
- entities.push({
572
- type,
573
- key: featureRelativePath.replace(/\\/g, "/"),
574
- });
575
-
576
- continue;
577
- }
578
-
439
+ if (type === "feature" || type === "target") {
440
+ const entityDirectoryPath =
441
+ type === "feature"
442
+ ? this.config.featuresDirectoryPath
443
+ : this.config.targetsDirectoryPath;
579
444
  const baseRelativePath = absolutePath
580
- .replace(this.config.featuresDirectoryPath + path.sep, "")
445
+ .replace(entityDirectoryPath + path.sep, "")
581
446
  .replace(extensionWithDot, "")
582
- .replace(/\\/g, "/");
447
+ .split(path.sep)
448
+ .join(this.config.namespaceCharacter);
583
449
 
584
450
  entities.push({
585
451
  type,