@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
@@ -9,36 +9,12 @@ import type {
9
9
  VariableSchemaWithInline,
10
10
  } from "@featurevisor/types";
11
11
  import { Dependencies } from "../dependencies";
12
+ import { normalizeOptionValues, resolveTargets, targetIncludesFeature } from "../targeting";
12
13
 
13
14
  export interface TypeScriptGenerationOptions {
14
15
  tag?: string | string[];
16
+ target?: string | string[];
15
17
  react?: boolean;
16
- individualFeatures?: boolean;
17
- }
18
-
19
- function convertFeaturevisorTypeToTypeScriptType(featurevisorType: string): string {
20
- switch (featurevisorType) {
21
- case "boolean":
22
- return "boolean";
23
- case "string":
24
- return "string";
25
- case "integer":
26
- return "number";
27
- case "double":
28
- return "number";
29
- case "date":
30
- return "Date | string";
31
- case "semver":
32
- return "string";
33
- case "array":
34
- return "string[]";
35
- case "object":
36
- return "Record<string, unknown>";
37
- case "json":
38
- return "unknown";
39
- default:
40
- throw new Error(`Unknown type: ${featurevisorType}`);
41
- }
42
18
  }
43
19
 
44
20
  function shouldWrapArrayItemType(typeName: string): boolean {
@@ -214,252 +190,6 @@ function getEffectiveVariableSchema(
214
190
  return variableSchema as VariableSchemaWithInline;
215
191
  }
216
192
 
217
- /**
218
- * Generates TypeScript type/interface declarations and metadata for a variable.
219
- * Returns declarations to emit (interface or type alias) plus the type name and generic to use in the getter.
220
- * When isLiteralType is true, the getter return must be asserted so the SDK's primitive return type matches the literal.
221
- * When schemaTypeNames is provided, direct schema refs and schema refs in array items use those type names and schemaTypesUsed is populated.
222
- */
223
- function generateVariableTypeDeclarations(
224
- variableKey: string,
225
- variableSchema: VariableSchema,
226
- schemasByKey: Record<string, Schema>,
227
- schemaTypeNames?: Record<string, string>,
228
- ): {
229
- declarations: string[];
230
- returnTypeName: string;
231
- genericArg: string;
232
- isLiteralType?: boolean;
233
- useGetVariable?: boolean;
234
- schemaTypesUsed: string[];
235
- } {
236
- const typeName = getPascalCase(variableKey) + "Variable";
237
- const itemTypeName = getPascalCase(variableKey) + "VariableItem";
238
- const schemaTypesUsed: string[] = [];
239
-
240
- const addSchemaUsed = (name: string) => {
241
- if (name && !schemaTypesUsed.includes(name)) schemaTypesUsed.push(name);
242
- };
243
-
244
- // Direct schema reference: emit type alias to schema type and reuse it
245
- if (
246
- schemaTypeNames &&
247
- "schema" in variableSchema &&
248
- variableSchema.schema &&
249
- schemasByKey[variableSchema.schema]
250
- ) {
251
- const schemaKey = variableSchema.schema;
252
- const schemaTypeName = schemaTypeNames[schemaKey];
253
- const resolvedSchema = resolveSchema(schemasByKey[schemaKey], schemasByKey);
254
- const isOneOf =
255
- resolvedSchema.oneOf &&
256
- Array.isArray(resolvedSchema.oneOf) &&
257
- resolvedSchema.oneOf.length > 0 &&
258
- !resolvedSchema.type;
259
- const isLiteralSchema =
260
- resolvedSchema.const !== undefined ||
261
- (resolvedSchema.enum && Array.isArray(resolvedSchema.enum) && resolvedSchema.enum.length > 0);
262
- addSchemaUsed(schemaTypeName);
263
- // getVariableArray<T> expects T to be the element type, not the full array type
264
- let genericArg = schemaTypeName;
265
- if (resolvedSchema.type === "array" && resolvedSchema.items) {
266
- const itemsSchema = resolvedSchema.items as Schema;
267
- if ("schema" in itemsSchema && itemsSchema.schema && schemaTypeNames[itemsSchema.schema]) {
268
- genericArg = schemaTypeNames[itemsSchema.schema];
269
- addSchemaUsed(genericArg);
270
- } else {
271
- genericArg = schemaToTypeScriptType(itemsSchema, schemasByKey, schemaTypeNames);
272
- }
273
- }
274
- return {
275
- declarations: [`${INDENT_NS}export type ${typeName} = ${schemaTypeName};`],
276
- returnTypeName: schemaTypeName,
277
- genericArg,
278
- useGetVariable: isOneOf,
279
- isLiteralType: isOneOf || isLiteralSchema,
280
- schemaTypesUsed,
281
- };
282
- }
283
-
284
- const effective = getEffectiveVariableSchema(variableSchema, schemasByKey);
285
- const type = effective?.type;
286
- const declarations: string[] = [];
287
-
288
- if (type === "json") {
289
- return { declarations: [], returnTypeName: "T", genericArg: "T", schemaTypesUsed };
290
- }
291
-
292
- const effectiveOneOf =
293
- effective && "oneOf" in effective && Array.isArray((effective as Schema).oneOf)
294
- ? (effective as Schema).oneOf
295
- : undefined;
296
- if (effectiveOneOf && effectiveOneOf.length > 0 && !type) {
297
- const unionType = effectiveOneOf
298
- .map((branch) => schemaToTypeScriptType(branch as Schema, schemasByKey, schemaTypeNames))
299
- .join(" | ");
300
- if (schemaTypeNames) {
301
- Object.values(schemaTypeNames).forEach((n) => {
302
- if (unionType.includes(n)) addSchemaUsed(n);
303
- });
304
- }
305
- declarations.push(`${INDENT_NS}export type ${typeName} = ${unionType};`);
306
- return {
307
- declarations,
308
- returnTypeName: typeName,
309
- genericArg: typeName,
310
- isLiteralType: true,
311
- useGetVariable: true,
312
- schemaTypesUsed,
313
- };
314
- }
315
-
316
- if (type === "object") {
317
- const resolvedEffective =
318
- effective && ("properties" in effective || "additionalProperties" in effective)
319
- ? (resolveSchema(effective as Schema, schemasByKey) as Schema)
320
- : undefined;
321
- const props = resolvedEffective?.properties;
322
- const additional = resolvedEffective?.additionalProperties;
323
- if (
324
- (props && typeof props === "object" && Object.keys(props).length > 0) ||
325
- (additional && typeof additional === "object")
326
- ) {
327
- const requiredSet = new Set(resolvedEffective?.required || []);
328
- const entries = Object.entries(props ?? {})
329
- .map(([k, v]) => {
330
- const propType = schemaToTypeScriptType(v as Schema, schemasByKey, schemaTypeNames);
331
- if (schemaTypeNames)
332
- Object.values(schemaTypeNames).forEach((n) => {
333
- if (propType.includes(n)) addSchemaUsed(n);
334
- });
335
- const optional = !requiredSet.has(k);
336
- return optional
337
- ? `${INDENT_NS_BODY}${formatObjectKey(k)}?: ${propType};`
338
- : `${INDENT_NS_BODY}${formatObjectKey(k)}: ${propType};`;
339
- })
340
- .filter(Boolean);
341
- if (additional && typeof additional === "object") {
342
- const additionalType = schemaToTypeScriptType(
343
- additional as Schema,
344
- schemasByKey,
345
- schemaTypeNames,
346
- );
347
- if (schemaTypeNames)
348
- Object.values(schemaTypeNames).forEach((n) => {
349
- if (additionalType.includes(n)) addSchemaUsed(n);
350
- });
351
- const propUnion = Object.entries(props ?? {})
352
- .map(([, v]) => schemaToTypeScriptType(v as Schema, schemasByKey, schemaTypeNames))
353
- .join(" | ");
354
- const indexType = [additionalType, propUnion].filter(Boolean).join(" | ");
355
- entries.push(`${INDENT_NS_BODY}[key: string]: ${indexType};`);
356
- }
357
- declarations.push(
358
- `${INDENT_NS}export interface ${typeName} {\n${entries.join("\n")}\n${INDENT_NS}}`,
359
- );
360
- return { declarations, returnTypeName: typeName, genericArg: typeName, schemaTypesUsed };
361
- }
362
- declarations.push(`${INDENT_NS}export type ${typeName} = Record<string, unknown>;`);
363
- return { declarations, returnTypeName: typeName, genericArg: typeName, schemaTypesUsed };
364
- }
365
-
366
- if (type === "array") {
367
- const itemsSchema = effective && "items" in effective ? (effective.items as Schema) : undefined;
368
- if (itemsSchema) {
369
- const itemsRef =
370
- schemaTypeNames &&
371
- "schema" in itemsSchema &&
372
- itemsSchema.schema &&
373
- schemasByKey[itemsSchema.schema]
374
- ? schemaTypeNames[itemsSchema.schema]
375
- : null;
376
- if (itemsRef) {
377
- addSchemaUsed(itemsRef);
378
- declarations.push(`${INDENT_NS}export type ${itemTypeName} = ${itemsRef};`);
379
- return {
380
- declarations,
381
- returnTypeName: `${itemTypeName}[]`,
382
- genericArg: itemTypeName,
383
- schemaTypesUsed,
384
- };
385
- }
386
- const resolvedItems = resolveSchema(itemsSchema, schemasByKey);
387
- if (
388
- resolvedItems.type === "object" &&
389
- resolvedItems.properties &&
390
- Object.keys(resolvedItems.properties).length > 0
391
- ) {
392
- const requiredSet = new Set(resolvedItems.required || []);
393
- const entries = Object.entries(resolvedItems.properties)
394
- .map(([k, v]) => {
395
- const propType = schemaToTypeScriptType(v as Schema, schemasByKey, schemaTypeNames);
396
- if (schemaTypeNames)
397
- Object.values(schemaTypeNames).forEach((n) => {
398
- if (propType.includes(n)) addSchemaUsed(n);
399
- });
400
- const optional = !requiredSet.has(k);
401
- return optional
402
- ? `${INDENT_NS_BODY}${k}?: ${propType};`
403
- : `${INDENT_NS_BODY}${k}: ${propType};`;
404
- })
405
- .join("\n");
406
- declarations.push(
407
- `${INDENT_NS}export interface ${itemTypeName} {\n${entries}\n${INDENT_NS}}`,
408
- );
409
- return {
410
- declarations,
411
- returnTypeName: `${itemTypeName}[]`,
412
- genericArg: itemTypeName,
413
- schemaTypesUsed,
414
- };
415
- }
416
- const itemType = schemaToTypeScriptType(resolvedItems, schemasByKey, schemaTypeNames);
417
- if (schemaTypeNames)
418
- Object.values(schemaTypeNames).forEach((n) => {
419
- if (itemType.includes(n)) addSchemaUsed(n);
420
- });
421
- declarations.push(`${INDENT_NS}export type ${itemTypeName} = ${itemType};`);
422
- return {
423
- declarations,
424
- returnTypeName: `${itemTypeName}[]`,
425
- genericArg: itemTypeName,
426
- schemaTypesUsed,
427
- };
428
- }
429
- declarations.push(`${INDENT_NS}export type ${itemTypeName} = string;`);
430
- return {
431
- declarations,
432
- returnTypeName: `${itemTypeName}[]`,
433
- genericArg: itemTypeName,
434
- schemaTypesUsed,
435
- };
436
- }
437
-
438
- // primitive: boolean, string, integer, double (or unknown when schema ref unresolved)
439
- // When schema has primitive const or enum, emit literal or union type
440
- const effectiveConst =
441
- effective && "const" in effective && (effective as Schema).const !== undefined
442
- ? (effective as Schema).const
443
- : undefined;
444
- const effectiveEnum =
445
- effective && "enum" in effective && Array.isArray((effective as Schema).enum)
446
- ? (effective as Schema).enum
447
- : undefined;
448
- const literalType = effectiveConst !== undefined ? constToLiteralType(effectiveConst) : null;
449
- const enumUnion =
450
- effectiveEnum && effectiveEnum.length > 0 ? enumToUnionType(effectiveEnum) : null;
451
- const primitiveType =
452
- literalType ?? enumUnion ?? (type ? convertFeaturevisorTypeToTypeScriptType(type) : "unknown");
453
- declarations.push(`${INDENT_NS}export type ${typeName} = ${primitiveType};`);
454
- return {
455
- declarations,
456
- returnTypeName: typeName,
457
- genericArg: typeName,
458
- isLiteralType: literalType !== null || enumUnion !== null,
459
- schemaTypesUsed,
460
- };
461
- }
462
-
463
193
  function getPascalCase(str) {
464
194
  // Remove special characters and split the string into an array of words
465
195
  const words = str.replace(/[^a-zA-Z0-9]/g, " ").split(" ");
@@ -582,21 +312,20 @@ function generateAttributesFileContent(
582
312
  return `${importLine}${lines.join("\n")}\n`;
583
313
  }
584
314
 
585
- // Indentation for generated namespace content (2 spaces per level)
586
315
  const INDENT_NS = " ";
587
316
  const INDENT_NS_BODY = " ";
588
317
 
589
318
  const instanceSnippet = `
590
- import { FeaturevisorInstance } from "@featurevisor/sdk";
319
+ import type { Featurevisor } from "@featurevisor/sdk";
591
320
 
592
- let _instance: FeaturevisorInstance;
321
+ let _instance: Featurevisor;
593
322
 
594
- export function setInstance(instance: FeaturevisorInstance) {
323
+ export function setInstance(instance: Featurevisor) {
595
324
  _instance = instance;
596
325
  }
597
326
 
598
- export function getInstance(): FeaturevisorInstance {
599
- return _instance as FeaturevisorInstance;
327
+ export function getInstance(): Featurevisor {
328
+ return _instance as Featurevisor;
600
329
  }
601
330
  `.trimStart();
602
331
 
@@ -605,14 +334,21 @@ export async function generateTypeScriptCodeForProject(
605
334
  outputPath: string,
606
335
  options: TypeScriptGenerationOptions = {},
607
336
  ) {
608
- const { rootDirectoryPath, datasource } = deps;
609
- const selectedTags = options.tag
610
- ? Array.isArray(options.tag)
611
- ? options.tag
612
- : [options.tag]
613
- : [];
337
+ const { rootDirectoryPath, projectConfig, datasource } = deps;
338
+ const selectedTags = normalizeOptionValues(options.tag);
614
339
  const shouldGenerateReact = Boolean(options.react);
615
- const shouldGenerateIndividualFeatures = options.individualFeatures !== false;
340
+
341
+ const unknownTag = selectedTags.find((tag) => !projectConfig.tags.includes(tag));
342
+ if (unknownTag) {
343
+ throw new Error(
344
+ `Unknown tag "${unknownTag}". Available tags: ${projectConfig.tags.join(", ") || "none"}.`,
345
+ );
346
+ }
347
+
348
+ const selectedTargets = await resolveTargets(datasource, options.target, {
349
+ defaultToAll: false,
350
+ requireTargets: false,
351
+ });
616
352
 
617
353
  console.log("\nGenerating TypeScript code...\n");
618
354
 
@@ -710,7 +446,6 @@ ${attributeProperties}
710
446
  const parsedFeatures: {
711
447
  featureKey: string;
712
448
  parsedFeature: ParsedFeature;
713
- namespaceValue: string;
714
449
  }[] = [];
715
450
 
716
451
  for (const featureKey of featureFiles) {
@@ -720,117 +455,20 @@ ${attributeProperties}
720
455
  continue;
721
456
  }
722
457
 
723
- if (selectedTags.length > 0) {
724
- const featureTags = Array.isArray(parsedFeature.tags) ? parsedFeature.tags : [];
725
- const hasTags = selectedTags.every((tag) => featureTags.includes(tag));
726
- if (!hasTags) {
727
- continue;
728
- }
458
+ const featureTags = Array.isArray(parsedFeature.tags) ? parsedFeature.tags : [];
459
+ const matchesSelectedTag = selectedTags.some((tag) => featureTags.includes(tag));
460
+ const matchesSelectedTarget = selectedTargets.some((target) =>
461
+ targetIncludesFeature(target, featureKey, parsedFeature),
462
+ );
463
+ if (
464
+ (selectedTags.length > 0 || selectedTargets.length > 0) &&
465
+ !matchesSelectedTag &&
466
+ !matchesSelectedTarget
467
+ ) {
468
+ continue;
729
469
  }
730
470
 
731
- const namespaceValue = getPascalCase(featureKey) + "Feature";
732
- parsedFeatures.push({ featureKey, parsedFeature, namespaceValue });
733
- }
734
-
735
- const featureNamespaces: string[] = [];
736
- if (shouldGenerateIndividualFeatures) {
737
- for (const { featureKey, parsedFeature, namespaceValue } of parsedFeatures) {
738
- featureNamespaces.push(namespaceValue);
739
-
740
- let variableTypeDeclarations = "";
741
- let variableMethods = "";
742
- const featureSchemaTypesUsed = new Set<string>();
743
-
744
- if (parsedFeature.variablesSchema) {
745
- const variableKeys = Object.keys(parsedFeature.variablesSchema);
746
- const allDeclarations: string[] = [];
747
-
748
- for (const variableKey of variableKeys) {
749
- const variableSchema = parsedFeature.variablesSchema[variableKey];
750
- const effective = getEffectiveVariableSchema(variableSchema, schemasByKey);
751
- const variableType = effective?.type;
752
- const {
753
- declarations,
754
- returnTypeName,
755
- genericArg,
756
- isLiteralType,
757
- useGetVariable,
758
- schemaTypesUsed,
759
- } = generateVariableTypeDeclarations(
760
- variableKey,
761
- variableSchema,
762
- schemasByKey,
763
- hasSchemasFile ? schemaTypeNames : undefined,
764
- );
765
- schemaTypesUsed.forEach((t) => featureSchemaTypesUsed.add(t));
766
- allDeclarations.push(...declarations);
767
-
768
- const internalMethodName = `getVariable${
769
- variableType === "json" ? "JSON" : getPascalCase(variableType ?? "string")
770
- }`;
771
-
772
- const hasGeneric =
773
- variableType === "json" || variableType === "array" || variableType === "object";
774
- const literalAssertion = isLiteralType ? ` as ${returnTypeName} | null` : "";
775
- if (useGetVariable) {
776
- variableMethods += `
777
-
778
- ${INDENT_NS}export function get${getPascalCase(variableKey)}(context: Context = {}): ${returnTypeName} | null {
779
- ${INDENT_NS_BODY}return getInstance().getVariable(key, "${variableKey}", context)${literalAssertion};
780
- ${INDENT_NS}}`;
781
- } else if (variableType === "json") {
782
- variableMethods += `
783
-
784
- ${INDENT_NS}export function get${getPascalCase(variableKey)}<T = unknown>(context: Context = {}): T | null {
785
- ${INDENT_NS_BODY}return getInstance().${internalMethodName}<T>(key, "${variableKey}", context);
786
- ${INDENT_NS}}`;
787
- } else if (hasGeneric) {
788
- variableMethods += `
789
-
790
- ${INDENT_NS}export function get${getPascalCase(variableKey)}(context: Context = {}): ${returnTypeName} | null {
791
- ${INDENT_NS_BODY}return getInstance().${internalMethodName}<${genericArg}>(key, "${variableKey}", context);
792
- ${INDENT_NS}}`;
793
- } else {
794
- variableMethods += `
795
-
796
- ${INDENT_NS}export function get${getPascalCase(variableKey)}(context: Context = {}): ${returnTypeName} | null {
797
- ${INDENT_NS_BODY}return getInstance().${internalMethodName}(key, "${variableKey}", context)${literalAssertion};
798
- ${INDENT_NS}}`;
799
- }
800
- }
801
-
802
- if (allDeclarations.length > 0) {
803
- variableTypeDeclarations = "\n\n" + allDeclarations.join("\n\n");
804
- }
805
- }
806
-
807
- const schemasImportLine = formatTypeImport([...featureSchemaTypesUsed].sort(), "./schemas");
808
-
809
- const featureContent = `
810
- import { Context } from "./context";
811
- import { getInstance } from "./instance";
812
- ${schemasImportLine}export namespace ${namespaceValue} {
813
- ${INDENT_NS}export const key = "${featureKey}";${variableTypeDeclarations}
814
-
815
- ${INDENT_NS}export function isEnabled(context: Context = {}) {
816
- ${INDENT_NS_BODY}return getInstance().isEnabled(key, context);
817
- ${INDENT_NS}}
818
-
819
- ${INDENT_NS}export function getVariation(context: Context = {}) {
820
- ${INDENT_NS_BODY}return getInstance().getVariation(key, context);
821
- ${INDENT_NS}}${variableMethods}
822
- }
823
- `.trimStart();
824
-
825
- const featureNamespaceFilePath = path.join(outputPath, `${namespaceValue}.ts`);
826
- fs.writeFileSync(featureNamespaceFilePath, featureContent);
827
- console.log(
828
- `Feature ${featureKey} file written at: ${getRelativePath(
829
- rootDirectoryPath,
830
- featureNamespaceFilePath,
831
- )}`,
832
- );
833
- }
471
+ parsedFeatures.push({ featureKey, parsedFeature });
834
472
  }
835
473
 
836
474
  const featuresTypeSchemasUsed = new Set<string>();
@@ -963,9 +601,6 @@ export function useVariable<F extends FeatureKey, V extends VariableKey<F>>(
963
601
  `export * from "./features";`,
964
602
  `export * from "./functions";`,
965
603
  ...(shouldGenerateReact ? [`export * from "./react";`] : []),
966
- ...featureNamespaces.map((featureNamespace) => {
967
- return `export * from "./${featureNamespace}";`;
968
- }),
969
604
  ].join("\n") + "\n";
970
605
  const indexFilePath = path.join(outputPath, "index.ts");
971
606
  fs.writeFileSync(indexFilePath, indexContent);
package/src/index.ts CHANGED
@@ -3,7 +3,6 @@ export * from "./linter";
3
3
  export * from "./builder";
4
4
  export * from "./tester";
5
5
  export * from "./init";
6
- export * from "./site";
7
6
  export * from "./generate-code";
8
7
  export * from "./find-duplicate-segments";
9
8
  export * from "./find-usage";
@@ -14,6 +13,8 @@ export * from "./evaluate";
14
13
  export * from "./assess-distribution";
15
14
  export * from "./info";
16
15
  export * from "./list";
16
+ export * from "./sets";
17
+ export * from "./promoter";
17
18
  export * from "./cli";
18
19
 
19
20
  export * from "@featurevisor/parsers";
package/src/info/index.ts CHANGED
@@ -1,14 +1,62 @@
1
1
  import { Dependencies } from "../dependencies";
2
2
  import { getMatrixCombinations } from "../list/matrix";
3
3
  import { Plugin } from "../cli";
4
+ import { getProjectSetExecutions, printSetHeader } from "../sets";
5
+ import { CLI_COLOR_CYAN, CLI_FORMAT_BOLD, colorize } from "../tester/cliFormat";
6
+ import { buildRuntimeDatafiles } from "../builder/buildRuntimeDatafiles";
7
+
8
+ async function showTargetInfo(deps: Dependencies, target: string | string[]) {
9
+ const { projectConfig } = deps;
10
+ const environments = Array.isArray(projectConfig.environments)
11
+ ? projectConfig.environments
12
+ : [false as const];
13
+
14
+ for (const environment of environments) {
15
+ const datafiles = await buildRuntimeDatafiles(deps, {
16
+ environment,
17
+ target,
18
+ revision: "info",
19
+ });
20
+
21
+ for (const entry of datafiles) {
22
+ const variables = Object.values(entry.datafile.features).reduce((count, feature) => {
23
+ const schemas = feature.variablesSchema;
24
+ return (
25
+ count + (Array.isArray(schemas) ? schemas.length : Object.keys(schemas || {}).length)
26
+ );
27
+ }, 0);
28
+
29
+ console.log("");
30
+ console.log(CLI_FORMAT_BOLD, `Target "${entry.target}"`);
31
+ console.log(` ${colorize("Environment", CLI_COLOR_CYAN)}: ${environment}`);
32
+ console.log(
33
+ ` ${colorize("Features", CLI_COLOR_CYAN)}: ${Object.keys(entry.datafile.features).length}`,
34
+ );
35
+ console.log(
36
+ ` ${colorize("Segments", CLI_COLOR_CYAN)}: ${Object.keys(entry.datafile.segments).length}`,
37
+ );
38
+ console.log(` ${colorize("Variables", CLI_COLOR_CYAN)}: ${variables}`);
39
+ console.log(
40
+ ` ${colorize("Datafile size", CLI_COLOR_CYAN)}: ${(JSON.stringify(entry.datafile).length / 1024).toFixed(2)} kB`,
41
+ );
42
+ }
43
+ }
44
+ }
4
45
 
5
46
  export async function showProjectInfo(deps: Dependencies) {
6
- const { datasource } = deps;
47
+ const { datasource, options } = deps;
7
48
 
8
- console.log("\nProject info:\n");
49
+ if (options.target) {
50
+ await showTargetInfo(deps, options.target);
51
+ return;
52
+ }
53
+
54
+ console.log("");
55
+ console.log(CLI_FORMAT_BOLD, "Project info");
56
+ console.log("");
9
57
 
10
58
  const revision = await datasource.readRevision();
11
- console.log(" - Revision: ", revision);
59
+ console.log(` ${colorize("Revision", CLI_COLOR_CYAN)}: ${revision}`);
12
60
 
13
61
  console.log("");
14
62
 
@@ -16,6 +64,7 @@ export async function showProjectInfo(deps: Dependencies) {
16
64
  const segments = await datasource.listSegments();
17
65
  const features = await datasource.listFeatures();
18
66
  const groups = await datasource.listGroups();
67
+ const targets = await datasource.listTargets();
19
68
 
20
69
  let variablesCount = 0;
21
70
  for (const featureKey of features) {
@@ -26,16 +75,17 @@ export async function showProjectInfo(deps: Dependencies) {
26
75
  }
27
76
  }
28
77
 
29
- console.log(" - Total attributes: ", attributes.length);
30
- console.log(" - Total segments: ", segments.length);
31
- console.log(" - Total features: ", features.length);
32
- console.log(" - Total variables: ", variablesCount);
33
- console.log(" - Total groups: ", groups.length);
78
+ console.log(` ${colorize("Total attributes", CLI_COLOR_CYAN)}: ${attributes.length}`);
79
+ console.log(` ${colorize("Total segments", CLI_COLOR_CYAN)}: ${segments.length}`);
80
+ console.log(` ${colorize("Total features", CLI_COLOR_CYAN)}: ${features.length}`);
81
+ console.log(` ${colorize("Total variables", CLI_COLOR_CYAN)}: ${variablesCount}`);
82
+ console.log(` ${colorize("Total groups", CLI_COLOR_CYAN)}: ${groups.length}`);
83
+ console.log(` ${colorize("Total targets", CLI_COLOR_CYAN)}: ${targets.length}`);
34
84
 
35
85
  console.log("");
36
86
 
37
87
  const tests = await datasource.listTests();
38
- console.log(" - Total test specs: ", tests.length);
88
+ console.log(` ${colorize("Total test specs", CLI_COLOR_CYAN)}: ${tests.length}`);
39
89
 
40
90
  let assertionsCount = 0;
41
91
  for (const test of tests) {
@@ -51,18 +101,24 @@ export async function showProjectInfo(deps: Dependencies) {
51
101
  }
52
102
  }
53
103
 
54
- console.log(" - Total assertions: ", assertionsCount);
104
+ console.log(` ${colorize("Total assertions", CLI_COLOR_CYAN)}: ${assertionsCount}`);
55
105
  }
56
106
 
57
107
  export const infoPlugin: Plugin = {
58
108
  command: "info",
59
109
  handler: async function ({ rootDirectoryPath, projectConfig, datasource, parsed }) {
60
- await showProjectInfo({
61
- rootDirectoryPath,
62
- projectConfig,
63
- datasource,
64
- options: parsed,
65
- });
110
+ const executions = await getProjectSetExecutions(projectConfig, datasource, parsed.set);
111
+
112
+ for (const execution of executions) {
113
+ printSetHeader(projectConfig, execution.set);
114
+
115
+ await showProjectInfo({
116
+ rootDirectoryPath,
117
+ projectConfig: execution.projectConfig,
118
+ datasource: execution.datasource,
119
+ options: parsed,
120
+ });
121
+ }
66
122
  },
67
123
  examples: [
68
124
  {
package/src/init/index.ts CHANGED
@@ -5,7 +5,7 @@ import { Plugin } from "../cli";
5
5
 
6
6
  export const DEFAULT_EXAMPLE = "yml";
7
7
 
8
- export const EXAMPLES_ORG_NAME = "fahad19";
8
+ export const EXAMPLES_ORG_NAME = "featurevisor";
9
9
  export const EXAMPLES_REPO_NAME = "featurevisor";
10
10
  export const EXAMPLES_BRANCH_NAME = "main";
11
11
 
@@ -552,6 +552,7 @@ export function getAttributeZodSchema() {
552
552
  const attributeZodSchema = z
553
553
  .object({
554
554
  archived: z.boolean().optional(),
555
+ promotable: z.boolean().optional(),
555
556
  type: attributeTypeEnum.optional(),
556
557
  description: z.string(),
557
558
  enum: z.array(valueZodSchema).optional(),