@featurevisor/core 2.27.0 → 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 (389) hide show
  1. package/coverage/clover.xml +4991 -3130
  2. package/coverage/coverage-final.json +63 -39
  3. package/coverage/lcov-report/block-navigation.js +1 -1
  4. package/coverage/lcov-report/index.html +248 -98
  5. package/coverage/lcov-report/sorter.js +21 -7
  6. package/coverage/lcov-report/src/assess-distribution/index.html +116 -0
  7. package/coverage/lcov-report/src/assess-distribution/index.ts.html +754 -0
  8. package/coverage/lcov-report/{list → src/benchmark}/index.html +30 -30
  9. package/coverage/lcov-report/src/benchmark/index.ts.html +793 -0
  10. package/coverage/lcov-report/{builder → src/builder}/allocator.ts.html +38 -38
  11. package/coverage/lcov-report/{builder/buildScopedConditions.ts.html → src/builder/applyContextToConditions.ts.html} +80 -65
  12. package/coverage/lcov-report/{builder/buildScopedDatafile.ts.html → src/builder/applyContextToDatafile.ts.html} +92 -92
  13. package/coverage/lcov-report/{builder/buildScopedSegments.ts.html → src/builder/applyContextToSegments.ts.html} +103 -67
  14. package/coverage/lcov-report/{builder → src/builder}/buildDatafile.ts.html +336 -306
  15. package/coverage/lcov-report/src/builder/buildProject.ts.html +1117 -0
  16. package/coverage/lcov-report/src/builder/buildRuntimeDatafiles.ts.html +256 -0
  17. package/coverage/lcov-report/{builder → src/builder}/getFeatureRanges.ts.html +22 -22
  18. package/coverage/lcov-report/{builder → src/builder}/hashes.ts.html +50 -50
  19. package/coverage/lcov-report/{builder → src/builder}/index.html +114 -84
  20. package/coverage/lcov-report/{tester/cliFormat.ts.html → src/builder/index.ts.html} +17 -29
  21. package/coverage/lcov-report/{builder → src/builder}/mutateVariables.ts.html +55 -55
  22. package/coverage/lcov-report/{builder → src/builder}/mutator.ts.html +118 -118
  23. package/coverage/lcov-report/{builder → src/builder}/revision.ts.html +15 -15
  24. package/coverage/lcov-report/{builder → src/builder}/traffic.ts.html +86 -86
  25. package/coverage/lcov-report/src/cli/cli.ts.html +400 -0
  26. package/coverage/lcov-report/{tester → src/cli}/index.html +41 -41
  27. package/coverage/lcov-report/src/cli/plugins.ts.html +214 -0
  28. package/coverage/lcov-report/{config → src/config}/index.html +31 -31
  29. package/coverage/lcov-report/{config → src/config}/index.ts.html +12 -12
  30. package/coverage/lcov-report/{config → src/config}/projectConfig.ts.html +312 -96
  31. package/coverage/lcov-report/{datasource → src/datasource}/adapter.ts.html +28 -73
  32. package/coverage/lcov-report/{datasource → src/datasource}/datasource.ts.html +191 -104
  33. package/coverage/lcov-report/{datasource → src/datasource}/filesystemAdapter.ts.html +233 -635
  34. package/coverage/lcov-report/{datasource → src/datasource}/index.html +48 -48
  35. package/coverage/lcov-report/{datasource → src/datasource}/index.ts.html +14 -14
  36. package/coverage/lcov-report/src/evaluate/index.html +116 -0
  37. package/coverage/lcov-report/src/evaluate/index.ts.html +814 -0
  38. package/coverage/lcov-report/src/find-duplicate-segments/findDuplicateSegments.ts.html +313 -0
  39. package/coverage/lcov-report/src/find-duplicate-segments/index.html +131 -0
  40. package/coverage/lcov-report/src/find-duplicate-segments/index.ts.html +307 -0
  41. package/coverage/lcov-report/src/find-usage/index.html +116 -0
  42. package/coverage/lcov-report/src/find-usage/index.ts.html +1780 -0
  43. package/coverage/lcov-report/src/generate-code/index.html +131 -0
  44. package/coverage/lcov-report/src/generate-code/index.ts.html +403 -0
  45. package/coverage/lcov-report/{generate-code → src/generate-code}/typescript.ts.html +266 -1361
  46. package/coverage/lcov-report/{generate-code → src}/index.html +38 -23
  47. package/coverage/lcov-report/src/info/index.html +116 -0
  48. package/coverage/lcov-report/src/info/index.ts.html +472 -0
  49. package/coverage/lcov-report/src/init/index.html +116 -0
  50. package/coverage/lcov-report/src/init/index.ts.html +280 -0
  51. package/coverage/lcov-report/{linter → src/linter}/attributeSchema.ts.html +160 -157
  52. package/coverage/lcov-report/{linter → src/linter}/checkCircularDependency.ts.html +25 -25
  53. package/coverage/lcov-report/{linter → src/linter}/checkPercentageExceedingSlot.ts.html +42 -42
  54. package/coverage/lcov-report/{linter → src/linter}/conditionSchema.ts.html +207 -207
  55. package/coverage/lcov-report/{linter → src/linter}/featureSchema.ts.html +462 -471
  56. package/coverage/lcov-report/{linter → src/linter}/groupSchema.ts.html +25 -22
  57. package/coverage/lcov-report/{linter → src/linter}/index.html +129 -99
  58. package/coverage/lcov-report/src/linter/index.ts.html +88 -0
  59. package/coverage/lcov-report/{linter → src/linter}/lintProject.ts.html +740 -332
  60. package/coverage/lcov-report/{linter → src/linter}/mutationNotation.ts.html +130 -130
  61. package/coverage/lcov-report/{linter → src/linter}/printError.ts.html +27 -27
  62. package/coverage/lcov-report/{linter → src/linter}/schema.ts.html +153 -150
  63. package/coverage/lcov-report/{linter → src/linter}/segmentSchema.ts.html +18 -15
  64. package/coverage/lcov-report/src/linter/targetSchema.ts.html +223 -0
  65. package/coverage/lcov-report/{linter → src/linter}/testSchema.ts.html +54 -48
  66. package/coverage/lcov-report/{linter → src/linter}/zodHelpers.ts.html +17 -17
  67. package/coverage/lcov-report/src/list/index.html +131 -0
  68. package/coverage/lcov-report/src/list/index.ts.html +2065 -0
  69. package/coverage/lcov-report/{list → src/list}/matrix.ts.html +43 -58
  70. package/coverage/lcov-report/src/promoter/index.html +116 -0
  71. package/coverage/lcov-report/src/promoter/index.ts.html +3883 -0
  72. package/coverage/lcov-report/src/sets.ts.html +313 -0
  73. package/coverage/lcov-report/src/targeting.ts.html +403 -0
  74. package/coverage/lcov-report/src/tester/cliFormat.ts.html +133 -0
  75. package/coverage/lcov-report/{tester → src/tester}/helpers.ts.html +15 -15
  76. package/coverage/lcov-report/src/tester/index.html +206 -0
  77. package/coverage/lcov-report/src/tester/prettyDuration.ts.html +187 -0
  78. package/coverage/lcov-report/src/tester/printTestResult.ts.html +337 -0
  79. package/coverage/lcov-report/src/tester/testFeature.ts.html +1186 -0
  80. package/coverage/lcov-report/src/tester/testProject.ts.html +1018 -0
  81. package/coverage/lcov-report/src/tester/testSegment.ts.html +316 -0
  82. package/coverage/lcov-report/{utils → src/utils}/extractKeys.ts.html +68 -68
  83. package/coverage/lcov-report/{utils → src/utils}/git.ts.html +44 -68
  84. package/coverage/lcov-report/{utils → src/utils}/index.html +44 -44
  85. package/coverage/lcov-report/{utils → src/utils}/index.ts.html +14 -14
  86. package/coverage/lcov-report/{utils → src/utils}/pretty.ts.html +20 -20
  87. package/coverage/lcov.info +10121 -5723
  88. package/jest.config.js +13 -4
  89. package/lib/assess-distribution/index.d.ts +1 -1
  90. package/lib/assess-distribution/index.js +59 -40
  91. package/lib/assess-distribution/index.js.map +1 -1
  92. package/lib/benchmark/index.d.ts +8 -5
  93. package/lib/benchmark/index.js +82 -65
  94. package/lib/benchmark/index.js.map +1 -1
  95. package/lib/builder/applyContextToConditions.d.ts +5 -0
  96. package/lib/builder/{buildScopedConditions.js → applyContextToConditions.js} +19 -14
  97. package/lib/builder/applyContextToConditions.js.map +1 -0
  98. package/lib/builder/applyContextToDatafile.d.ts +2 -0
  99. package/lib/builder/{buildScopedDatafile.js → applyContextToDatafile.js} +26 -26
  100. package/lib/builder/applyContextToDatafile.js.map +1 -0
  101. package/lib/builder/applyContextToSegments.d.ts +5 -0
  102. package/lib/builder/{buildScopedSegments.js → applyContextToSegments.js} +19 -14
  103. package/lib/builder/applyContextToSegments.js.map +1 -0
  104. package/lib/builder/buildDatafile.d.ts +9 -6
  105. package/lib/builder/buildDatafile.js +86 -51
  106. package/lib/builder/buildDatafile.js.map +1 -1
  107. package/lib/builder/buildProject.d.ts +17 -3
  108. package/lib/builder/buildProject.js +151 -59
  109. package/lib/builder/buildProject.js.map +1 -1
  110. package/lib/builder/buildRuntimeDatafiles.d.ts +12 -0
  111. package/lib/builder/buildRuntimeDatafiles.js +35 -0
  112. package/lib/builder/buildRuntimeDatafiles.js.map +1 -0
  113. package/lib/builder/getFeatureRanges.js +34 -1
  114. package/lib/builder/getFeatureRanges.js.map +1 -1
  115. package/lib/builder/hashes.js +34 -1
  116. package/lib/builder/hashes.js.map +1 -1
  117. package/lib/builder/index.d.ts +0 -1
  118. package/lib/builder/index.js +0 -1
  119. package/lib/builder/index.js.map +1 -1
  120. package/lib/cli/cli.js +0 -4
  121. package/lib/cli/cli.js.map +1 -1
  122. package/lib/cli/plugins.js +7 -2
  123. package/lib/cli/plugins.js.map +1 -1
  124. package/lib/config/projectConfig.d.ts +17 -17
  125. package/lib/config/projectConfig.js +101 -15
  126. package/lib/config/projectConfig.js.map +1 -1
  127. package/lib/datasource/adapter.d.ts +7 -9
  128. package/lib/datasource/adapter.js +0 -7
  129. package/lib/datasource/adapter.js.map +1 -1
  130. package/lib/datasource/datasource.d.ts +15 -5
  131. package/lib/datasource/datasource.js +37 -9
  132. package/lib/datasource/datasource.js.map +1 -1
  133. package/lib/datasource/filesystemAdapter.d.ts +4 -10
  134. package/lib/datasource/filesystemAdapter.js +111 -149
  135. package/lib/datasource/filesystemAdapter.js.map +1 -1
  136. package/lib/evaluate/index.d.ts +1 -7
  137. package/lib/evaluate/index.js +81 -67
  138. package/lib/evaluate/index.js.map +1 -1
  139. package/lib/find-duplicate-segments/findDuplicateSegments.js +34 -1
  140. package/lib/find-duplicate-segments/findDuplicateSegments.js.map +1 -1
  141. package/lib/find-duplicate-segments/index.js +21 -13
  142. package/lib/find-duplicate-segments/index.js.map +1 -1
  143. package/lib/find-usage/index.js +57 -41
  144. package/lib/find-usage/index.js.map +1 -1
  145. package/lib/generate-code/index.d.ts +1 -1
  146. package/lib/generate-code/index.js +64 -21
  147. package/lib/generate-code/index.js.map +1 -1
  148. package/lib/generate-code/typescript.d.ts +1 -1
  149. package/lib/generate-code/typescript.js +59 -333
  150. package/lib/generate-code/typescript.js.map +1 -1
  151. package/lib/index.d.ts +2 -1
  152. package/lib/index.js +2 -1
  153. package/lib/index.js.map +1 -1
  154. package/lib/info/index.js +57 -16
  155. package/lib/info/index.js.map +1 -1
  156. package/lib/init/index.d.ts +2 -2
  157. package/lib/init/index.js +39 -3
  158. package/lib/init/index.js.map +1 -1
  159. package/lib/linter/attributeSchema.d.ts +1 -0
  160. package/lib/linter/attributeSchema.js +1 -0
  161. package/lib/linter/attributeSchema.js.map +1 -1
  162. package/lib/linter/conditionSchema.js +5 -5
  163. package/lib/linter/conditionSchema.js.map +1 -1
  164. package/lib/linter/featureSchema.d.ts +4 -1
  165. package/lib/linter/featureSchema.js +15 -13
  166. package/lib/linter/featureSchema.js.map +1 -1
  167. package/lib/linter/groupSchema.d.ts +1 -0
  168. package/lib/linter/groupSchema.js +1 -0
  169. package/lib/linter/groupSchema.js.map +1 -1
  170. package/lib/linter/lintProject.d.ts +1 -3
  171. package/lib/linter/lintProject.js +198 -68
  172. package/lib/linter/lintProject.js.map +1 -1
  173. package/lib/linter/schema.js +1 -0
  174. package/lib/linter/schema.js.map +1 -1
  175. package/lib/linter/segmentSchema.d.ts +1 -0
  176. package/lib/linter/segmentSchema.js +1 -0
  177. package/lib/linter/segmentSchema.js.map +1 -1
  178. package/lib/linter/targetSchema.d.ts +16 -0
  179. package/lib/linter/targetSchema.js +40 -0
  180. package/lib/linter/targetSchema.js.map +1 -0
  181. package/lib/linter/testSchema.d.ts +4 -3
  182. package/lib/linter/testSchema.js +9 -4
  183. package/lib/linter/testSchema.js.map +1 -1
  184. package/lib/list/index.d.ts +1 -0
  185. package/lib/list/index.js +131 -12
  186. package/lib/list/index.js.map +1 -1
  187. package/lib/list/matrix.js +3 -7
  188. package/lib/list/matrix.js.map +1 -1
  189. package/lib/promoter/index.d.ts +50 -0
  190. package/lib/promoter/index.js +880 -0
  191. package/lib/promoter/index.js.map +1 -0
  192. package/lib/sets.d.ts +11 -0
  193. package/lib/sets.js +81 -0
  194. package/lib/sets.js.map +1 -0
  195. package/lib/targeting.d.ts +14 -0
  196. package/lib/targeting.js +82 -0
  197. package/lib/targeting.js.map +1 -0
  198. package/lib/tester/cliFormat.d.ts +7 -1
  199. package/lib/tester/cliFormat.js +11 -2
  200. package/lib/tester/cliFormat.js.map +1 -1
  201. package/lib/tester/printTestResult.js +2 -2
  202. package/lib/tester/printTestResult.js.map +1 -1
  203. package/lib/tester/testFeature.d.ts +0 -1
  204. package/lib/tester/testFeature.js +8 -25
  205. package/lib/tester/testFeature.js.map +1 -1
  206. package/lib/tester/testProject.d.ts +2 -3
  207. package/lib/tester/testProject.js +93 -86
  208. package/lib/tester/testProject.js.map +1 -1
  209. package/lib/tester/testSegment.d.ts +1 -1
  210. package/lib/tester/testSegment.js +3 -21
  211. package/lib/tester/testSegment.js.map +1 -1
  212. package/lib/utils/git.js +45 -19
  213. package/lib/utils/git.js.map +1 -1
  214. package/package.json +12 -12
  215. package/src/assess-distribution/index.ts +72 -52
  216. package/src/benchmark/index.ts +124 -91
  217. package/src/builder/{buildScopedConditions.spec.ts → applyContextToConditions.spec.ts} +160 -142
  218. package/src/builder/{buildScopedConditions.ts → applyContextToConditions.ts} +19 -14
  219. package/src/builder/{buildScopedDatafile.spec.ts → applyContextToDatafile.spec.ts} +141 -81
  220. package/src/builder/{buildScopedDatafile.ts → applyContextToDatafile.ts} +33 -33
  221. package/src/builder/{buildScopedSegments.spec.ts → applyContextToSegments.spec.ts} +171 -151
  222. package/src/builder/{buildScopedSegments.ts → applyContextToSegments.ts} +26 -14
  223. package/src/builder/buildDatafile.spec.ts +192 -14
  224. package/src/builder/buildDatafile.ts +74 -64
  225. package/src/builder/buildProject.ts +171 -86
  226. package/src/builder/buildRuntimeDatafiles.ts +57 -0
  227. package/src/builder/index.ts +0 -1
  228. package/src/cli/cli.ts +0 -5
  229. package/src/cli/plugins.ts +7 -2
  230. package/src/config/projectConfig.spec.ts +171 -8
  231. package/src/config/projectConfig.ts +100 -28
  232. package/src/datasource/adapter.ts +8 -23
  233. package/src/datasource/datasource.ts +50 -21
  234. package/src/datasource/filesystemAdapter.spec.ts +133 -74
  235. package/src/datasource/filesystemAdapter.ts +93 -227
  236. package/src/evaluate/index.ts +109 -97
  237. package/src/find-duplicate-segments/index.ts +34 -16
  238. package/src/find-usage/index.ts +89 -44
  239. package/src/generate-code/index.ts +36 -24
  240. package/src/generate-code/typescript.spec.ts +106 -0
  241. package/src/generate-code/typescript.ts +33 -398
  242. package/src/index.ts +2 -1
  243. package/src/info/index.ts +72 -16
  244. package/src/init/index.ts +1 -1
  245. package/src/linter/attributeSchema.ts +1 -0
  246. package/src/linter/conditionSchema.spec.ts +23 -3
  247. package/src/linter/conditionSchema.ts +5 -5
  248. package/src/linter/featureSchema.spec.ts +107 -18
  249. package/src/linter/featureSchema.ts +25 -28
  250. package/src/linter/groupSchema.ts +1 -0
  251. package/src/linter/lintProject.spec.ts +131 -92
  252. package/src/linter/lintProject.ts +233 -97
  253. package/src/linter/schema.ts +1 -0
  254. package/src/linter/segmentSchema.spec.ts +5 -3
  255. package/src/linter/segmentSchema.ts +1 -0
  256. package/src/linter/targetSchema.spec.ts +159 -0
  257. package/src/linter/targetSchema.ts +46 -0
  258. package/src/linter/testSchema.spec.ts +70 -5
  259. package/src/linter/testSchema.ts +12 -10
  260. package/src/list/index.spec.ts +135 -0
  261. package/src/list/index.ts +188 -12
  262. package/src/list/matrix.ts +3 -8
  263. package/src/promoter/index.spec.ts +617 -0
  264. package/src/promoter/index.ts +1266 -0
  265. package/src/sets.ts +76 -0
  266. package/src/targeting.spec.ts +74 -0
  267. package/src/targeting.ts +106 -0
  268. package/src/tester/cliFormat.ts +11 -1
  269. package/src/tester/printTestResult.ts +12 -3
  270. package/src/tester/testFeature.ts +10 -36
  271. package/src/tester/testProject.spec.ts +50 -0
  272. package/src/tester/testProject.ts +89 -140
  273. package/src/tester/testSegment.ts +5 -22
  274. package/src/utils/git.ts +13 -21
  275. package/tsconfig.cjs.json +5 -1
  276. package/tsconfig.typecheck.json +9 -0
  277. package/coverage/lcov-report/builder/convertToV1.ts.html +0 -583
  278. package/lib/builder/allocator.spec.d.ts +0 -1
  279. package/lib/builder/allocator.spec.js +0 -85
  280. package/lib/builder/allocator.spec.js.map +0 -1
  281. package/lib/builder/buildDatafile.spec.d.ts +0 -1
  282. package/lib/builder/buildDatafile.spec.js +0 -233
  283. package/lib/builder/buildDatafile.spec.js.map +0 -1
  284. package/lib/builder/buildScopedConditions.d.ts +0 -5
  285. package/lib/builder/buildScopedConditions.js.map +0 -1
  286. package/lib/builder/buildScopedConditions.spec.d.ts +0 -1
  287. package/lib/builder/buildScopedConditions.spec.js +0 -2167
  288. package/lib/builder/buildScopedConditions.spec.js.map +0 -1
  289. package/lib/builder/buildScopedDatafile.d.ts +0 -2
  290. package/lib/builder/buildScopedDatafile.js.map +0 -1
  291. package/lib/builder/buildScopedDatafile.spec.d.ts +0 -1
  292. package/lib/builder/buildScopedDatafile.spec.js +0 -2277
  293. package/lib/builder/buildScopedDatafile.spec.js.map +0 -1
  294. package/lib/builder/buildScopedSegments.d.ts +0 -5
  295. package/lib/builder/buildScopedSegments.js.map +0 -1
  296. package/lib/builder/buildScopedSegments.spec.d.ts +0 -1
  297. package/lib/builder/buildScopedSegments.spec.js +0 -1062
  298. package/lib/builder/buildScopedSegments.spec.js.map +0 -1
  299. package/lib/builder/convertToV1.d.ts +0 -10
  300. package/lib/builder/convertToV1.js +0 -119
  301. package/lib/builder/convertToV1.js.map +0 -1
  302. package/lib/builder/mutateVariables.spec.d.ts +0 -1
  303. package/lib/builder/mutateVariables.spec.js +0 -1074
  304. package/lib/builder/mutateVariables.spec.js.map +0 -1
  305. package/lib/builder/mutator.spec.d.ts +0 -1
  306. package/lib/builder/mutator.spec.js +0 -368
  307. package/lib/builder/mutator.spec.js.map +0 -1
  308. package/lib/builder/revision.spec.d.ts +0 -1
  309. package/lib/builder/revision.spec.js +0 -21
  310. package/lib/builder/revision.spec.js.map +0 -1
  311. package/lib/builder/traffic.spec.d.ts +0 -1
  312. package/lib/builder/traffic.spec.js +0 -872
  313. package/lib/builder/traffic.spec.js.map +0 -1
  314. package/lib/config/projectConfig.spec.d.ts +0 -1
  315. package/lib/config/projectConfig.spec.js +0 -24
  316. package/lib/config/projectConfig.spec.js.map +0 -1
  317. package/lib/datasource/filesystemAdapter.spec.d.ts +0 -1
  318. package/lib/datasource/filesystemAdapter.spec.js +0 -88
  319. package/lib/datasource/filesystemAdapter.spec.js.map +0 -1
  320. package/lib/generate-code/typescript.spec.d.ts +0 -1
  321. package/lib/generate-code/typescript.spec.js +0 -78
  322. package/lib/generate-code/typescript.spec.js.map +0 -1
  323. package/lib/linter/attributeSchema.spec.d.ts +0 -1
  324. package/lib/linter/attributeSchema.spec.js +0 -266
  325. package/lib/linter/attributeSchema.spec.js.map +0 -1
  326. package/lib/linter/conditionSchema.spec.d.ts +0 -1
  327. package/lib/linter/conditionSchema.spec.js +0 -380
  328. package/lib/linter/conditionSchema.spec.js.map +0 -1
  329. package/lib/linter/featureSchema.spec.d.ts +0 -1
  330. package/lib/linter/featureSchema.spec.js +0 -1552
  331. package/lib/linter/featureSchema.spec.js.map +0 -1
  332. package/lib/linter/lintProject.spec.d.ts +0 -1
  333. package/lib/linter/lintProject.spec.js +0 -211
  334. package/lib/linter/lintProject.spec.js.map +0 -1
  335. package/lib/linter/mutationNotation.spec.d.ts +0 -1
  336. package/lib/linter/mutationNotation.spec.js +0 -598
  337. package/lib/linter/mutationNotation.spec.js.map +0 -1
  338. package/lib/linter/schema.spec.d.ts +0 -1
  339. package/lib/linter/schema.spec.js +0 -535
  340. package/lib/linter/schema.spec.js.map +0 -1
  341. package/lib/linter/segmentSchema.spec.d.ts +0 -1
  342. package/lib/linter/segmentSchema.spec.js +0 -303
  343. package/lib/linter/segmentSchema.spec.js.map +0 -1
  344. package/lib/linter/testSchema.spec.d.ts +0 -1
  345. package/lib/linter/testSchema.spec.js +0 -162
  346. package/lib/linter/testSchema.spec.js.map +0 -1
  347. package/lib/list/matrix.spec.d.ts +0 -1
  348. package/lib/list/matrix.spec.js +0 -42
  349. package/lib/list/matrix.spec.js.map +0 -1
  350. package/lib/site/exportSite.d.ts +0 -2
  351. package/lib/site/exportSite.js +0 -30
  352. package/lib/site/exportSite.js.map +0 -1
  353. package/lib/site/generateHistory.d.ts +0 -3
  354. package/lib/site/generateHistory.js +0 -31
  355. package/lib/site/generateHistory.js.map +0 -1
  356. package/lib/site/generateSiteSearchIndex.d.ts +0 -4
  357. package/lib/site/generateSiteSearchIndex.js +0 -195
  358. package/lib/site/generateSiteSearchIndex.js.map +0 -1
  359. package/lib/site/getLastModifiedFromHistory.d.ts +0 -2
  360. package/lib/site/getLastModifiedFromHistory.js +0 -18
  361. package/lib/site/getLastModifiedFromHistory.js.map +0 -1
  362. package/lib/site/getOwnerAndRepoFromUrl.d.ts +0 -4
  363. package/lib/site/getOwnerAndRepoFromUrl.js +0 -20
  364. package/lib/site/getOwnerAndRepoFromUrl.js.map +0 -1
  365. package/lib/site/getRelativePaths.d.ts +0 -6
  366. package/lib/site/getRelativePaths.js +0 -15
  367. package/lib/site/getRelativePaths.js.map +0 -1
  368. package/lib/site/getRepoDetails.d.ts +0 -8
  369. package/lib/site/getRepoDetails.js +0 -48
  370. package/lib/site/getRepoDetails.js.map +0 -1
  371. package/lib/site/index.d.ts +0 -2
  372. package/lib/site/index.js +0 -43
  373. package/lib/site/index.js.map +0 -1
  374. package/lib/site/serveSite.d.ts +0 -2
  375. package/lib/site/serveSite.js +0 -54
  376. package/lib/site/serveSite.js.map +0 -1
  377. package/lib/tester/helpers.spec.d.ts +0 -1
  378. package/lib/tester/helpers.spec.js +0 -115
  379. package/lib/tester/helpers.spec.js.map +0 -1
  380. package/src/builder/convertToV1.ts +0 -166
  381. package/src/site/exportSite.ts +0 -42
  382. package/src/site/generateHistory.ts +0 -40
  383. package/src/site/generateSiteSearchIndex.ts +0 -258
  384. package/src/site/getLastModifiedFromHistory.ts +0 -21
  385. package/src/site/getOwnerAndRepoFromUrl.ts +0 -17
  386. package/src/site/getRelativePaths.ts +0 -24
  387. package/src/site/getRepoDetails.ts +0 -62
  388. package/src/site/index.ts +0 -46
  389. 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,