@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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// for use in node only
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
import * as path from "path";
|
|
3
4
|
|
|
4
5
|
import type { Attribute, Schema } from "@featurevisor/types";
|
|
@@ -11,15 +12,24 @@ import { getGroupZodSchema } from "./groupSchema";
|
|
|
11
12
|
import { getFeatureZodSchema } from "./featureSchema";
|
|
12
13
|
import { getSchemaZodSchema } from "./schema";
|
|
13
14
|
import { getTestsZodSchema } from "./testSchema";
|
|
15
|
+
import { getTargetZodSchema } from "./targetSchema";
|
|
14
16
|
|
|
15
17
|
import { checkForCircularDependencyInRequired } from "./checkCircularDependency";
|
|
16
18
|
import { checkForFeatureExceedingGroupSlotPercentage } from "./checkPercentageExceedingSlot";
|
|
17
19
|
import { getLintIssuesFromZodError, printZodError } from "./printError";
|
|
18
20
|
import { Dependencies } from "../dependencies";
|
|
19
|
-
import {
|
|
21
|
+
import { CLI_FORMAT_BOLD_UNDERLINE, CLI_FORMAT_GREEN, CLI_FORMAT_RED } from "../tester/cliFormat";
|
|
20
22
|
import { Plugin } from "../cli";
|
|
23
|
+
import { assertProjectSetJsonSelection, getProjectSetExecutions, printSetHeader } from "../sets";
|
|
21
24
|
|
|
22
|
-
export type LintEntityType =
|
|
25
|
+
export type LintEntityType =
|
|
26
|
+
| "attribute"
|
|
27
|
+
| "segment"
|
|
28
|
+
| "feature"
|
|
29
|
+
| "group"
|
|
30
|
+
| "schema"
|
|
31
|
+
| "target"
|
|
32
|
+
| "test";
|
|
23
33
|
|
|
24
34
|
export interface LintProjectOptions {
|
|
25
35
|
keyPattern?: string;
|
|
@@ -37,8 +47,6 @@ export interface LintErrorItem {
|
|
|
37
47
|
path: (string | number)[];
|
|
38
48
|
code?: string;
|
|
39
49
|
value?: unknown;
|
|
40
|
-
/** Present only when splitByEnvironment is true and the error is from an environment-specific file (rules/force/expose). */
|
|
41
|
-
environment?: string;
|
|
42
50
|
}
|
|
43
51
|
|
|
44
52
|
export interface LintResult {
|
|
@@ -47,10 +55,65 @@ export interface LintResult {
|
|
|
47
55
|
}
|
|
48
56
|
|
|
49
57
|
const ENTITY_NAME_REGEX = /^[a-zA-Z0-9_\-./]+$/;
|
|
50
|
-
const ENTITY_NAME_REGEX_ERROR =
|
|
58
|
+
const ENTITY_NAME_REGEX_ERROR =
|
|
59
|
+
"Names must be alphanumeric and can contain _, -, /, ., and the configured namespace character";
|
|
51
60
|
|
|
52
|
-
const
|
|
53
|
-
|
|
61
|
+
const ATTRIBUTE_NAME_REGEX_ERROR =
|
|
62
|
+
"Names must be alphanumeric and can contain _, -, /, ., and the configured namespace character";
|
|
63
|
+
|
|
64
|
+
function escapeRegExp(value: string): string {
|
|
65
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function isValidEntityKey(key: string, namespaceCharacter: string): boolean {
|
|
69
|
+
const keyWithoutNamespaceCharacter = key.replace(
|
|
70
|
+
new RegExp(escapeRegExp(namespaceCharacter), "g"),
|
|
71
|
+
"",
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return ENTITY_NAME_REGEX.test(keyWithoutNamespaceCharacter);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function getPathSegmentsFromKey(
|
|
78
|
+
key: string,
|
|
79
|
+
namespaceCharacter: string,
|
|
80
|
+
entityType?: LintEntityType,
|
|
81
|
+
): string[] {
|
|
82
|
+
const pathSegments = key.split(namespaceCharacter);
|
|
83
|
+
|
|
84
|
+
if (
|
|
85
|
+
entityType === "test" &&
|
|
86
|
+
pathSegments.length > 1 &&
|
|
87
|
+
["spec", "feature", "segment"].includes(pathSegments[pathSegments.length - 1])
|
|
88
|
+
) {
|
|
89
|
+
const suffix = pathSegments[pathSegments.length - 1];
|
|
90
|
+
pathSegments[pathSegments.length - 2] = `${pathSegments[pathSegments.length - 2]}.${suffix}`;
|
|
91
|
+
pathSegments.pop();
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return pathSegments;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function getReservedNameCheckValue(
|
|
98
|
+
entityType: LintEntityType,
|
|
99
|
+
name: string,
|
|
100
|
+
isFile: boolean,
|
|
101
|
+
extension: string,
|
|
102
|
+
): string {
|
|
103
|
+
let value =
|
|
104
|
+
isFile && name.endsWith(`.${extension}`) ? name.slice(0, -extension.length - 1) : name;
|
|
105
|
+
|
|
106
|
+
if (entityType === "test" && isFile) {
|
|
107
|
+
for (const suffix of [".spec", ".feature", ".segment"]) {
|
|
108
|
+
if (value.endsWith(suffix)) {
|
|
109
|
+
value = value.slice(0, -suffix.length);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return value;
|
|
116
|
+
}
|
|
54
117
|
|
|
55
118
|
async function getAuthorsOfEntity(datasource, entityType, entityKey): Promise<string[]> {
|
|
56
119
|
const entries = await datasource.listHistoryEntries(entityType, entityKey);
|
|
@@ -97,7 +160,9 @@ export async function lintProject(
|
|
|
97
160
|
}
|
|
98
161
|
|
|
99
162
|
function getFullPathFromKey(type: LintEntityType, key: string, relative = false) {
|
|
100
|
-
const fileName = `${key
|
|
163
|
+
const fileName = `${getPathSegmentsFromKey(key, projectConfig.namespaceCharacter, type).join(
|
|
164
|
+
path.sep,
|
|
165
|
+
)}.${datasource.getExtension()}`;
|
|
101
166
|
let fullPath = "";
|
|
102
167
|
|
|
103
168
|
if (type === "attribute") {
|
|
@@ -110,6 +175,8 @@ export async function lintProject(
|
|
|
110
175
|
fullPath = path.join(projectConfig.groupsDirectoryPath, fileName);
|
|
111
176
|
} else if (type === "schema") {
|
|
112
177
|
fullPath = path.join(projectConfig.schemasDirectoryPath, fileName);
|
|
178
|
+
} else if (type === "target") {
|
|
179
|
+
fullPath = path.join(projectConfig.targetsDirectoryPath, fileName);
|
|
113
180
|
} else {
|
|
114
181
|
fullPath = path.join(projectConfig.testsDirectoryPath, fileName);
|
|
115
182
|
}
|
|
@@ -121,60 +188,71 @@ export async function lintProject(
|
|
|
121
188
|
return fullPath;
|
|
122
189
|
}
|
|
123
190
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
191
|
+
function getEntityDirectoryPath(type: LintEntityType): string {
|
|
192
|
+
if (type === "attribute") {
|
|
193
|
+
return projectConfig.attributesDirectoryPath;
|
|
194
|
+
}
|
|
195
|
+
if (type === "segment") {
|
|
196
|
+
return projectConfig.segmentsDirectoryPath;
|
|
197
|
+
}
|
|
198
|
+
if (type === "feature") {
|
|
199
|
+
return projectConfig.featuresDirectoryPath;
|
|
200
|
+
}
|
|
201
|
+
if (type === "group") {
|
|
202
|
+
return projectConfig.groupsDirectoryPath;
|
|
203
|
+
}
|
|
204
|
+
if (type === "schema") {
|
|
205
|
+
return projectConfig.schemasDirectoryPath;
|
|
206
|
+
}
|
|
207
|
+
if (type === "target") {
|
|
208
|
+
return projectConfig.targetsDirectoryPath;
|
|
132
209
|
}
|
|
133
210
|
|
|
134
|
-
|
|
135
|
-
|
|
211
|
+
return projectConfig.testsDirectoryPath;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async function lintReservedNamespaceCharacterInPathNames(
|
|
215
|
+
entityType: LintEntityType,
|
|
216
|
+
directoryPath: string,
|
|
217
|
+
) {
|
|
218
|
+
if (!fs.existsSync(directoryPath)) {
|
|
219
|
+
return;
|
|
136
220
|
}
|
|
137
221
|
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
typeof environment === "string"
|
|
142
|
-
) {
|
|
143
|
-
const sourcePath = await datasource.getFeaturePropertySourcePath(
|
|
144
|
-
featureKey,
|
|
145
|
-
topLevelKey,
|
|
146
|
-
environment,
|
|
147
|
-
);
|
|
222
|
+
const extension = datasource.getExtension();
|
|
223
|
+
const namespaceCharacter = projectConfig.namespaceCharacter;
|
|
224
|
+
const entries = fs.readdirSync(directoryPath, { withFileTypes: true });
|
|
148
225
|
|
|
149
|
-
|
|
150
|
-
|
|
226
|
+
for (const entry of entries) {
|
|
227
|
+
const entryPath = path.join(directoryPath, entry.name);
|
|
228
|
+
const isFile = entry.isFile();
|
|
229
|
+
const isDirectory = entry.isDirectory();
|
|
230
|
+
|
|
231
|
+
if (!isDirectory && !(isFile && entry.name.endsWith(`.${extension}`))) {
|
|
232
|
+
continue;
|
|
151
233
|
}
|
|
152
|
-
}
|
|
153
234
|
|
|
154
|
-
|
|
235
|
+
const nameToCheck = getReservedNameCheckValue(entityType, entry.name, isFile, extension);
|
|
236
|
+
|
|
237
|
+
if (nameToCheck.includes(namespaceCharacter)) {
|
|
238
|
+
await reportSimpleError({
|
|
239
|
+
entityType,
|
|
240
|
+
key: path.relative(getEntityDirectoryPath(entityType), entryPath),
|
|
241
|
+
fullPath: entryPath,
|
|
242
|
+
message: `Invalid file or directory name: "${entry.name}"`,
|
|
243
|
+
detail: `Namespace character "${namespaceCharacter}" is not allowed in entity file or directory names.`,
|
|
244
|
+
code: "invalid_name",
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (isDirectory) {
|
|
249
|
+
await lintReservedNamespaceCharacterInPathNames(entityType, entryPath);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
155
252
|
}
|
|
156
253
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
* is against the merged feature (e.g. rules.production.1.variables.foo). Return the path
|
|
160
|
-
* as it appears in that file (e.g. rules.1.variables.foo) by stripping the environment segment.
|
|
161
|
-
*/
|
|
162
|
-
function getPathRelativeToFeatureFile(
|
|
163
|
-
issuePath: (string | number)[],
|
|
164
|
-
targetPath: string,
|
|
165
|
-
defaultFeaturePath: string,
|
|
166
|
-
): (string | number)[] {
|
|
167
|
-
if (targetPath === defaultFeaturePath || issuePath.length < 2) {
|
|
168
|
-
return issuePath;
|
|
169
|
-
}
|
|
170
|
-
const [topLevelKey, second] = issuePath;
|
|
171
|
-
if (
|
|
172
|
-
(topLevelKey === "rules" || topLevelKey === "force" || topLevelKey === "expose") &&
|
|
173
|
-
typeof second === "string"
|
|
174
|
-
) {
|
|
175
|
-
return [topLevelKey, ...issuePath.slice(2)];
|
|
176
|
-
}
|
|
177
|
-
return issuePath;
|
|
254
|
+
async function lintReservedNamespaceCharacterInEntityPaths(entityType: LintEntityType) {
|
|
255
|
+
await lintReservedNamespaceCharacterInPathNames(entityType, getEntityDirectoryPath(entityType));
|
|
178
256
|
}
|
|
179
257
|
|
|
180
258
|
async function printEntityHeader(entityType: LintEntityType, key: string, fullPath: string) {
|
|
@@ -272,8 +350,6 @@ export async function lintProject(
|
|
|
272
350
|
error: ZodError,
|
|
273
351
|
) {
|
|
274
352
|
const issues = getLintIssuesFromZodError(error);
|
|
275
|
-
const defaultFeaturePath =
|
|
276
|
-
entityType === "feature" ? getFullPathFromKey("feature", key) : fullPath;
|
|
277
353
|
|
|
278
354
|
const issuesWithTargetPath: {
|
|
279
355
|
issue: (typeof issues)[0];
|
|
@@ -281,19 +357,8 @@ export async function lintProject(
|
|
|
281
357
|
pathRelativeToFile: (string | number)[];
|
|
282
358
|
}[] = [];
|
|
283
359
|
for (const issue of issues) {
|
|
284
|
-
const targetPath =
|
|
285
|
-
|
|
286
|
-
const pathRelativeToFile =
|
|
287
|
-
entityType === "feature"
|
|
288
|
-
? getPathRelativeToFeatureFile(issue.path, targetPath, defaultFeaturePath)
|
|
289
|
-
: issue.path;
|
|
290
|
-
const isFromEnvFile =
|
|
291
|
-
entityType === "feature" &&
|
|
292
|
-
targetPath !== defaultFeaturePath &&
|
|
293
|
-
issue.path.length >= 2 &&
|
|
294
|
-
(issue.path[0] === "rules" || issue.path[0] === "force" || issue.path[0] === "expose") &&
|
|
295
|
-
typeof issue.path[1] === "string";
|
|
296
|
-
const environment = isFromEnvFile ? (issue.path[1] as string) : undefined;
|
|
360
|
+
const targetPath = fullPath;
|
|
361
|
+
const pathRelativeToFile = issue.path;
|
|
297
362
|
issuesWithTargetPath.push({ issue, targetPath, pathRelativeToFile });
|
|
298
363
|
|
|
299
364
|
recordError({
|
|
@@ -304,7 +369,6 @@ export async function lintProject(
|
|
|
304
369
|
path: pathRelativeToFile,
|
|
305
370
|
code: issue.code,
|
|
306
371
|
value: issue.value,
|
|
307
|
-
...(environment !== undefined && { environment }),
|
|
308
372
|
});
|
|
309
373
|
}
|
|
310
374
|
|
|
@@ -373,6 +437,8 @@ export async function lintProject(
|
|
|
373
437
|
}
|
|
374
438
|
|
|
375
439
|
if (!options.entityType || options.entityType === "attribute") {
|
|
440
|
+
await lintReservedNamespaceCharacterInEntityPaths("attribute");
|
|
441
|
+
|
|
376
442
|
const filteredKeys = !keyPattern
|
|
377
443
|
? attributes
|
|
378
444
|
: attributes.filter((key) => keyPattern.test(key));
|
|
@@ -384,7 +450,7 @@ export async function lintProject(
|
|
|
384
450
|
for (const key of filteredKeys) {
|
|
385
451
|
const fullPath = getFullPathFromKey("attribute", key);
|
|
386
452
|
|
|
387
|
-
if (!
|
|
453
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
388
454
|
await reportSimpleError({
|
|
389
455
|
entityType: "attribute",
|
|
390
456
|
key,
|
|
@@ -425,6 +491,8 @@ export async function lintProject(
|
|
|
425
491
|
const segmentZodSchema = getSegmentZodSchema(projectConfig, conditionsZodSchema);
|
|
426
492
|
|
|
427
493
|
if (!options.entityType || options.entityType === "segment") {
|
|
494
|
+
await lintReservedNamespaceCharacterInEntityPaths("segment");
|
|
495
|
+
|
|
428
496
|
const filteredKeys = !keyPattern ? segments : segments.filter((key) => keyPattern.test(key));
|
|
429
497
|
|
|
430
498
|
if (filteredKeys.length > 0) {
|
|
@@ -434,7 +502,7 @@ export async function lintProject(
|
|
|
434
502
|
for (const key of filteredKeys) {
|
|
435
503
|
const fullPath = getFullPathFromKey("segment", key);
|
|
436
504
|
|
|
437
|
-
if (!
|
|
505
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
438
506
|
await reportSimpleError({
|
|
439
507
|
entityType: "segment",
|
|
440
508
|
key,
|
|
@@ -471,6 +539,8 @@ export async function lintProject(
|
|
|
471
539
|
);
|
|
472
540
|
|
|
473
541
|
if (!options.entityType || options.entityType === "feature") {
|
|
542
|
+
await lintReservedNamespaceCharacterInEntityPaths("feature");
|
|
543
|
+
|
|
474
544
|
const filteredKeys = !keyPattern ? features : features.filter((key) => keyPattern.test(key));
|
|
475
545
|
|
|
476
546
|
if (filteredKeys.length > 0) {
|
|
@@ -480,7 +550,7 @@ export async function lintProject(
|
|
|
480
550
|
for (const key of filteredKeys) {
|
|
481
551
|
const fullPath = getFullPathFromKey("feature", key);
|
|
482
552
|
|
|
483
|
-
if (!
|
|
553
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
484
554
|
await reportSimpleError({
|
|
485
555
|
entityType: "feature",
|
|
486
556
|
key,
|
|
@@ -526,6 +596,8 @@ export async function lintProject(
|
|
|
526
596
|
const groupZodSchema = getGroupZodSchema(projectConfig, datasource, features);
|
|
527
597
|
|
|
528
598
|
if (!options.entityType || options.entityType === "group") {
|
|
599
|
+
await lintReservedNamespaceCharacterInEntityPaths("group");
|
|
600
|
+
|
|
529
601
|
const filteredKeys = !keyPattern ? groups : groups.filter((key) => keyPattern.test(key));
|
|
530
602
|
|
|
531
603
|
if (filteredKeys.length > 0) {
|
|
@@ -535,7 +607,7 @@ export async function lintProject(
|
|
|
535
607
|
for (const key of filteredKeys) {
|
|
536
608
|
const fullPath = getFullPathFromKey("group", key);
|
|
537
609
|
|
|
538
|
-
if (!
|
|
610
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
539
611
|
await reportSimpleError({
|
|
540
612
|
entityType: "group",
|
|
541
613
|
key,
|
|
@@ -582,6 +654,8 @@ export async function lintProject(
|
|
|
582
654
|
const schemaZodSchema = getSchemaZodSchema(schemas);
|
|
583
655
|
|
|
584
656
|
if (!options.entityType || options.entityType === "schema") {
|
|
657
|
+
await lintReservedNamespaceCharacterInEntityPaths("schema");
|
|
658
|
+
|
|
585
659
|
const filteredKeys = !keyPattern ? schemas : schemas.filter((key) => keyPattern.test(key));
|
|
586
660
|
|
|
587
661
|
if (filteredKeys.length > 0) {
|
|
@@ -591,7 +665,7 @@ export async function lintProject(
|
|
|
591
665
|
for (const key of filteredKeys) {
|
|
592
666
|
const fullPath = getFullPathFromKey("schema", key);
|
|
593
667
|
|
|
594
|
-
if (!
|
|
668
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
595
669
|
await reportSimpleError({
|
|
596
670
|
entityType: "schema",
|
|
597
671
|
key,
|
|
@@ -616,6 +690,47 @@ export async function lintProject(
|
|
|
616
690
|
}
|
|
617
691
|
}
|
|
618
692
|
|
|
693
|
+
// lint targets
|
|
694
|
+
const targets = await datasource.listTargets();
|
|
695
|
+
const targetZodSchema = getTargetZodSchema(projectConfig);
|
|
696
|
+
|
|
697
|
+
if (!options.entityType || options.entityType === "target") {
|
|
698
|
+
await lintReservedNamespaceCharacterInEntityPaths("target");
|
|
699
|
+
|
|
700
|
+
const filteredKeys = !keyPattern ? targets : targets.filter((key) => keyPattern.test(key));
|
|
701
|
+
|
|
702
|
+
if (filteredKeys.length > 0) {
|
|
703
|
+
log(`Linting ${filteredKeys.length} targets...\n`);
|
|
704
|
+
}
|
|
705
|
+
|
|
706
|
+
for (const key of filteredKeys) {
|
|
707
|
+
const fullPath = getFullPathFromKey("target", key);
|
|
708
|
+
|
|
709
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
710
|
+
await reportSimpleError({
|
|
711
|
+
entityType: "target",
|
|
712
|
+
key,
|
|
713
|
+
fullPath,
|
|
714
|
+
message: `Invalid name: "${key}"`,
|
|
715
|
+
detail: ENTITY_NAME_REGEX_ERROR,
|
|
716
|
+
code: "invalid_name",
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
try {
|
|
721
|
+
const parsed = await datasource.readTarget(key);
|
|
722
|
+
|
|
723
|
+
const result = targetZodSchema.safeParse(parsed);
|
|
724
|
+
|
|
725
|
+
if (!result.success && "error" in result) {
|
|
726
|
+
await reportZodValidationError("target", key, fullPath, result.error);
|
|
727
|
+
}
|
|
728
|
+
} catch (error) {
|
|
729
|
+
await reportThrownError("target", key, fullPath, error);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
|
|
619
734
|
// lint tests
|
|
620
735
|
const tests = await datasource.listTests();
|
|
621
736
|
|
|
@@ -623,9 +738,12 @@ export async function lintProject(
|
|
|
623
738
|
projectConfig,
|
|
624
739
|
features as [string, ...string[]],
|
|
625
740
|
segments as [string, ...string[]],
|
|
741
|
+
targets as [string, ...string[]],
|
|
626
742
|
);
|
|
627
743
|
|
|
628
744
|
if (!options.entityType || options.entityType === "test") {
|
|
745
|
+
await lintReservedNamespaceCharacterInEntityPaths("test");
|
|
746
|
+
|
|
629
747
|
const filteredKeys = !keyPattern ? tests : tests.filter((key) => keyPattern.test(key));
|
|
630
748
|
|
|
631
749
|
if (filteredKeys.length > 0) {
|
|
@@ -635,7 +753,7 @@ export async function lintProject(
|
|
|
635
753
|
for (const key of filteredKeys) {
|
|
636
754
|
const fullPath = getFullPathFromKey("test", key);
|
|
637
755
|
|
|
638
|
-
if (!
|
|
756
|
+
if (!isValidEntityKey(key, projectConfig.namespaceCharacter)) {
|
|
639
757
|
await reportSimpleError({
|
|
640
758
|
entityType: "test",
|
|
641
759
|
key,
|
|
@@ -671,30 +789,48 @@ export const lintPlugin: Plugin = {
|
|
|
671
789
|
handler: async function (options) {
|
|
672
790
|
const { rootDirectoryPath, projectConfig, datasource, parsed } = options;
|
|
673
791
|
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
792
|
+
assertProjectSetJsonSelection(projectConfig, parsed.set, parsed.json);
|
|
793
|
+
|
|
794
|
+
const executions = await getProjectSetExecutions(projectConfig, datasource, parsed.set);
|
|
795
|
+
let hasError = false;
|
|
796
|
+
|
|
797
|
+
for (const execution of executions) {
|
|
798
|
+
printSetHeader(projectConfig, execution.set, parsed.json);
|
|
799
|
+
|
|
800
|
+
const result = await lintProject(
|
|
801
|
+
{
|
|
802
|
+
rootDirectoryPath,
|
|
803
|
+
projectConfig: execution.projectConfig,
|
|
804
|
+
datasource: execution.datasource,
|
|
805
|
+
options: parsed,
|
|
806
|
+
},
|
|
807
|
+
{
|
|
808
|
+
keyPattern: parsed.keyPattern,
|
|
809
|
+
entityType: parsed.entityType,
|
|
810
|
+
authors: parsed.authors,
|
|
811
|
+
json: parsed.json,
|
|
812
|
+
pretty: parsed.pretty,
|
|
813
|
+
},
|
|
814
|
+
);
|
|
815
|
+
|
|
816
|
+
if (parsed.json) {
|
|
817
|
+
const payload = { errors: result.errors };
|
|
818
|
+
console.log(parsed.pretty ? JSON.stringify(payload, null, 2) : JSON.stringify(payload));
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
if (result.hasError) {
|
|
822
|
+
hasError = true;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
if (hasError) {
|
|
696
827
|
return false;
|
|
697
828
|
}
|
|
829
|
+
|
|
830
|
+
if (!parsed.json) {
|
|
831
|
+
console.log("");
|
|
832
|
+
console.log(CLI_FORMAT_GREEN, "✔ No lint errors found");
|
|
833
|
+
}
|
|
698
834
|
},
|
|
699
835
|
examples: [
|
|
700
836
|
{
|
package/src/linter/schema.ts
CHANGED
|
@@ -445,6 +445,7 @@ export function getSchemaZodSchema(schemaKeys: SchemaKey[] = []) {
|
|
|
445
445
|
z
|
|
446
446
|
.object({
|
|
447
447
|
description: z.string().optional(),
|
|
448
|
+
promotable: z.boolean().optional(),
|
|
448
449
|
type: propertyTypeEnum.optional(),
|
|
449
450
|
enum: z.array(valueZodSchema).optional(),
|
|
450
451
|
const: valueZodSchema.optional(),
|
|
@@ -17,15 +17,17 @@ function minimalProjectConfig(): ProjectConfig {
|
|
|
17
17
|
attributesDirectoryPath: "",
|
|
18
18
|
groupsDirectoryPath: "",
|
|
19
19
|
schemasDirectoryPath: "",
|
|
20
|
+
targetsDirectoryPath: "",
|
|
20
21
|
testsDirectoryPath: "",
|
|
21
22
|
stateDirectoryPath: "",
|
|
22
23
|
datafilesDirectoryPath: "",
|
|
23
24
|
datafileNamePattern: "",
|
|
24
25
|
revisionFileName: "",
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
catalogDirectoryPath: "",
|
|
27
|
+
setsDirectoryPath: "",
|
|
27
28
|
environments: ["staging", "production"],
|
|
28
|
-
|
|
29
|
+
sets: false,
|
|
30
|
+
namespaceCharacter: ".",
|
|
29
31
|
tags: ["all"],
|
|
30
32
|
adapter: {},
|
|
31
33
|
plugins: [],
|
|
@@ -6,6 +6,7 @@ export function getSegmentZodSchema(projectConfig: ProjectConfig, conditionsZodS
|
|
|
6
6
|
const segmentZodSchema = z
|
|
7
7
|
.object({
|
|
8
8
|
archived: z.boolean().optional(),
|
|
9
|
+
promotable: z.boolean().optional(),
|
|
9
10
|
description: z.string({
|
|
10
11
|
error: (issue) => (issue.input === undefined ? "Required" : undefined),
|
|
11
12
|
}),
|