@featurevisor/core 2.14.0 → 2.15.0

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 (93) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/coverage/clover.xml +774 -652
  3. package/coverage/coverage-final.json +19 -18
  4. package/coverage/lcov-report/builder/allocator.ts.html +1 -1
  5. package/coverage/lcov-report/builder/buildScopedConditions.ts.html +1 -1
  6. package/coverage/lcov-report/builder/buildScopedDatafile.ts.html +1 -1
  7. package/coverage/lcov-report/builder/buildScopedSegments.ts.html +1 -1
  8. package/coverage/lcov-report/builder/index.html +1 -1
  9. package/coverage/lcov-report/builder/mutateVariables.ts.html +1 -1
  10. package/coverage/lcov-report/builder/mutator.ts.html +1 -1
  11. package/coverage/lcov-report/builder/revision.ts.html +1 -1
  12. package/coverage/lcov-report/builder/traffic.ts.html +1 -1
  13. package/coverage/lcov-report/config/index.html +30 -15
  14. package/coverage/lcov-report/config/index.ts.html +88 -0
  15. package/coverage/lcov-report/config/projectConfig.ts.html +79 -46
  16. package/coverage/lcov-report/datasource/adapter.ts.html +74 -11
  17. package/coverage/lcov-report/datasource/datasource.ts.html +76 -25
  18. package/coverage/lcov-report/datasource/filesystemAdapter.ts.html +690 -66
  19. package/coverage/lcov-report/datasource/index.html +35 -35
  20. package/coverage/lcov-report/datasource/index.ts.html +1 -1
  21. package/coverage/lcov-report/index.html +43 -43
  22. package/coverage/lcov-report/linter/attributeSchema.ts.html +4 -4
  23. package/coverage/lcov-report/linter/checkCircularDependency.ts.html +1 -1
  24. package/coverage/lcov-report/linter/checkPercentageExceedingSlot.ts.html +1 -1
  25. package/coverage/lcov-report/linter/conditionSchema.ts.html +7 -7
  26. package/coverage/lcov-report/linter/featureSchema.ts.html +152 -164
  27. package/coverage/lcov-report/linter/groupSchema.ts.html +3 -3
  28. package/coverage/lcov-report/linter/index.html +34 -34
  29. package/coverage/lcov-report/linter/lintProject.ts.html +428 -83
  30. package/coverage/lcov-report/linter/mutationNotation.ts.html +3 -3
  31. package/coverage/lcov-report/linter/printError.ts.html +9 -9
  32. package/coverage/lcov-report/linter/schema.ts.html +4 -4
  33. package/coverage/lcov-report/linter/segmentSchema.ts.html +3 -3
  34. package/coverage/lcov-report/linter/testSchema.ts.html +6 -6
  35. package/coverage/lcov-report/list/index.html +1 -1
  36. package/coverage/lcov-report/list/matrix.ts.html +1 -1
  37. package/coverage/lcov-report/parsers/index.html +1 -1
  38. package/coverage/lcov-report/parsers/index.ts.html +4 -4
  39. package/coverage/lcov-report/parsers/json.ts.html +2 -2
  40. package/coverage/lcov-report/parsers/yml.ts.html +6 -6
  41. package/coverage/lcov-report/tester/cliFormat.ts.html +1 -1
  42. package/coverage/lcov-report/tester/helpers.ts.html +1 -1
  43. package/coverage/lcov-report/tester/index.html +1 -1
  44. package/coverage/lcov-report/utils/git.ts.html +118 -16
  45. package/coverage/lcov-report/utils/index.html +14 -14
  46. package/coverage/lcov.info +1374 -1107
  47. package/lib/config/projectConfig.d.ts +3 -0
  48. package/lib/config/projectConfig.js +7 -1
  49. package/lib/config/projectConfig.js.map +1 -1
  50. package/lib/config/projectConfig.spec.d.ts +1 -0
  51. package/lib/config/projectConfig.spec.js +24 -0
  52. package/lib/config/projectConfig.spec.js.map +1 -0
  53. package/lib/datasource/adapter.d.ts +7 -0
  54. package/lib/datasource/adapter.js +7 -0
  55. package/lib/datasource/adapter.js.map +1 -1
  56. package/lib/datasource/datasource.d.ts +3 -1
  57. package/lib/datasource/datasource.js +6 -0
  58. package/lib/datasource/datasource.js.map +1 -1
  59. package/lib/datasource/filesystemAdapter.d.ts +8 -0
  60. package/lib/datasource/filesystemAdapter.js +134 -7
  61. package/lib/datasource/filesystemAdapter.js.map +1 -1
  62. package/lib/datasource/filesystemAdapter.spec.d.ts +1 -0
  63. package/lib/datasource/filesystemAdapter.spec.js +88 -0
  64. package/lib/datasource/filesystemAdapter.spec.js.map +1 -0
  65. package/lib/linter/conditionSchema.spec.js +2 -0
  66. package/lib/linter/conditionSchema.spec.js.map +1 -1
  67. package/lib/linter/featureSchema.js +46 -49
  68. package/lib/linter/featureSchema.js.map +1 -1
  69. package/lib/linter/featureSchema.spec.js +17 -0
  70. package/lib/linter/featureSchema.spec.js.map +1 -1
  71. package/lib/linter/lintProject.d.ts +2 -0
  72. package/lib/linter/lintProject.js +85 -8
  73. package/lib/linter/lintProject.js.map +1 -1
  74. package/lib/linter/lintProject.spec.js +37 -0
  75. package/lib/linter/lintProject.spec.js.map +1 -1
  76. package/lib/linter/segmentSchema.spec.js +2 -0
  77. package/lib/linter/segmentSchema.spec.js.map +1 -1
  78. package/lib/utils/git.js +32 -7
  79. package/lib/utils/git.js.map +1 -1
  80. package/package.json +2 -2
  81. package/src/config/projectConfig.spec.ts +31 -0
  82. package/src/config/projectConfig.ts +11 -0
  83. package/src/datasource/adapter.ts +21 -0
  84. package/src/datasource/datasource.ts +18 -1
  85. package/src/datasource/filesystemAdapter.spec.ts +153 -0
  86. package/src/datasource/filesystemAdapter.ts +216 -8
  87. package/src/linter/conditionSchema.spec.ts +2 -0
  88. package/src/linter/featureSchema.spec.ts +21 -0
  89. package/src/linter/featureSchema.ts +84 -88
  90. package/src/linter/lintProject.spec.ts +74 -0
  91. package/src/linter/lintProject.ts +123 -8
  92. package/src/linter/segmentSchema.spec.ts +2 -0
  93. package/src/utils/git.ts +41 -7
