@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.
- package/CHANGELOG.md +8 -0
- package/coverage/clover.xml +4991 -3130
- package/coverage/coverage-final.json +63 -39
- package/coverage/lcov-report/block-navigation.js +1 -1
- package/coverage/lcov-report/index.html +248 -98
- package/coverage/lcov-report/sorter.js +21 -7
- package/coverage/lcov-report/src/assess-distribution/index.html +116 -0
- package/coverage/lcov-report/src/assess-distribution/index.ts.html +754 -0
- package/coverage/lcov-report/{list → src/benchmark}/index.html +30 -30
- package/coverage/lcov-report/src/benchmark/index.ts.html +793 -0
- package/coverage/lcov-report/{builder → src/builder}/allocator.ts.html +38 -38
- package/coverage/lcov-report/{builder/buildScopedConditions.ts.html → src/builder/applyContextToConditions.ts.html} +80 -65
- package/coverage/lcov-report/{builder/buildScopedDatafile.ts.html → src/builder/applyContextToDatafile.ts.html} +92 -92
- package/coverage/lcov-report/{builder/buildScopedSegments.ts.html → src/builder/applyContextToSegments.ts.html} +103 -67
- package/coverage/lcov-report/{builder → src/builder}/buildDatafile.ts.html +336 -306
- package/coverage/lcov-report/src/builder/buildProject.ts.html +1117 -0
- package/coverage/lcov-report/src/builder/buildRuntimeDatafiles.ts.html +256 -0
- package/coverage/lcov-report/{builder → src/builder}/getFeatureRanges.ts.html +22 -22
- package/coverage/lcov-report/{builder → src/builder}/hashes.ts.html +50 -50
- package/coverage/lcov-report/{builder → src/builder}/index.html +114 -84
- package/coverage/lcov-report/{tester/cliFormat.ts.html → src/builder/index.ts.html} +17 -29
- package/coverage/lcov-report/{builder → src/builder}/mutateVariables.ts.html +55 -55
- package/coverage/lcov-report/{builder → src/builder}/mutator.ts.html +118 -118
- package/coverage/lcov-report/{builder → src/builder}/revision.ts.html +15 -15
- package/coverage/lcov-report/{builder → src/builder}/traffic.ts.html +86 -86
- package/coverage/lcov-report/src/cli/cli.ts.html +400 -0
- package/coverage/lcov-report/{tester → src/cli}/index.html +41 -41
- package/coverage/lcov-report/src/cli/plugins.ts.html +214 -0
- package/coverage/lcov-report/{config → src/config}/index.html +31 -31
- package/coverage/lcov-report/{config → src/config}/index.ts.html +12 -12
- package/coverage/lcov-report/{config → src/config}/projectConfig.ts.html +312 -96
- package/coverage/lcov-report/{datasource → src/datasource}/adapter.ts.html +28 -73
- package/coverage/lcov-report/{datasource → src/datasource}/datasource.ts.html +191 -104
- package/coverage/lcov-report/{datasource → src/datasource}/filesystemAdapter.ts.html +233 -635
- package/coverage/lcov-report/{datasource → src/datasource}/index.html +48 -48
- package/coverage/lcov-report/{datasource → src/datasource}/index.ts.html +14 -14
- package/coverage/lcov-report/src/evaluate/index.html +116 -0
- package/coverage/lcov-report/src/evaluate/index.ts.html +814 -0
- package/coverage/lcov-report/src/find-duplicate-segments/findDuplicateSegments.ts.html +313 -0
- package/coverage/lcov-report/src/find-duplicate-segments/index.html +131 -0
- package/coverage/lcov-report/src/find-duplicate-segments/index.ts.html +307 -0
- package/coverage/lcov-report/src/find-usage/index.html +116 -0
- package/coverage/lcov-report/src/find-usage/index.ts.html +1780 -0
- package/coverage/lcov-report/src/generate-code/index.html +131 -0
- package/coverage/lcov-report/src/generate-code/index.ts.html +403 -0
- package/coverage/lcov-report/{generate-code → src/generate-code}/typescript.ts.html +266 -1361
- package/coverage/lcov-report/{generate-code → src}/index.html +38 -23
- package/coverage/lcov-report/src/info/index.html +116 -0
- package/coverage/lcov-report/src/info/index.ts.html +472 -0
- package/coverage/lcov-report/src/init/index.html +116 -0
- package/coverage/lcov-report/src/init/index.ts.html +280 -0
- package/coverage/lcov-report/{linter → src/linter}/attributeSchema.ts.html +160 -157
- package/coverage/lcov-report/{linter → src/linter}/checkCircularDependency.ts.html +25 -25
- package/coverage/lcov-report/{linter → src/linter}/checkPercentageExceedingSlot.ts.html +42 -42
- package/coverage/lcov-report/{linter → src/linter}/conditionSchema.ts.html +207 -207
- package/coverage/lcov-report/{linter → src/linter}/featureSchema.ts.html +462 -471
- package/coverage/lcov-report/{linter → src/linter}/groupSchema.ts.html +25 -22
- package/coverage/lcov-report/{linter → src/linter}/index.html +129 -99
- package/coverage/lcov-report/src/linter/index.ts.html +88 -0
- package/coverage/lcov-report/{linter → src/linter}/lintProject.ts.html +740 -332
- package/coverage/lcov-report/{linter → src/linter}/mutationNotation.ts.html +130 -130
- package/coverage/lcov-report/{linter → src/linter}/printError.ts.html +27 -27
- package/coverage/lcov-report/{linter → src/linter}/schema.ts.html +153 -150
- package/coverage/lcov-report/{linter → src/linter}/segmentSchema.ts.html +18 -15
- package/coverage/lcov-report/src/linter/targetSchema.ts.html +223 -0
- package/coverage/lcov-report/{linter → src/linter}/testSchema.ts.html +54 -48
- package/coverage/lcov-report/{linter → src/linter}/zodHelpers.ts.html +17 -17
- package/coverage/lcov-report/src/list/index.html +131 -0
- package/coverage/lcov-report/src/list/index.ts.html +2065 -0
- package/coverage/lcov-report/{list → src/list}/matrix.ts.html +43 -58
- package/coverage/lcov-report/src/promoter/index.html +116 -0
- package/coverage/lcov-report/src/promoter/index.ts.html +3883 -0
- package/coverage/lcov-report/src/sets.ts.html +313 -0
- package/coverage/lcov-report/src/targeting.ts.html +403 -0
- package/coverage/lcov-report/src/tester/cliFormat.ts.html +133 -0
- package/coverage/lcov-report/{tester → src/tester}/helpers.ts.html +15 -15
- package/coverage/lcov-report/src/tester/index.html +206 -0
- package/coverage/lcov-report/src/tester/prettyDuration.ts.html +187 -0
- package/coverage/lcov-report/src/tester/printTestResult.ts.html +337 -0
- package/coverage/lcov-report/src/tester/testFeature.ts.html +1186 -0
- package/coverage/lcov-report/src/tester/testProject.ts.html +1018 -0
- package/coverage/lcov-report/src/tester/testSegment.ts.html +316 -0
- package/coverage/lcov-report/{utils → src/utils}/extractKeys.ts.html +68 -68
- package/coverage/lcov-report/{utils → src/utils}/git.ts.html +44 -68
- package/coverage/lcov-report/{utils → src/utils}/index.html +44 -44
- package/coverage/lcov-report/{utils → src/utils}/index.ts.html +14 -14
- package/coverage/lcov-report/{utils → src/utils}/pretty.ts.html +20 -20
- package/coverage/lcov.info +10121 -5723
- package/jest.config.js +13 -4
- package/lib/assess-distribution/index.d.ts +1 -1
- package/lib/assess-distribution/index.js +59 -40
- package/lib/assess-distribution/index.js.map +1 -1
- package/lib/benchmark/index.d.ts +8 -5
- package/lib/benchmark/index.js +82 -65
- package/lib/benchmark/index.js.map +1 -1
- package/lib/builder/applyContextToConditions.d.ts +5 -0
- package/lib/builder/{buildScopedConditions.js → applyContextToConditions.js} +19 -14
- package/lib/builder/applyContextToConditions.js.map +1 -0
- package/lib/builder/applyContextToDatafile.d.ts +2 -0
- package/lib/builder/{buildScopedDatafile.js → applyContextToDatafile.js} +26 -26
- package/lib/builder/applyContextToDatafile.js.map +1 -0
- package/lib/builder/applyContextToSegments.d.ts +5 -0
- package/lib/builder/{buildScopedSegments.js → applyContextToSegments.js} +19 -14
- package/lib/builder/applyContextToSegments.js.map +1 -0
- package/lib/builder/buildDatafile.d.ts +9 -6
- package/lib/builder/buildDatafile.js +86 -51
- package/lib/builder/buildDatafile.js.map +1 -1
- package/lib/builder/buildProject.d.ts +17 -3
- package/lib/builder/buildProject.js +151 -59
- package/lib/builder/buildProject.js.map +1 -1
- package/lib/builder/buildRuntimeDatafiles.d.ts +12 -0
- package/lib/builder/buildRuntimeDatafiles.js +35 -0
- package/lib/builder/buildRuntimeDatafiles.js.map +1 -0
- package/lib/builder/getFeatureRanges.js +34 -1
- package/lib/builder/getFeatureRanges.js.map +1 -1
- package/lib/builder/hashes.js +34 -1
- package/lib/builder/hashes.js.map +1 -1
- package/lib/builder/index.d.ts +0 -1
- package/lib/builder/index.js +0 -1
- package/lib/builder/index.js.map +1 -1
- package/lib/cli/cli.js +0 -4
- package/lib/cli/cli.js.map +1 -1
- package/lib/cli/plugins.js +7 -2
- package/lib/cli/plugins.js.map +1 -1
- package/lib/config/projectConfig.d.ts +17 -17
- package/lib/config/projectConfig.js +101 -15
- package/lib/config/projectConfig.js.map +1 -1
- package/lib/datasource/adapter.d.ts +7 -9
- package/lib/datasource/adapter.js +0 -7
- package/lib/datasource/adapter.js.map +1 -1
- package/lib/datasource/datasource.d.ts +15 -5
- package/lib/datasource/datasource.js +37 -9
- package/lib/datasource/datasource.js.map +1 -1
- package/lib/datasource/filesystemAdapter.d.ts +4 -10
- package/lib/datasource/filesystemAdapter.js +111 -149
- package/lib/datasource/filesystemAdapter.js.map +1 -1
- package/lib/evaluate/index.d.ts +1 -7
- package/lib/evaluate/index.js +81 -67
- package/lib/evaluate/index.js.map +1 -1
- package/lib/find-duplicate-segments/findDuplicateSegments.js +34 -1
- package/lib/find-duplicate-segments/findDuplicateSegments.js.map +1 -1
- package/lib/find-duplicate-segments/index.js +21 -13
- package/lib/find-duplicate-segments/index.js.map +1 -1
- package/lib/find-usage/index.js +57 -41
- package/lib/find-usage/index.js.map +1 -1
- package/lib/generate-code/index.d.ts +1 -1
- package/lib/generate-code/index.js +64 -21
- package/lib/generate-code/index.js.map +1 -1
- package/lib/generate-code/typescript.d.ts +1 -1
- package/lib/generate-code/typescript.js +59 -333
- package/lib/generate-code/typescript.js.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/index.js.map +1 -1
- package/lib/info/index.js +57 -16
- package/lib/info/index.js.map +1 -1
- package/lib/init/index.d.ts +2 -2
- package/lib/init/index.js +39 -3
- package/lib/init/index.js.map +1 -1
- package/lib/linter/attributeSchema.d.ts +1 -0
- package/lib/linter/attributeSchema.js +1 -0
- package/lib/linter/attributeSchema.js.map +1 -1
- package/lib/linter/conditionSchema.js +5 -5
- package/lib/linter/conditionSchema.js.map +1 -1
- package/lib/linter/featureSchema.d.ts +4 -1
- package/lib/linter/featureSchema.js +15 -13
- package/lib/linter/featureSchema.js.map +1 -1
- package/lib/linter/groupSchema.d.ts +1 -0
- package/lib/linter/groupSchema.js +1 -0
- package/lib/linter/groupSchema.js.map +1 -1
- package/lib/linter/lintProject.d.ts +1 -3
- package/lib/linter/lintProject.js +198 -68
- package/lib/linter/lintProject.js.map +1 -1
- package/lib/linter/schema.js +1 -0
- package/lib/linter/schema.js.map +1 -1
- package/lib/linter/segmentSchema.d.ts +1 -0
- package/lib/linter/segmentSchema.js +1 -0
- package/lib/linter/segmentSchema.js.map +1 -1
- package/lib/linter/targetSchema.d.ts +16 -0
- package/lib/linter/targetSchema.js +40 -0
- package/lib/linter/targetSchema.js.map +1 -0
- package/lib/linter/testSchema.d.ts +4 -3
- package/lib/linter/testSchema.js +9 -4
- package/lib/linter/testSchema.js.map +1 -1
- package/lib/list/index.d.ts +1 -0
- package/lib/list/index.js +131 -12
- package/lib/list/index.js.map +1 -1
- package/lib/list/matrix.js +3 -7
- package/lib/list/matrix.js.map +1 -1
- package/lib/promoter/index.d.ts +50 -0
- package/lib/promoter/index.js +880 -0
- package/lib/promoter/index.js.map +1 -0
- package/lib/sets.d.ts +11 -0
- package/lib/sets.js +81 -0
- package/lib/sets.js.map +1 -0
- package/lib/targeting.d.ts +14 -0
- package/lib/targeting.js +82 -0
- package/lib/targeting.js.map +1 -0
- package/lib/tester/cliFormat.d.ts +7 -1
- package/lib/tester/cliFormat.js +11 -2
- package/lib/tester/cliFormat.js.map +1 -1
- package/lib/tester/printTestResult.js +2 -2
- package/lib/tester/printTestResult.js.map +1 -1
- package/lib/tester/testFeature.d.ts +0 -1
- package/lib/tester/testFeature.js +8 -25
- package/lib/tester/testFeature.js.map +1 -1
- package/lib/tester/testProject.d.ts +2 -3
- package/lib/tester/testProject.js +93 -86
- package/lib/tester/testProject.js.map +1 -1
- package/lib/tester/testSegment.d.ts +1 -1
- package/lib/tester/testSegment.js +3 -21
- package/lib/tester/testSegment.js.map +1 -1
- package/lib/utils/git.js +45 -19
- package/lib/utils/git.js.map +1 -1
- package/package.json +12 -12
- package/src/assess-distribution/index.ts +72 -52
- package/src/benchmark/index.ts +124 -91
- package/src/builder/{buildScopedConditions.spec.ts → applyContextToConditions.spec.ts} +160 -142
- package/src/builder/{buildScopedConditions.ts → applyContextToConditions.ts} +19 -14
- package/src/builder/{buildScopedDatafile.spec.ts → applyContextToDatafile.spec.ts} +141 -81
- package/src/builder/{buildScopedDatafile.ts → applyContextToDatafile.ts} +33 -33
- package/src/builder/{buildScopedSegments.spec.ts → applyContextToSegments.spec.ts} +171 -151
- package/src/builder/{buildScopedSegments.ts → applyContextToSegments.ts} +26 -14
- package/src/builder/buildDatafile.spec.ts +192 -14
- package/src/builder/buildDatafile.ts +74 -64
- package/src/builder/buildProject.ts +171 -86
- package/src/builder/buildRuntimeDatafiles.ts +57 -0
- package/src/builder/index.ts +0 -1
- package/src/cli/cli.ts +0 -5
- package/src/cli/plugins.ts +7 -2
- package/src/config/projectConfig.spec.ts +171 -8
- package/src/config/projectConfig.ts +100 -28
- package/src/datasource/adapter.ts +8 -23
- package/src/datasource/datasource.ts +50 -21
- package/src/datasource/filesystemAdapter.spec.ts +133 -74
- package/src/datasource/filesystemAdapter.ts +93 -227
- package/src/evaluate/index.ts +109 -97
- package/src/find-duplicate-segments/index.ts +34 -16
- package/src/find-usage/index.ts +89 -44
- package/src/generate-code/index.ts +36 -24
- package/src/generate-code/typescript.spec.ts +106 -0
- package/src/generate-code/typescript.ts +33 -398
- package/src/index.ts +2 -1
- package/src/info/index.ts +72 -16
- package/src/init/index.ts +1 -1
- package/src/linter/attributeSchema.ts +1 -0
- package/src/linter/conditionSchema.spec.ts +23 -3
- package/src/linter/conditionSchema.ts +5 -5
- package/src/linter/featureSchema.spec.ts +107 -18
- package/src/linter/featureSchema.ts +25 -28
- package/src/linter/groupSchema.ts +1 -0
- package/src/linter/lintProject.spec.ts +131 -92
- package/src/linter/lintProject.ts +233 -97
- package/src/linter/schema.ts +1 -0
- package/src/linter/segmentSchema.spec.ts +5 -3
- package/src/linter/segmentSchema.ts +1 -0
- package/src/linter/targetSchema.spec.ts +159 -0
- package/src/linter/targetSchema.ts +46 -0
- package/src/linter/testSchema.spec.ts +70 -5
- package/src/linter/testSchema.ts +12 -10
- package/src/list/index.spec.ts +135 -0
- package/src/list/index.ts +188 -12
- package/src/list/matrix.ts +3 -8
- package/src/promoter/index.spec.ts +617 -0
- package/src/promoter/index.ts +1266 -0
- package/src/sets.ts +76 -0
- package/src/targeting.spec.ts +74 -0
- package/src/targeting.ts +106 -0
- package/src/tester/cliFormat.ts +11 -1
- package/src/tester/printTestResult.ts +12 -3
- package/src/tester/testFeature.ts +10 -36
- package/src/tester/testProject.spec.ts +50 -0
- package/src/tester/testProject.ts +89 -140
- package/src/tester/testSegment.ts +5 -22
- package/src/utils/git.ts +13 -21
- package/tsconfig.cjs.json +5 -1
- package/tsconfig.typecheck.json +9 -0
- package/coverage/lcov-report/builder/convertToV1.ts.html +0 -583
- package/lib/builder/allocator.spec.d.ts +0 -1
- package/lib/builder/allocator.spec.js +0 -85
- package/lib/builder/allocator.spec.js.map +0 -1
- package/lib/builder/buildDatafile.spec.d.ts +0 -1
- package/lib/builder/buildDatafile.spec.js +0 -233
- package/lib/builder/buildDatafile.spec.js.map +0 -1
- package/lib/builder/buildScopedConditions.d.ts +0 -5
- package/lib/builder/buildScopedConditions.js.map +0 -1
- package/lib/builder/buildScopedConditions.spec.d.ts +0 -1
- package/lib/builder/buildScopedConditions.spec.js +0 -2167
- package/lib/builder/buildScopedConditions.spec.js.map +0 -1
- package/lib/builder/buildScopedDatafile.d.ts +0 -2
- package/lib/builder/buildScopedDatafile.js.map +0 -1
- package/lib/builder/buildScopedDatafile.spec.d.ts +0 -1
- package/lib/builder/buildScopedDatafile.spec.js +0 -2277
- package/lib/builder/buildScopedDatafile.spec.js.map +0 -1
- package/lib/builder/buildScopedSegments.d.ts +0 -5
- package/lib/builder/buildScopedSegments.js.map +0 -1
- package/lib/builder/buildScopedSegments.spec.d.ts +0 -1
- package/lib/builder/buildScopedSegments.spec.js +0 -1062
- package/lib/builder/buildScopedSegments.spec.js.map +0 -1
- package/lib/builder/convertToV1.d.ts +0 -10
- package/lib/builder/convertToV1.js +0 -119
- package/lib/builder/convertToV1.js.map +0 -1
- package/lib/builder/mutateVariables.spec.d.ts +0 -1
- package/lib/builder/mutateVariables.spec.js +0 -1074
- package/lib/builder/mutateVariables.spec.js.map +0 -1
- package/lib/builder/mutator.spec.d.ts +0 -1
- package/lib/builder/mutator.spec.js +0 -368
- package/lib/builder/mutator.spec.js.map +0 -1
- package/lib/builder/revision.spec.d.ts +0 -1
- package/lib/builder/revision.spec.js +0 -21
- package/lib/builder/revision.spec.js.map +0 -1
- package/lib/builder/traffic.spec.d.ts +0 -1
- package/lib/builder/traffic.spec.js +0 -872
- package/lib/builder/traffic.spec.js.map +0 -1
- package/lib/config/projectConfig.spec.d.ts +0 -1
- package/lib/config/projectConfig.spec.js +0 -24
- package/lib/config/projectConfig.spec.js.map +0 -1
- package/lib/datasource/filesystemAdapter.spec.d.ts +0 -1
- package/lib/datasource/filesystemAdapter.spec.js +0 -88
- package/lib/datasource/filesystemAdapter.spec.js.map +0 -1
- package/lib/generate-code/typescript.spec.d.ts +0 -1
- package/lib/generate-code/typescript.spec.js +0 -78
- package/lib/generate-code/typescript.spec.js.map +0 -1
- package/lib/linter/attributeSchema.spec.d.ts +0 -1
- package/lib/linter/attributeSchema.spec.js +0 -266
- package/lib/linter/attributeSchema.spec.js.map +0 -1
- package/lib/linter/conditionSchema.spec.d.ts +0 -1
- package/lib/linter/conditionSchema.spec.js +0 -380
- package/lib/linter/conditionSchema.spec.js.map +0 -1
- package/lib/linter/featureSchema.spec.d.ts +0 -1
- package/lib/linter/featureSchema.spec.js +0 -1552
- package/lib/linter/featureSchema.spec.js.map +0 -1
- package/lib/linter/lintProject.spec.d.ts +0 -1
- package/lib/linter/lintProject.spec.js +0 -211
- package/lib/linter/lintProject.spec.js.map +0 -1
- package/lib/linter/mutationNotation.spec.d.ts +0 -1
- package/lib/linter/mutationNotation.spec.js +0 -598
- package/lib/linter/mutationNotation.spec.js.map +0 -1
- package/lib/linter/schema.spec.d.ts +0 -1
- package/lib/linter/schema.spec.js +0 -535
- package/lib/linter/schema.spec.js.map +0 -1
- package/lib/linter/segmentSchema.spec.d.ts +0 -1
- package/lib/linter/segmentSchema.spec.js +0 -303
- package/lib/linter/segmentSchema.spec.js.map +0 -1
- package/lib/linter/testSchema.spec.d.ts +0 -1
- package/lib/linter/testSchema.spec.js +0 -162
- package/lib/linter/testSchema.spec.js.map +0 -1
- package/lib/list/matrix.spec.d.ts +0 -1
- package/lib/list/matrix.spec.js +0 -42
- package/lib/list/matrix.spec.js.map +0 -1
- package/lib/site/exportSite.d.ts +0 -2
- package/lib/site/exportSite.js +0 -30
- package/lib/site/exportSite.js.map +0 -1
- package/lib/site/generateHistory.d.ts +0 -3
- package/lib/site/generateHistory.js +0 -31
- package/lib/site/generateHistory.js.map +0 -1
- package/lib/site/generateSiteSearchIndex.d.ts +0 -4
- package/lib/site/generateSiteSearchIndex.js +0 -195
- package/lib/site/generateSiteSearchIndex.js.map +0 -1
- package/lib/site/getLastModifiedFromHistory.d.ts +0 -2
- package/lib/site/getLastModifiedFromHistory.js +0 -18
- package/lib/site/getLastModifiedFromHistory.js.map +0 -1
- package/lib/site/getOwnerAndRepoFromUrl.d.ts +0 -4
- package/lib/site/getOwnerAndRepoFromUrl.js +0 -20
- package/lib/site/getOwnerAndRepoFromUrl.js.map +0 -1
- package/lib/site/getRelativePaths.d.ts +0 -6
- package/lib/site/getRelativePaths.js +0 -15
- package/lib/site/getRelativePaths.js.map +0 -1
- package/lib/site/getRepoDetails.d.ts +0 -8
- package/lib/site/getRepoDetails.js +0 -48
- package/lib/site/getRepoDetails.js.map +0 -1
- package/lib/site/index.d.ts +0 -2
- package/lib/site/index.js +0 -43
- package/lib/site/index.js.map +0 -1
- package/lib/site/serveSite.d.ts +0 -2
- package/lib/site/serveSite.js +0 -54
- package/lib/site/serveSite.js.map +0 -1
- package/lib/tester/helpers.spec.d.ts +0 -1
- package/lib/tester/helpers.spec.js +0 -115
- package/lib/tester/helpers.spec.js.map +0 -1
- package/src/builder/convertToV1.ts +0 -166
- package/src/site/exportSite.ts +0 -42
- package/src/site/generateHistory.ts +0 -40
- package/src/site/generateSiteSearchIndex.ts +0 -258
- package/src/site/getLastModifiedFromHistory.ts +0 -21
- package/src/site/getOwnerAndRepoFromUrl.ts +0 -17
- package/src/site/getRelativePaths.ts +0 -24
- package/src/site/getRepoDetails.ts +0 -62
- package/src/site/index.ts +0 -46
- 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 {
|
|
319
|
+
import type { Featurevisor } from "@featurevisor/sdk";
|
|
591
320
|
|
|
592
|
-
let _instance:
|
|
321
|
+
let _instance: Featurevisor;
|
|
593
322
|
|
|
594
|
-
export function setInstance(instance:
|
|
323
|
+
export function setInstance(instance: Featurevisor) {
|
|
595
324
|
_instance = instance;
|
|
596
325
|
}
|
|
597
326
|
|
|
598
|
-
export function getInstance():
|
|
599
|
-
return _instance as
|
|
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
|
-
|
|
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
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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("
|
|
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("
|
|
30
|
-
console.log("
|
|
31
|
-
console.log("
|
|
32
|
-
console.log("
|
|
33
|
-
console.log("
|
|
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("
|
|
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("
|
|
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
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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 = "
|
|
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(),
|