@@ -205,7 +205,7 @@ export function getUpdatedAvailableRangesAfterFilling(
205
205
  <div class='footer quiet pad2 space-top1 center small'>
206
206
  Code coverage generated by
207
207
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
208
- at 2026-02-24T19:50:30.107Z
208
+ at 2026-02-25T22:03:15.189Z
209
209
  </div>
210
210
  <script src="../prettify.js"></script>
211
211
  <script>
@@ -472,7 +472,7 @@ export function buildScopedCondition(
472
472
  <div class='footer quiet pad2 space-top1 center small'>
473
473
  Code coverage generated by
474
474
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
475
- at 2026-02-24T19:50:30.107Z
475
+ at 2026-02-25T22:03:15.189Z
476
476
  </div>
477
477
  <script src="../prettify.js"></script>
478
478
  <script>
@@ -589,7 +589,7 @@ export function buildScopedDatafile(
589
589
  <div class='footer quiet pad2 space-top1 center small'>
590
590
  Code coverage generated by
591
591
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
592
- at 2026-02-24T19:50:30.107Z
592
+ at 2026-02-25T22:03:15.189Z
593
593
  </div>
594
594
  <script src="../prettify.js"></script>
595
595
  <script>
@@ -529,7 +529,7 @@ export function buildScopedGroupSegments(
529
529
  <div class='footer quiet pad2 space-top1 center small'>
530
530
  Code coverage generated by
531
531
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
532
- at 2026-02-24T19:50:30.107Z
532
+ at 2026-02-25T22:03:15.189Z
533
533
  </div>
534
534
  <script src="../prettify.js"></script>
535
535
  <script>
@@ -206,7 +206,7 @@
206
206
  <div class='footer quiet pad2 space-top1 center small'>
207
207
  Code coverage generated by
208
208
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
209
- at 2026-02-24T19:50:30.107Z
209
+ at 2026-02-25T22:03:15.189Z
210
210
  </div>
211
211
  <script src="../prettify.js"></script>
212
212
  <script>
@@ -385,7 +385,7 @@ export function resolveMutationsForSingleVariable(
385
385
  <div class='footer quiet pad2 space-top1 center small'>
386
386
  Code coverage generated by
387
387
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
388
- at 2026-02-24T19:50:30.107Z
388
+ at 2026-02-25T22:03:15.189Z
389
389
  </div>
390
390
  <script src="../prettify.js"></script>
391
391
  <script>
@@ -781,7 +781,7 @@ export function mutate(
781
781
  <div class='footer quiet pad2 space-top1 center small'>
782
782
  Code coverage generated by
783
783
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
784
- at 2026-02-24T19:50:30.107Z
784
+ at 2026-02-25T22:03:15.189Z
785
785
  </div>
786
786
  <script src="../prettify.js"></script>
787
787
  <script>
@@ -136,7 +136,7 @@
136
136
  <div class='footer quiet pad2 space-top1 center small'>
137
137
  Code coverage generated by
138
138
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
139
- at 2026-02-24T19:50:30.107Z
139
+ at 2026-02-25T22:03:15.189Z
140
140
  </div>
141
141
  <script src="../prettify.js"></script>
142
142
  <script>
@@ -643,7 +643,7 @@ export function getTraffic(
643
643
  <div class='footer quiet pad2 space-top1 center small'>
644
644
  Code coverage generated by
645
645
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
646
- at 2026-02-24T19:50:30.107Z
646
+ at 2026-02-25T22:03:15.189Z
647
647
  </div>
648
648
  <script src="../prettify.js"></script>
649
649
  <script>
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">70.9% </span>
26
+ <span class="strong">72.88% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>39/55</span>
28
+ <span class='fraction'>43/59</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">35.71% </span>
33
+ <span class="strong">47.05% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>5/14</span>
35
+ <span class='fraction'>8/17</span>
36
36
  </div>
37
37
 
38
38
 
@@ -44,9 +44,9 @@
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">72.22% </span>
47
+ <span class="strong">74.13% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>39/54</span>
49
+ <span class='fraction'>43/58</span>
50
50
  </div>
51
51
 
52
52
 
@@ -79,18 +79,33 @@
79
79
  </tr>
80
80
  </thead>
81
81
  <tbody><tr>
82
+ <td class="file high" data-value="index.ts"><a href="index.ts.html">index.ts</a></td>
83
+ <td data-value="100" class="pic high">
84
+ <div class="chart"><div class="cover-fill cover-full" style="width: 100%"></div><div class="cover-empty" style="width: 0%"></div></div>
85
+ </td>
86
+ <td data-value="100" class="pct high">100%</td>
87
+ <td data-value="1" class="abs high">1/1</td>
88
+ <td data-value="100" class="pct high">100%</td>
89
+ <td data-value="0" class="abs high">0/0</td>
90
+ <td data-value="100" class="pct high">100%</td>
91
+ <td data-value="0" class="abs high">0/0</td>
92
+ <td data-value="100" class="pct high">100%</td>
93
+ <td data-value="1" class="abs high">1/1</td>
94
+ </tr>
95
+
96
+ <tr>
82
97
  <td class="file medium" data-value="projectConfig.ts"><a href="projectConfig.ts.html">projectConfig.ts</a></td>
83
- <td data-value="70.9" class="pic medium">
84
- <div class="chart"><div class="cover-fill" style="width: 70%"></div><div class="cover-empty" style="width: 30%"></div></div>
98
+ <td data-value="72.41" class="pic medium">
99
+ <div class="chart"><div class="cover-fill" style="width: 72%"></div><div class="cover-empty" style="width: 28%"></div></div>
85
100
  </td>
86
- <td data-value="70.9" class="pct medium">70.9%</td>
87
- <td data-value="55" class="abs medium">39/55</td>
88
- <td data-value="35.71" class="pct low">35.71%</td>
89
- <td data-value="14" class="abs low">5/14</td>
101
+ <td data-value="72.41" class="pct medium">72.41%</td>
102
+ <td data-value="58" class="abs medium">42/58</td>
103
+ <td data-value="47.05" class="pct low">47.05%</td>
104
+ <td data-value="17" class="abs low">8/17</td>
90
105
  <td data-value="40" class="pct low">40%</td>
91
106
  <td data-value="5" class="abs low">2/5</td>
92
- <td data-value="72.22" class="pct medium">72.22%</td>
93
- <td data-value="54" class="abs medium">39/54</td>
107
+ <td data-value="73.68" class="pct medium">73.68%</td>
108
+ <td data-value="57" class="abs medium">42/57</td>
94
109
  </tr>
95
110
 
96
111
  </tbody>
@@ -101,7 +116,7 @@
101
116
  <div class='footer quiet pad2 space-top1 center small'>
102
117
  Code coverage generated by
103
118
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
104
- at 2026-02-24T19:50:30.107Z
119
+ at 2026-02-25T22:03:15.189Z
105
120
  </div>
106
121
  <script src="../prettify.js"></script>
107
122
  <script>
@@ -0,0 +1,88 @@
1
+
2
+ <!doctype html>
3
+ <html lang="en">
4
+
5
+ <head>
6
+ <title>Code coverage report for config/index.ts</title>
7
+ <meta charset="utf-8" />
8
+ <link rel="stylesheet" href="../prettify.css" />
9
+ <link rel="stylesheet" href="../base.css" />
10
+ <link rel="shortcut icon" type="image/x-icon" href="../favicon.png" />
11
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
12
+ <style type='text/css'>
13
+ .coverage-summary .sorter {
14
+ background-image: url(../sort-arrow-sprite.png);
15
+ }
16
+ </style>
17
+ </head>
18
+
19
+ <body>
20
+ <div class='wrapper'>
21
+ <div class='pad1'>
22
+ <h1><a href="../index.html">All files</a> / <a href="index.html">config</a> index.ts</h1>
23
+ <div class='clearfix'>
24
+
25
+ <div class='fl pad1y space-right2'>
26
+ <span class="strong">100% </span>
27
+ <span class="quiet">Statements</span>
28
+ <span class='fraction'>1/1</span>
29
+ </div>
30
+
31
+
32
+ <div class='fl pad1y space-right2'>
33
+ <span class="strong">100% </span>
34
+ <span class="quiet">Branches</span>
35
+ <span class='fraction'>0/0</span>
36
+ </div>
37
+
38
+
39
+ <div class='fl pad1y space-right2'>
40
+ <span class="strong">100% </span>
41
+ <span class="quiet">Functions</span>
42
+ <span class='fraction'>0/0</span>
43
+ </div>
44
+
45
+
46
+ <div class='fl pad1y space-right2'>
47
+ <span class="strong">100% </span>
48
+ <span class="quiet">Lines</span>
49
+ <span class='fraction'>1/1</span>
50
+ </div>
51
+
52
+
53
+ </div>
54
+ <p class="quiet">
55
+ Press <em>n</em> or <em>j</em> to go to the next uncovered block, <em>b</em>, <em>p</em> or <em>k</em> for the previous block.
56
+ </p>
57
+ <template id="filterTemplate">
58
+ <div class="quiet">
59
+ Filter:
60
+ <input oninput="onInput()" type="search" id="fileSearch">
61
+ </div>
62
+ </template>
63
+ </div>
64
+ <div class='status-line high'></div>
65
+ <pre><table class="coverage">
66
+ <tr><td class="line-count quiet"><a name='L1'></a><a href='#L1'>1</a>
67
+ <a name='L2'></a><a href='#L2'>2</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
68
+ <span class="cline-any cline-neutral">&nbsp;</span></td><td class="text"><pre class="prettyprint lang-js">export * from "./projectConfig";
69
+ &nbsp;</pre></td></tr></table></pre>
70
+
71
+ <div class='push'></div><!-- for sticky footer -->
72
+ </div><!-- /wrapper -->
73
+ <div class='footer quiet pad2 space-top1 center small'>
74
+ Code coverage generated by
75
+ <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
76
+ at 2026-02-25T22:03:15.189Z
77
+ </div>
78
+ <script src="../prettify.js"></script>
79
+ <script>
80
+ window.onload = function () {
81
+ prettyPrint();
82
+ };
83
+ </script>
84
+ <script src="../sorter.js"></script>
85
+ <script src="../block-navigation.js"></script>
86
+ </body>
87
+ </html>
88
+
@@ -23,16 +23,16 @@
23
23
  <div class='clearfix'>
24
24
 
25
25
  <div class='fl pad1y space-right2'>
26
- <span class="strong">70.9% </span>
26
+ <span class="strong">72.41% </span>
27
27
  <span class="quiet">Statements</span>
28
- <span class='fraction'>39/55</span>
28
+ <span class='fraction'>42/58</span>
29
29
  </div>
30
30
 
31
31
 
32
32
  <div class='fl pad1y space-right2'>
33
- <span class="strong">35.71% </span>
33
+ <span class="strong">47.05% </span>
34
34
  <span class="quiet">Branches</span>
35
- <span class='fraction'>5/14</span>
35
+ <span class='fraction'>8/17</span>
36
36
  </div>
37
37
 
38
38
 
@@ -44,9 +44,9 @@
44
44
 
45
45
 
46
46
  <div class='fl pad1y space-right2'>
47
- <span class="strong">72.22% </span>
47
+ <span class="strong">73.68% </span>
48
48
  <span class="quiet">Lines</span>
49
- <span class='fraction'>39/54</span>
49
+ <span class='fraction'>42/57</span>
50
50
  </div>
51
51
 
52
52
 
@@ -260,40 +260,53 @@
260
260
  <a name='L195'></a><a href='#L195'>195</a>
261
261
  <a name='L196'></a><a href='#L196'>196</a>
262
262
  <a name='L197'></a><a href='#L197'>197</a>
263
- <a name='L198'></a><a href='#L198'>198</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">1x</span>
263
+ <a name='L198'></a><a href='#L198'>198</a>
264
+ <a name='L199'></a><a href='#L199'>199</a>
265
+ <a name='L200'></a><a href='#L200'>200</a>
266
+ <a name='L201'></a><a href='#L201'>201</a>
267
+ <a name='L202'></a><a href='#L202'>202</a>
268
+ <a name='L203'></a><a href='#L203'>203</a>
269
+ <a name='L204'></a><a href='#L204'>204</a>
270
+ <a name='L205'></a><a href='#L205'>205</a>
271
+ <a name='L206'></a><a href='#L206'>206</a>
272
+ <a name='L207'></a><a href='#L207'>207</a>
273
+ <a name='L208'></a><a href='#L208'>208</a>
274
+ <a name='L209'></a><a href='#L209'>209</a></td><td class="line-coverage quiet"><span class="cline-any cline-yes">3x</span>
264
275
  <span class="cline-any cline-neutral">&nbsp;</span>
265
276
  <span class="cline-any cline-neutral">&nbsp;</span>
266
277
  <span class="cline-any cline-neutral">&nbsp;</span>
267
- <span class="cline-any cline-yes">1x</span>
268
- <span class="cline-any cline-yes">1x</span>
278
+ <span class="cline-any cline-yes">3x</span>
279
+ <span class="cline-any cline-yes">3x</span>
269
280
  <span class="cline-any cline-neutral">&nbsp;</span>
270
281
  <span class="cline-any cline-neutral">&nbsp;</span>
271
282
  <span class="cline-any cline-neutral">&nbsp;</span>
272
- <span class="cline-any cline-yes">1x</span>
273
- <span class="cline-any cline-yes">1x</span>
274
- <span class="cline-any cline-yes">1x</span>
275
- <span class="cline-any cline-yes">1x</span>
276
- <span class="cline-any cline-yes">1x</span>
277
- <span class="cline-any cline-yes">1x</span>
278
- <span class="cline-any cline-yes">1x</span>
279
- <span class="cline-any cline-yes">1x</span>
280
- <span class="cline-any cline-yes">1x</span>
281
- <span class="cline-any cline-yes">1x</span>
282
- <span class="cline-any cline-yes">1x</span>
283
+ <span class="cline-any cline-yes">3x</span>
284
+ <span class="cline-any cline-yes">3x</span>
285
+ <span class="cline-any cline-yes">3x</span>
286
+ <span class="cline-any cline-yes">3x</span>
287
+ <span class="cline-any cline-yes">3x</span>
288
+ <span class="cline-any cline-yes">3x</span>
289
+ <span class="cline-any cline-yes">3x</span>
290
+ <span class="cline-any cline-yes">3x</span>
291
+ <span class="cline-any cline-yes">3x</span>
292
+ <span class="cline-any cline-yes">3x</span>
293
+ <span class="cline-any cline-yes">3x</span>
294
+ <span class="cline-any cline-yes">3x</span>
283
295
  <span class="cline-any cline-neutral">&nbsp;</span>
284
- <span class="cline-any cline-yes">1x</span>
285
- <span class="cline-any cline-yes">1x</span>
296
+ <span class="cline-any cline-yes">3x</span>
297
+ <span class="cline-any cline-yes">3x</span>
286
298
  <span class="cline-any cline-neutral">&nbsp;</span>
287
- <span class="cline-any cline-yes">1x</span>
288
- <span class="cline-any cline-yes">1x</span>
289
- <span class="cline-any cline-yes">1x</span>
299
+ <span class="cline-any cline-yes">3x</span>
300
+ <span class="cline-any cline-yes">3x</span>
301
+ <span class="cline-any cline-yes">3x</span>
290
302
  <span class="cline-any cline-neutral">&nbsp;</span>
291
- <span class="cline-any cline-yes">1x</span>
292
- <span class="cline-any cline-yes">1x</span>
303
+ <span class="cline-any cline-yes">3x</span>
304
+ <span class="cline-any cline-yes">3x</span>
293
305
  <span class="cline-any cline-neutral">&nbsp;</span>
294
- <span class="cline-any cline-yes">1x</span>
306
+ <span class="cline-any cline-yes">3x</span>
307
+ <span class="cline-any cline-neutral">&nbsp;</span>
308
+ <span class="cline-any cline-yes">3x</span>
295
309
  <span class="cline-any cline-neutral">&nbsp;</span>
296
- <span class="cline-any cline-yes">1x</span>
297
310
  <span class="cline-any cline-neutral">&nbsp;</span>
298
311
  <span class="cline-any cline-neutral">&nbsp;</span>
299
312
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -337,9 +350,9 @@
337
350
  <span class="cline-any cline-neutral">&nbsp;</span>
338
351
  <span class="cline-any cline-neutral">&nbsp;</span>
339
352
  <span class="cline-any cline-neutral">&nbsp;</span>
340
- <span class="cline-any cline-yes">1x</span>
341
- <span class="cline-any cline-yes">4x</span>
342
353
  <span class="cline-any cline-neutral">&nbsp;</span>
354
+ <span class="cline-any cline-yes">3x</span>
355
+ <span class="cline-any cline-yes">12x</span>
343
356
  <span class="cline-any cline-neutral">&nbsp;</span>
344
357
  <span class="cline-any cline-neutral">&nbsp;</span>
345
358
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -373,40 +386,49 @@
373
386
  <span class="cline-any cline-neutral">&nbsp;</span>
374
387
  <span class="cline-any cline-neutral">&nbsp;</span>
375
388
  <span class="cline-any cline-neutral">&nbsp;</span>
376
- <span class="cline-any cline-yes">4x</span>
377
- <span class="cline-any cline-yes">4x</span>
378
389
  <span class="cline-any cline-neutral">&nbsp;</span>
379
- <span class="cline-any cline-yes">4x</span>
380
390
  <span class="cline-any cline-neutral">&nbsp;</span>
381
- <span class="cline-any cline-yes">4x</span>
382
- <span class="cline-any cline-yes">104x</span>
383
391
  <span class="cline-any cline-neutral">&nbsp;</span>
392
+ <span class="cline-any cline-yes">12x</span>
393
+ <span class="cline-any cline-yes">12x</span>
384
394
  <span class="cline-any cline-neutral">&nbsp;</span>
385
- <span class="cline-any cline-yes">104x</span>
395
+ <span class="cline-any cline-yes">12x</span>
396
+ <span class="cline-any cline-neutral">&nbsp;</span>
397
+ <span class="cline-any cline-yes">12x</span>
398
+ <span class="cline-any cline-yes">336x</span>
399
+ <span class="cline-any cline-neutral">&nbsp;</span>
400
+ <span class="cline-any cline-neutral">&nbsp;</span>
401
+ <span class="cline-any cline-yes">336x</span>
386
402
  <span class="cline-any cline-no">&nbsp;</span>
387
403
  <span class="cline-any cline-neutral">&nbsp;</span>
388
404
  <span class="cline-any cline-neutral">&nbsp;</span>
389
405
  <span class="cline-any cline-neutral">&nbsp;</span>
390
- <span class="cline-any cline-yes">4x</span>
406
+ <span class="cline-any cline-yes">12x</span>
391
407
  <span class="cline-any cline-neutral">&nbsp;</span>
392
- <span class="cline-any cline-yes">4x</span>
393
- <span class="cline-any cline-yes">4x</span>
394
- <span class="cline-any cline-yes">4x</span>
408
+ <span class="cline-any cline-yes">12x</span>
409
+ <span class="cline-any cline-yes">12x</span>
410
+ <span class="cline-any cline-yes">12x</span>
395
411
  <span class="cline-any cline-no">&nbsp;</span>
396
412
  <span class="cline-any cline-neutral">&nbsp;</span>
397
413
  <span class="cline-any cline-neutral">&nbsp;</span>
398
- <span class="cline-any cline-yes">4x</span>
414
+ <span class="cline-any cline-yes">12x</span>
415
+ <span class="cline-any cline-neutral">&nbsp;</span>
399
416
  <span class="cline-any cline-neutral">&nbsp;</span>
417
+ <span class="cline-any cline-yes">12x</span>
418
+ <span class="cline-any cline-yes">1x</span>
400
419
  <span class="cline-any cline-neutral">&nbsp;</span>
401
- <span class="cline-any cline-yes">4x</span>
402
420
  <span class="cline-any cline-neutral">&nbsp;</span>
403
421
  <span class="cline-any cline-neutral">&nbsp;</span>
404
422
  <span class="cline-any cline-neutral">&nbsp;</span>
423
+ <span class="cline-any cline-yes">11x</span>
405
424
  <span class="cline-any cline-neutral">&nbsp;</span>
406
425
  <span class="cline-any cline-neutral">&nbsp;</span>
407
426
  <span class="cline-any cline-neutral">&nbsp;</span>
408
427
  <span class="cline-any cline-neutral">&nbsp;</span>
409
- <span class="cline-any cline-yes">1x</span>
428
+ <span class="cline-any cline-neutral">&nbsp;</span>
429
+ <span class="cline-any cline-neutral">&nbsp;</span>
430
+ <span class="cline-any cline-neutral">&nbsp;</span>
431
+ <span class="cline-any cline-yes">3x</span>
410
432
  <span class="cline-any cline-neutral">&nbsp;</span>
411
433
  <span class="cline-any cline-neutral">&nbsp;</span>
412
434
  <span class="cline-any cline-neutral">&nbsp;</span>
@@ -433,7 +455,7 @@
433
455
  <span class="cline-any cline-neutral">&nbsp;</span>
434
456
  <span class="cline-any cline-neutral">&nbsp;</span>
435
457
  <span class="cline-any cline-neutral">&nbsp;</span>
436
- <span class="cline-any cline-yes">1x</span>
458
+ <span class="cline-any cline-yes">3x</span>
437
459
  <span class="cline-any cline-neutral">&nbsp;</span>
438
460
  <span class="cline-any cline-neutral">&nbsp;</span>
439
461
  <span class="cline-any cline-no">&nbsp;</span>
@@ -477,6 +499,7 @@ export const DATAFILES_DIRECTORY_NAME = "datafiles";
477
499
  export const DATAFILE_NAME_PATTERN = "featurevisor-%s.json";
478
500
  export const REVISION_FILE_NAME = "REVISION";
479
501
  export const SITE_EXPORT_DIRECTORY_NAME = "out";
502
+ export const ENVIRONMENTS_DIRECTORY_NAME = "environments";
480
503
  &nbsp;
481
504
  export const CONFIG_MODULE_NAME = "featurevisor.config.js";
482
505
  export const ROOT_DIR_PLACEHOLDER = "&lt;rootDir&gt;";
@@ -511,8 +534,10 @@ export interface ProjectConfig {
511
534
  datafileNamePattern: string;
512
535
  revisionFileName: string;
513
536
  siteExportDirectoryPath: string;
537
+ environmentsDirectoryPath: string;
514
538
  &nbsp;
515
539
  environments: string[] | false;
540
+ splitByEnvironment: boolean;
516
541
  tags: string[];
517
542
  scopes?: Scope[];
518
543
  &nbsp;
@@ -550,6 +575,7 @@ export function getProjectConfig(rootDirectoryPath: string): ProjectConfig {
550
575
  adapter: FilesystemAdapter,
551
576
  &nbsp;
552
577
  featuresDirectoryPath: path.join(rootDirectoryPath, FEATURES_DIRECTORY_NAME),
578
+ environmentsDirectoryPath: path.join(rootDirectoryPath, ENVIRONMENTS_DIRECTORY_NAME),
553
579
  segmentsDirectoryPath: path.join(rootDirectoryPath, SEGMENTS_DIRECTORY_NAME),
554
580
  attributesDirectoryPath: path.join(rootDirectoryPath, ATTRIBUTES_DIRECTORY_NAME),
555
581
  groupsDirectoryPath: path.join(rootDirectoryPath, GROUPS_DIRECTORY_NAME),
@@ -563,6 +589,7 @@ export function getProjectConfig(rootDirectoryPath: string): ProjectConfig {
563
589
  &nbsp;
564
590
  enforceCatchAllRule: false,
565
591
  plugins: [],
592
+ splitByEnvironment: false,
566
593
  &nbsp;
567
594
  maxVariableStringLength: undefined,
568
595
  maxVariableArrayStringifiedLength: undefined,
@@ -594,6 +621,12 @@ export function getProjectConfig(rootDirectoryPath: string): ProjectConfig {
594
621
  &nbsp;
595
622
  finalConfig.parser = parsers[finalConfig.parser];
596
623
  }
624
+ &nbsp;
625
+ if (finalConfig.splitByEnvironment &amp;&amp; finalConfig.environments === false) {
626
+ throw new Error(
627
+ "Invalid configuration: splitByEnvironment=true requires environments to be an array",
628
+ );
629
+ }
597
630
  &nbsp;
598
631
  return finalConfig as ProjectConfig;
599
632
  }
@@ -661,7 +694,7 @@ export const configPlugin: Plugin = {
661
694
  <div class='footer quiet pad2 space-top1 center small'>
662
695
  Code coverage generated by
663
696
  <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a>
664
- at 2026-02-24T19:50:30.107Z
697
+ at 2026-02-25T22:03:15.189Z
665
698
  </div>
666
699
  <script src="../prettify.js"></script>
667
700
  <script>