@opensip-tools/fitness 1.0.4
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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-typecheck.log +4 -0
- package/LICENSE +21 -0
- package/dist/__tests__/gate.test.d.ts +13 -0
- package/dist/__tests__/gate.test.d.ts.map +1 -0
- package/dist/__tests__/gate.test.js +422 -0
- package/dist/__tests__/gate.test.js.map +1 -0
- package/dist/__tests__/sarif.test.d.ts +2 -0
- package/dist/__tests__/sarif.test.d.ts.map +1 -0
- package/dist/__tests__/sarif.test.js +169 -0
- package/dist/__tests__/sarif.test.js.map +1 -0
- package/dist/cli/dashboard.d.ts +6 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +77 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/fit.d.ts +37 -0
- package/dist/cli/fit.d.ts.map +1 -0
- package/dist/cli/fit.js +539 -0
- package/dist/cli/fit.js.map +1 -0
- package/dist/cli/list-checks.d.ts +6 -0
- package/dist/cli/list-checks.d.ts.map +1 -0
- package/dist/cli/list-checks.js +23 -0
- package/dist/cli/list-checks.js.map +1 -0
- package/dist/cli/list-recipes.d.ts +6 -0
- package/dist/cli/list-recipes.d.ts.map +1 -0
- package/dist/cli/list-recipes.js +31 -0
- package/dist/cli/list-recipes.js.map +1 -0
- package/dist/framework/__tests__/ast-utilities.test.d.ts +2 -0
- package/dist/framework/__tests__/ast-utilities.test.d.ts.map +1 -0
- package/dist/framework/__tests__/ast-utilities.test.js +153 -0
- package/dist/framework/__tests__/ast-utilities.test.js.map +1 -0
- package/dist/framework/__tests__/check-config.test.d.ts +2 -0
- package/dist/framework/__tests__/check-config.test.d.ts.map +1 -0
- package/dist/framework/__tests__/check-config.test.js +56 -0
- package/dist/framework/__tests__/check-config.test.js.map +1 -0
- package/dist/framework/__tests__/command-executor.test.d.ts +2 -0
- package/dist/framework/__tests__/command-executor.test.d.ts.map +1 -0
- package/dist/framework/__tests__/command-executor.test.js +71 -0
- package/dist/framework/__tests__/command-executor.test.js.map +1 -0
- package/dist/framework/__tests__/content-filter-dispatch.test.d.ts +2 -0
- package/dist/framework/__tests__/content-filter-dispatch.test.d.ts.map +1 -0
- package/dist/framework/__tests__/content-filter-dispatch.test.js +104 -0
- package/dist/framework/__tests__/content-filter-dispatch.test.js.map +1 -0
- package/dist/framework/__tests__/content-filter.test.d.ts +2 -0
- package/dist/framework/__tests__/content-filter.test.d.ts.map +1 -0
- package/dist/framework/__tests__/content-filter.test.js +126 -0
- package/dist/framework/__tests__/content-filter.test.js.map +1 -0
- package/dist/framework/__tests__/define-check.test.d.ts +2 -0
- package/dist/framework/__tests__/define-check.test.d.ts.map +1 -0
- package/dist/framework/__tests__/define-check.test.js +155 -0
- package/dist/framework/__tests__/define-check.test.js.map +1 -0
- package/dist/framework/__tests__/directive-inventory.test.d.ts +2 -0
- package/dist/framework/__tests__/directive-inventory.test.d.ts.map +1 -0
- package/dist/framework/__tests__/directive-inventory.test.js +44 -0
- package/dist/framework/__tests__/directive-inventory.test.js.map +1 -0
- package/dist/framework/__tests__/execution-context.test.d.ts +2 -0
- package/dist/framework/__tests__/execution-context.test.d.ts.map +1 -0
- package/dist/framework/__tests__/execution-context.test.js +62 -0
- package/dist/framework/__tests__/execution-context.test.js.map +1 -0
- package/dist/framework/__tests__/file-accessor.test.d.ts +2 -0
- package/dist/framework/__tests__/file-accessor.test.d.ts.map +1 -0
- package/dist/framework/__tests__/file-accessor.test.js +106 -0
- package/dist/framework/__tests__/file-accessor.test.js.map +1 -0
- package/dist/framework/__tests__/file-cache.test.d.ts +2 -0
- package/dist/framework/__tests__/file-cache.test.d.ts.map +1 -0
- package/dist/framework/__tests__/file-cache.test.js +122 -0
- package/dist/framework/__tests__/file-cache.test.js.map +1 -0
- package/dist/framework/__tests__/import-graph.test.d.ts +15 -0
- package/dist/framework/__tests__/import-graph.test.d.ts.map +1 -0
- package/dist/framework/__tests__/import-graph.test.js +164 -0
- package/dist/framework/__tests__/import-graph.test.js.map +1 -0
- package/dist/framework/__tests__/path-matcher.test.d.ts +2 -0
- package/dist/framework/__tests__/path-matcher.test.d.ts.map +1 -0
- package/dist/framework/__tests__/path-matcher.test.js +113 -0
- package/dist/framework/__tests__/path-matcher.test.js.map +1 -0
- package/dist/framework/__tests__/register-helpers.test.d.ts +2 -0
- package/dist/framework/__tests__/register-helpers.test.d.ts.map +1 -0
- package/dist/framework/__tests__/register-helpers.test.js +42 -0
- package/dist/framework/__tests__/register-helpers.test.js.map +1 -0
- package/dist/framework/__tests__/registry.test.d.ts +2 -0
- package/dist/framework/__tests__/registry.test.d.ts.map +1 -0
- package/dist/framework/__tests__/registry.test.js +208 -0
- package/dist/framework/__tests__/registry.test.js.map +1 -0
- package/dist/framework/__tests__/result-builder.test.d.ts +2 -0
- package/dist/framework/__tests__/result-builder.test.d.ts.map +1 -0
- package/dist/framework/__tests__/result-builder.test.js +153 -0
- package/dist/framework/__tests__/result-builder.test.js.map +1 -0
- package/dist/framework/__tests__/scope-resolver.test.d.ts +2 -0
- package/dist/framework/__tests__/scope-resolver.test.d.ts.map +1 -0
- package/dist/framework/__tests__/scope-resolver.test.js +140 -0
- package/dist/framework/__tests__/scope-resolver.test.js.map +1 -0
- package/dist/framework/__tests__/severity-mapping.test.d.ts +2 -0
- package/dist/framework/__tests__/severity-mapping.test.d.ts.map +1 -0
- package/dist/framework/__tests__/severity-mapping.test.js +42 -0
- package/dist/framework/__tests__/severity-mapping.test.js.map +1 -0
- package/dist/framework/__tests__/strip-literals.test.d.ts +2 -0
- package/dist/framework/__tests__/strip-literals.test.d.ts.map +1 -0
- package/dist/framework/__tests__/strip-literals.test.js +87 -0
- package/dist/framework/__tests__/strip-literals.test.js.map +1 -0
- package/dist/framework/abortable-exec.d.ts +34 -0
- package/dist/framework/abortable-exec.d.ts.map +1 -0
- package/dist/framework/abortable-exec.js +136 -0
- package/dist/framework/abortable-exec.js.map +1 -0
- package/dist/framework/ast-utilities.d.ts +41 -0
- package/dist/framework/ast-utilities.d.ts.map +1 -0
- package/dist/framework/ast-utilities.js +106 -0
- package/dist/framework/ast-utilities.js.map +1 -0
- package/dist/framework/check-config.d.ts +171 -0
- package/dist/framework/check-config.d.ts.map +1 -0
- package/dist/framework/check-config.js +114 -0
- package/dist/framework/check-config.js.map +1 -0
- package/dist/framework/check-types.d.ts +57 -0
- package/dist/framework/check-types.d.ts.map +1 -0
- package/dist/framework/check-types.js +35 -0
- package/dist/framework/check-types.js.map +1 -0
- package/dist/framework/command-executor.d.ts +25 -0
- package/dist/framework/command-executor.d.ts.map +1 -0
- package/dist/framework/command-executor.js +63 -0
- package/dist/framework/command-executor.js.map +1 -0
- package/dist/framework/constants.d.ts +9 -0
- package/dist/framework/constants.d.ts.map +1 -0
- package/dist/framework/constants.js +16 -0
- package/dist/framework/constants.js.map +1 -0
- package/dist/framework/content-filter.d.ts +33 -0
- package/dist/framework/content-filter.d.ts.map +1 -0
- package/dist/framework/content-filter.js +236 -0
- package/dist/framework/content-filter.js.map +1 -0
- package/dist/framework/define-check.d.ts +38 -0
- package/dist/framework/define-check.d.ts.map +1 -0
- package/dist/framework/define-check.js +252 -0
- package/dist/framework/define-check.js.map +1 -0
- package/dist/framework/directive-inventory.d.ts +34 -0
- package/dist/framework/directive-inventory.d.ts.map +1 -0
- package/dist/framework/directive-inventory.js +77 -0
- package/dist/framework/directive-inventory.js.map +1 -0
- package/dist/framework/directive-parsing.d.ts +20 -0
- package/dist/framework/directive-parsing.d.ts.map +1 -0
- package/dist/framework/directive-parsing.js +121 -0
- package/dist/framework/directive-parsing.js.map +1 -0
- package/dist/framework/execution-context.d.ts +95 -0
- package/dist/framework/execution-context.d.ts.map +1 -0
- package/dist/framework/execution-context.js +122 -0
- package/dist/framework/execution-context.js.map +1 -0
- package/dist/framework/file-accessor.d.ts +20 -0
- package/dist/framework/file-accessor.d.ts.map +1 -0
- package/dist/framework/file-accessor.js +122 -0
- package/dist/framework/file-accessor.js.map +1 -0
- package/dist/framework/file-cache.d.ts +70 -0
- package/dist/framework/file-cache.d.ts.map +1 -0
- package/dist/framework/file-cache.js +178 -0
- package/dist/framework/file-cache.js.map +1 -0
- package/dist/framework/file-type-filter.d.ts +11 -0
- package/dist/framework/file-type-filter.d.ts.map +1 -0
- package/dist/framework/file-type-filter.js +21 -0
- package/dist/framework/file-type-filter.js.map +1 -0
- package/dist/framework/ignore-processing.d.ts +22 -0
- package/dist/framework/ignore-processing.d.ts.map +1 -0
- package/dist/framework/ignore-processing.js +241 -0
- package/dist/framework/ignore-processing.js.map +1 -0
- package/dist/framework/import-graph.d.ts +51 -0
- package/dist/framework/import-graph.d.ts.map +1 -0
- package/dist/framework/import-graph.js +216 -0
- package/dist/framework/import-graph.js.map +1 -0
- package/dist/framework/memory-profiler.d.ts +53 -0
- package/dist/framework/memory-profiler.d.ts.map +1 -0
- package/dist/framework/memory-profiler.js +92 -0
- package/dist/framework/memory-profiler.js.map +1 -0
- package/dist/framework/parse-cache.d.ts +23 -0
- package/dist/framework/parse-cache.d.ts.map +1 -0
- package/dist/framework/parse-cache.js +37 -0
- package/dist/framework/parse-cache.js.map +1 -0
- package/dist/framework/path-matcher.d.ts +86 -0
- package/dist/framework/path-matcher.d.ts.map +1 -0
- package/dist/framework/path-matcher.js +138 -0
- package/dist/framework/path-matcher.js.map +1 -0
- package/dist/framework/register-helpers.d.ts +10 -0
- package/dist/framework/register-helpers.d.ts.map +1 -0
- package/dist/framework/register-helpers.js +17 -0
- package/dist/framework/register-helpers.js.map +1 -0
- package/dist/framework/registry.d.ts +41 -0
- package/dist/framework/registry.d.ts.map +1 -0
- package/dist/framework/registry.js +103 -0
- package/dist/framework/registry.js.map +1 -0
- package/dist/framework/result-builder.d.ts +74 -0
- package/dist/framework/result-builder.d.ts.map +1 -0
- package/dist/framework/result-builder.js +154 -0
- package/dist/framework/result-builder.js.map +1 -0
- package/dist/framework/scope-resolver.d.ts +23 -0
- package/dist/framework/scope-resolver.d.ts.map +1 -0
- package/dist/framework/scope-resolver.js +201 -0
- package/dist/framework/scope-resolver.js.map +1 -0
- package/dist/framework/severity-mapping.d.ts +13 -0
- package/dist/framework/severity-mapping.d.ts.map +1 -0
- package/dist/framework/severity-mapping.js +51 -0
- package/dist/framework/severity-mapping.js.map +1 -0
- package/dist/framework/strip-literals.d.ts +48 -0
- package/dist/framework/strip-literals.d.ts.map +1 -0
- package/dist/framework/strip-literals.js +188 -0
- package/dist/framework/strip-literals.js.map +1 -0
- package/dist/gate.d.ts +74 -0
- package/dist/gate.d.ts.map +1 -0
- package/dist/gate.js +257 -0
- package/dist/gate.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/plugins/__tests__/check-package-discovery.test.d.ts +2 -0
- package/dist/plugins/__tests__/check-package-discovery.test.d.ts.map +1 -0
- package/dist/plugins/__tests__/check-package-discovery.test.js +170 -0
- package/dist/plugins/__tests__/check-package-discovery.test.js.map +1 -0
- package/dist/plugins/__tests__/lang-domain.test.d.ts +2 -0
- package/dist/plugins/__tests__/lang-domain.test.d.ts.map +1 -0
- package/dist/plugins/__tests__/lang-domain.test.js +171 -0
- package/dist/plugins/__tests__/lang-domain.test.js.map +1 -0
- package/dist/plugins/__tests__/loader.test.d.ts +2 -0
- package/dist/plugins/__tests__/loader.test.d.ts.map +1 -0
- package/dist/plugins/__tests__/loader.test.js +194 -0
- package/dist/plugins/__tests__/loader.test.js.map +1 -0
- package/dist/plugins/check-package-discovery.d.ts +73 -0
- package/dist/plugins/check-package-discovery.d.ts.map +1 -0
- package/dist/plugins/check-package-discovery.js +212 -0
- package/dist/plugins/check-package-discovery.js.map +1 -0
- package/dist/plugins/loader.d.ts +31 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +290 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/types.d.ts +23 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +9 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/recipes/__tests__/built-in-recipes.test.d.ts +2 -0
- package/dist/recipes/__tests__/built-in-recipes.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/built-in-recipes.test.js +93 -0
- package/dist/recipes/__tests__/built-in-recipes.test.js.map +1 -0
- package/dist/recipes/__tests__/check-config.test.d.ts +5 -0
- package/dist/recipes/__tests__/check-config.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/check-config.test.js +37 -0
- package/dist/recipes/__tests__/check-config.test.js.map +1 -0
- package/dist/recipes/__tests__/check-resolution.test.d.ts +2 -0
- package/dist/recipes/__tests__/check-resolution.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/check-resolution.test.js +135 -0
- package/dist/recipes/__tests__/check-resolution.test.js.map +1 -0
- package/dist/recipes/__tests__/registry.test.d.ts +2 -0
- package/dist/recipes/__tests__/registry.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/registry.test.js +97 -0
- package/dist/recipes/__tests__/registry.test.js.map +1 -0
- package/dist/recipes/__tests__/retry.test.d.ts +2 -0
- package/dist/recipes/__tests__/retry.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/retry.test.js +75 -0
- package/dist/recipes/__tests__/retry.test.js.map +1 -0
- package/dist/recipes/__tests__/service.test.d.ts +11 -0
- package/dist/recipes/__tests__/service.test.d.ts.map +1 -0
- package/dist/recipes/__tests__/service.test.js +482 -0
- package/dist/recipes/__tests__/service.test.js.map +1 -0
- package/dist/recipes/built-in-recipes.d.ts +14 -0
- package/dist/recipes/built-in-recipes.d.ts.map +1 -0
- package/dist/recipes/built-in-recipes.js +247 -0
- package/dist/recipes/built-in-recipes.js.map +1 -0
- package/dist/recipes/check-config.d.ts +40 -0
- package/dist/recipes/check-config.d.ts.map +1 -0
- package/dist/recipes/check-config.js +61 -0
- package/dist/recipes/check-config.js.map +1 -0
- package/dist/recipes/check-resolution.d.ts +21 -0
- package/dist/recipes/check-resolution.d.ts.map +1 -0
- package/dist/recipes/check-resolution.js +121 -0
- package/dist/recipes/check-resolution.js.map +1 -0
- package/dist/recipes/check-result-processor.d.ts +51 -0
- package/dist/recipes/check-result-processor.d.ts.map +1 -0
- package/dist/recipes/check-result-processor.js +158 -0
- package/dist/recipes/check-result-processor.js.map +1 -0
- package/dist/recipes/parallel-execution.d.ts +33 -0
- package/dist/recipes/parallel-execution.d.ts.map +1 -0
- package/dist/recipes/parallel-execution.js +142 -0
- package/dist/recipes/parallel-execution.js.map +1 -0
- package/dist/recipes/registry.d.ts +81 -0
- package/dist/recipes/registry.d.ts.map +1 -0
- package/dist/recipes/registry.js +131 -0
- package/dist/recipes/registry.js.map +1 -0
- package/dist/recipes/retry.d.ts +25 -0
- package/dist/recipes/retry.d.ts.map +1 -0
- package/dist/recipes/retry.js +44 -0
- package/dist/recipes/retry.js.map +1 -0
- package/dist/recipes/sequential-execution.d.ts +10 -0
- package/dist/recipes/sequential-execution.d.ts.map +1 -0
- package/dist/recipes/sequential-execution.js +122 -0
- package/dist/recipes/sequential-execution.js.map +1 -0
- package/dist/recipes/service-types.d.ts +84 -0
- package/dist/recipes/service-types.d.ts.map +1 -0
- package/dist/recipes/service-types.js +8 -0
- package/dist/recipes/service-types.js.map +1 -0
- package/dist/recipes/service.d.ts +71 -0
- package/dist/recipes/service.d.ts.map +1 -0
- package/dist/recipes/service.js +331 -0
- package/dist/recipes/service.js.map +1 -0
- package/dist/recipes/types.d.ts +154 -0
- package/dist/recipes/types.d.ts.map +1 -0
- package/dist/recipes/types.js +54 -0
- package/dist/recipes/types.js.map +1 -0
- package/dist/sarif.d.ts +34 -0
- package/dist/sarif.d.ts.map +1 -0
- package/dist/sarif.js +192 -0
- package/dist/sarif.js.map +1 -0
- package/dist/signalers/__tests__/loader.test.d.ts +2 -0
- package/dist/signalers/__tests__/loader.test.d.ts.map +1 -0
- package/dist/signalers/__tests__/loader.test.js +74 -0
- package/dist/signalers/__tests__/loader.test.js.map +1 -0
- package/dist/signalers/index.d.ts +8 -0
- package/dist/signalers/index.d.ts.map +1 -0
- package/dist/signalers/index.js +9 -0
- package/dist/signalers/index.js.map +1 -0
- package/dist/signalers/loader.d.ts +24 -0
- package/dist/signalers/loader.d.ts.map +1 -0
- package/dist/signalers/loader.js +108 -0
- package/dist/signalers/loader.js.map +1 -0
- package/dist/signalers/schema.d.ts +288 -0
- package/dist/signalers/schema.d.ts.map +1 -0
- package/dist/signalers/schema.js +99 -0
- package/dist/signalers/schema.js.map +1 -0
- package/dist/signalers/types.d.ts +13 -0
- package/dist/signalers/types.d.ts.map +1 -0
- package/dist/signalers/types.js +5 -0
- package/dist/signalers/types.js.map +1 -0
- package/dist/targets/__tests__/loader.test.d.ts +2 -0
- package/dist/targets/__tests__/loader.test.d.ts.map +1 -0
- package/dist/targets/__tests__/loader.test.js +127 -0
- package/dist/targets/__tests__/loader.test.js.map +1 -0
- package/dist/targets/__tests__/resolver.test.d.ts +2 -0
- package/dist/targets/__tests__/resolver.test.d.ts.map +1 -0
- package/dist/targets/__tests__/resolver.test.js +54 -0
- package/dist/targets/__tests__/resolver.test.js.map +1 -0
- package/dist/targets/__tests__/target-registry.test.d.ts +2 -0
- package/dist/targets/__tests__/target-registry.test.d.ts.map +1 -0
- package/dist/targets/__tests__/target-registry.test.js +89 -0
- package/dist/targets/__tests__/target-registry.test.js.map +1 -0
- package/dist/targets/index.d.ts +10 -0
- package/dist/targets/index.d.ts.map +1 -0
- package/dist/targets/index.js +12 -0
- package/dist/targets/index.js.map +1 -0
- package/dist/targets/loader.d.ts +19 -0
- package/dist/targets/loader.d.ts.map +1 -0
- package/dist/targets/loader.js +159 -0
- package/dist/targets/loader.js.map +1 -0
- package/dist/targets/resolver.d.ts +19 -0
- package/dist/targets/resolver.d.ts.map +1 -0
- package/dist/targets/resolver.js +37 -0
- package/dist/targets/resolver.js.map +1 -0
- package/dist/targets/target-registry.d.ts +61 -0
- package/dist/targets/target-registry.d.ts.map +1 -0
- package/dist/targets/target-registry.js +93 -0
- package/dist/targets/target-registry.js.map +1 -0
- package/dist/targets/types.d.ts +85 -0
- package/dist/targets/types.d.ts.map +1 -0
- package/dist/targets/types.js +5 -0
- package/dist/targets/types.js.map +1 -0
- package/dist/tool.d.ts +17 -0
- package/dist/tool.d.ts.map +1 -0
- package/dist/tool.js +282 -0
- package/dist/tool.js.map +1 -0
- package/dist/types/findings.d.ts +117 -0
- package/dist/types/findings.d.ts.map +1 -0
- package/dist/types/findings.js +93 -0
- package/dist/types/findings.js.map +1 -0
- package/dist/types/severity.d.ts +15 -0
- package/dist/types/severity.d.ts.map +1 -0
- package/dist/types/severity.js +36 -0
- package/dist/types/severity.js.map +1 -0
- package/package.json +45 -0
- package/src/__tests__/gate.test.ts +537 -0
- package/src/__tests__/sarif.test.ts +201 -0
- package/src/cli/dashboard.ts +93 -0
- package/src/cli/fit.ts +612 -0
- package/src/cli/list-checks.ts +32 -0
- package/src/cli/list-recipes.ts +38 -0
- package/src/framework/__tests__/ast-utilities.test.ts +157 -0
- package/src/framework/__tests__/check-config.test.ts +65 -0
- package/src/framework/__tests__/command-executor.test.ts +79 -0
- package/src/framework/__tests__/content-filter-dispatch.test.ts +132 -0
- package/src/framework/__tests__/content-filter.test.ts +136 -0
- package/src/framework/__tests__/define-check.test.ts +180 -0
- package/src/framework/__tests__/directive-inventory.test.ts +53 -0
- package/src/framework/__tests__/execution-context.test.ts +80 -0
- package/src/framework/__tests__/file-accessor.test.ts +121 -0
- package/src/framework/__tests__/file-cache.test.ts +142 -0
- package/src/framework/__tests__/import-graph.test.ts +282 -0
- package/src/framework/__tests__/path-matcher.test.ts +130 -0
- package/src/framework/__tests__/register-helpers.test.ts +51 -0
- package/src/framework/__tests__/registry.test.ts +243 -0
- package/src/framework/__tests__/result-builder.test.ts +178 -0
- package/src/framework/__tests__/scope-resolver.test.ts +208 -0
- package/src/framework/__tests__/severity-mapping.test.ts +50 -0
- package/src/framework/__tests__/strip-literals.test.ts +109 -0
- package/src/framework/abortable-exec.ts +177 -0
- package/src/framework/ast-utilities.ts +112 -0
- package/src/framework/check-config.ts +339 -0
- package/src/framework/check-types.ts +77 -0
- package/src/framework/command-executor.ts +100 -0
- package/src/framework/constants.ts +16 -0
- package/src/framework/content-filter.ts +288 -0
- package/src/framework/define-check.ts +336 -0
- package/src/framework/directive-inventory.ts +110 -0
- package/src/framework/directive-parsing.ts +152 -0
- package/src/framework/execution-context.ts +247 -0
- package/src/framework/file-accessor.ts +171 -0
- package/src/framework/file-cache.ts +220 -0
- package/src/framework/file-type-filter.ts +25 -0
- package/src/framework/ignore-processing.ts +350 -0
- package/src/framework/import-graph.ts +280 -0
- package/src/framework/memory-profiler.ts +145 -0
- package/src/framework/parse-cache.ts +38 -0
- package/src/framework/path-matcher.ts +191 -0
- package/src/framework/register-helpers.ts +20 -0
- package/src/framework/registry.ts +125 -0
- package/src/framework/result-builder.ts +225 -0
- package/src/framework/scope-resolver.ts +262 -0
- package/src/framework/severity-mapping.ts +56 -0
- package/src/framework/strip-literals.ts +200 -0
- package/src/gate.ts +337 -0
- package/src/index.ts +110 -0
- package/src/plugins/__tests__/check-package-discovery.test.ts +204 -0
- package/src/plugins/__tests__/lang-domain.test.ts +198 -0
- package/src/plugins/__tests__/loader.test.ts +226 -0
- package/src/plugins/check-package-discovery.ts +242 -0
- package/src/plugins/loader.ts +327 -0
- package/src/plugins/types.ts +25 -0
- package/src/recipes/__tests__/built-in-recipes.test.ts +107 -0
- package/src/recipes/__tests__/check-config.test.ts +51 -0
- package/src/recipes/__tests__/check-resolution.test.ts +185 -0
- package/src/recipes/__tests__/registry.test.ts +115 -0
- package/src/recipes/__tests__/retry.test.ts +83 -0
- package/src/recipes/__tests__/service.test.ts +572 -0
- package/src/recipes/built-in-recipes.ts +273 -0
- package/src/recipes/check-config.ts +64 -0
- package/src/recipes/check-resolution.ts +169 -0
- package/src/recipes/check-result-processor.ts +258 -0
- package/src/recipes/parallel-execution.ts +220 -0
- package/src/recipes/registry.ts +192 -0
- package/src/recipes/retry.ts +69 -0
- package/src/recipes/sequential-execution.ts +139 -0
- package/src/recipes/service-types.ts +105 -0
- package/src/recipes/service.ts +400 -0
- package/src/recipes/types.ts +247 -0
- package/src/sarif.ts +232 -0
- package/src/signalers/__tests__/loader.test.ts +99 -0
- package/src/signalers/index.ts +9 -0
- package/src/signalers/loader.ts +141 -0
- package/src/signalers/schema.ts +117 -0
- package/src/signalers/types.ts +15 -0
- package/src/targets/__tests__/loader.test.ts +170 -0
- package/src/targets/__tests__/resolver.test.ts +74 -0
- package/src/targets/__tests__/target-registry.test.ts +103 -0
- package/src/targets/index.ts +13 -0
- package/src/targets/loader.ts +214 -0
- package/src/targets/resolver.ts +44 -0
- package/src/targets/target-registry.ts +111 -0
- package/src/targets/types.ts +89 -0
- package/src/tool.ts +302 -0
- package/src/types/findings.ts +239 -0
- package/src/types/severity.ts +39 -0
- package/tsconfig.json +8 -0
- package/vitest.config.ts +33 -0
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Built-in fitness recipe definitions
|
|
3
|
+
*
|
|
4
|
+
* Defines the standard set of recipes (default, quick-smoke, backend, etc.)
|
|
5
|
+
* that ship with the fitness framework.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { DEFAULT_MAX_PARALLEL, defineRecipe, type FitnessRecipe } from './types.js'
|
|
9
|
+
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// DEFAULT RECIPE
|
|
12
|
+
// =============================================================================
|
|
13
|
+
|
|
14
|
+
/** Default recipe: runs all enabled checks in parallel */
|
|
15
|
+
const defaultRecipe: FitnessRecipe = defineRecipe({
|
|
16
|
+
name: 'default',
|
|
17
|
+
displayName: 'Default',
|
|
18
|
+
description: 'Run all enabled checks in parallel',
|
|
19
|
+
checks: { type: 'all' },
|
|
20
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 30_000 },
|
|
21
|
+
reporting: { format: 'table', verbose: false },
|
|
22
|
+
tags: ['comprehensive', 'default'],
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// =============================================================================
|
|
26
|
+
// QUICK SMOKE RECIPE
|
|
27
|
+
// =============================================================================
|
|
28
|
+
|
|
29
|
+
/** Quick smoke recipe: fast critical checks for rapid validation */
|
|
30
|
+
const quickSmokeRecipe: FitnessRecipe = defineRecipe({
|
|
31
|
+
name: 'quick-smoke',
|
|
32
|
+
displayName: 'Quick Smoke',
|
|
33
|
+
description: 'Fast critical checks for rapid validation',
|
|
34
|
+
checks: {
|
|
35
|
+
type: 'explicit',
|
|
36
|
+
checkIds: [
|
|
37
|
+
'no-console-log',
|
|
38
|
+
'no-any-types',
|
|
39
|
+
'null-safety',
|
|
40
|
+
'detached-promises',
|
|
41
|
+
'catch-clause-safety',
|
|
42
|
+
'error-handling-quality',
|
|
43
|
+
'no-hardcoded-secrets',
|
|
44
|
+
'no-eval',
|
|
45
|
+
'sql-injection',
|
|
46
|
+
'env-secret-exposure',
|
|
47
|
+
'input-sanitization',
|
|
48
|
+
'no-focused-tests',
|
|
49
|
+
'no-skipped-tests',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 15_000 },
|
|
53
|
+
reporting: { format: 'table', verbose: false },
|
|
54
|
+
tags: ['fast', 'smoke', 'critical'],
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// BACKEND RECIPE
|
|
59
|
+
// =============================================================================
|
|
60
|
+
|
|
61
|
+
/** Backend recipe: architecture, resilience, and quality checks for server code */
|
|
62
|
+
const backendRecipe: FitnessRecipe = defineRecipe({
|
|
63
|
+
name: 'backend',
|
|
64
|
+
displayName: 'Backend',
|
|
65
|
+
description: 'Backend-focused checks (architecture, resilience, quality)',
|
|
66
|
+
checks: {
|
|
67
|
+
type: 'pattern',
|
|
68
|
+
include: [
|
|
69
|
+
'architecture/*',
|
|
70
|
+
'resilience/*',
|
|
71
|
+
'quality/*-backend',
|
|
72
|
+
'quality/fastify-*',
|
|
73
|
+
'quality/database-*',
|
|
74
|
+
'quality/pino-*',
|
|
75
|
+
'quality/logging-*',
|
|
76
|
+
'quality/correlation-*',
|
|
77
|
+
'quality/no-console-log',
|
|
78
|
+
'quality/result-pattern-*',
|
|
79
|
+
'quality/api-*',
|
|
80
|
+
'quality/null-safety',
|
|
81
|
+
'quality/no-any-types',
|
|
82
|
+
'quality/file-headers',
|
|
83
|
+
'quality/concurrency-safety',
|
|
84
|
+
'quality/error-swallowing-*',
|
|
85
|
+
'security/*',
|
|
86
|
+
'testing/*',
|
|
87
|
+
],
|
|
88
|
+
exclude: ['quality/*-frontend', 'testing/*-frontend'],
|
|
89
|
+
},
|
|
90
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 30_000 },
|
|
91
|
+
reporting: { format: 'table', verbose: false },
|
|
92
|
+
tags: ['backend', 'server', 'api'],
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// =============================================================================
|
|
96
|
+
// FRONTEND RECIPE
|
|
97
|
+
// =============================================================================
|
|
98
|
+
|
|
99
|
+
/** Frontend recipe: React and accessibility checks for UI code */
|
|
100
|
+
const frontendRecipe: FitnessRecipe = defineRecipe({
|
|
101
|
+
name: 'frontend',
|
|
102
|
+
displayName: 'Frontend',
|
|
103
|
+
description: 'Frontend-focused checks (React, accessibility)',
|
|
104
|
+
checks: {
|
|
105
|
+
type: 'pattern',
|
|
106
|
+
include: [
|
|
107
|
+
'quality/*-frontend',
|
|
108
|
+
'quality/accessible-*',
|
|
109
|
+
'quality/navigation-*',
|
|
110
|
+
'quality/theme-*',
|
|
111
|
+
'quality/image-*',
|
|
112
|
+
'quality/lazy-*',
|
|
113
|
+
'quality/no-inline-functions',
|
|
114
|
+
'quality/async-state-*',
|
|
115
|
+
'quality/no-any-types',
|
|
116
|
+
'quality/null-safety',
|
|
117
|
+
'architecture/heavy-import-detection',
|
|
118
|
+
'testing/no-focused-tests',
|
|
119
|
+
'testing/no-skipped-tests',
|
|
120
|
+
'testing/*-frontend',
|
|
121
|
+
],
|
|
122
|
+
exclude: ['quality/*-backend', 'testing/*-backend'],
|
|
123
|
+
},
|
|
124
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 30_000 },
|
|
125
|
+
reporting: { format: 'table', verbose: false },
|
|
126
|
+
tags: ['frontend', 'react', 'ui'],
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// =============================================================================
|
|
130
|
+
// SECURITY RECIPE
|
|
131
|
+
// =============================================================================
|
|
132
|
+
|
|
133
|
+
/** Security recipe: comprehensive security audit checks */
|
|
134
|
+
const securityRecipe: FitnessRecipe = defineRecipe({
|
|
135
|
+
name: 'security',
|
|
136
|
+
displayName: 'Security Audit',
|
|
137
|
+
description: 'Comprehensive security analysis',
|
|
138
|
+
checks: {
|
|
139
|
+
type: 'pattern',
|
|
140
|
+
include: [
|
|
141
|
+
'security/*',
|
|
142
|
+
'quality/pii-*',
|
|
143
|
+
'quality/dependency-security-*',
|
|
144
|
+
'quality/centralized-input-*',
|
|
145
|
+
'quality/security-*',
|
|
146
|
+
'quality/no-console-log',
|
|
147
|
+
'resilience/no-custom-cache',
|
|
148
|
+
'resilience/no-custom-rate-limiter',
|
|
149
|
+
'resilience/context-leakage',
|
|
150
|
+
],
|
|
151
|
+
},
|
|
152
|
+
execution: { mode: 'sequential', stopOnFirstFailure: false, timeout: 60_000 },
|
|
153
|
+
reporting: { format: 'table', verbose: true },
|
|
154
|
+
tags: ['security', 'audit', 'comprehensive'],
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
// =============================================================================
|
|
158
|
+
// PRE-COMMIT RECIPE
|
|
159
|
+
// =============================================================================
|
|
160
|
+
|
|
161
|
+
/** Pre-commit recipe: fast checks suitable for git pre-commit hooks */
|
|
162
|
+
const preCommitRecipe: FitnessRecipe = defineRecipe({
|
|
163
|
+
name: 'pre-commit',
|
|
164
|
+
displayName: 'Pre-Commit',
|
|
165
|
+
description: 'Fast checks for git pre-commit hooks',
|
|
166
|
+
checks: {
|
|
167
|
+
type: 'explicit',
|
|
168
|
+
checkIds: [
|
|
169
|
+
'no-console-log',
|
|
170
|
+
'no-any-types',
|
|
171
|
+
'no-hardcoded-secrets',
|
|
172
|
+
'detached-promises',
|
|
173
|
+
'no-focused-tests',
|
|
174
|
+
'no-skipped-tests',
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
execution: { mode: 'parallel', stopOnFirstFailure: true, timeout: 10_000 },
|
|
178
|
+
reporting: { format: 'table', verbose: false },
|
|
179
|
+
tags: ['fast', 'hook', 'pre-commit'],
|
|
180
|
+
})
|
|
181
|
+
|
|
182
|
+
// =============================================================================
|
|
183
|
+
// PRE-RELEASE RECIPE
|
|
184
|
+
// =============================================================================
|
|
185
|
+
|
|
186
|
+
/** Pre-release recipe: comprehensive checks run before a release */
|
|
187
|
+
const preReleaseRecipe: FitnessRecipe = defineRecipe({
|
|
188
|
+
name: 'pre-release',
|
|
189
|
+
displayName: 'Pre-Release',
|
|
190
|
+
description: 'Comprehensive checks before release',
|
|
191
|
+
checks: { type: 'all' },
|
|
192
|
+
execution: { mode: 'sequential', stopOnFirstFailure: false, timeout: 120_000 },
|
|
193
|
+
reporting: { format: 'unified', verbose: true },
|
|
194
|
+
tags: ['comprehensive', 'release', 'thorough'],
|
|
195
|
+
})
|
|
196
|
+
|
|
197
|
+
// =============================================================================
|
|
198
|
+
// NIGHTLY FULL RECIPE
|
|
199
|
+
// =============================================================================
|
|
200
|
+
|
|
201
|
+
/** Nightly full recipe: complete check suite for scheduled nightly runs */
|
|
202
|
+
const nightlyFullRecipe: FitnessRecipe = defineRecipe({
|
|
203
|
+
name: 'nightly-full',
|
|
204
|
+
displayName: 'Nightly Full',
|
|
205
|
+
description: 'Complete suite for nightly scheduled runs',
|
|
206
|
+
checks: { type: 'all' },
|
|
207
|
+
execution: {
|
|
208
|
+
mode: 'parallel',
|
|
209
|
+
stopOnFirstFailure: false,
|
|
210
|
+
timeout: 300_000,
|
|
211
|
+
maxParallel: DEFAULT_MAX_PARALLEL,
|
|
212
|
+
},
|
|
213
|
+
reporting: { format: 'unified', verbose: true, outputPath: 'fitness-nightly-report.json' },
|
|
214
|
+
tags: ['nightly', 'comprehensive', 'scheduled'],
|
|
215
|
+
})
|
|
216
|
+
|
|
217
|
+
// =============================================================================
|
|
218
|
+
// CI RECIPE
|
|
219
|
+
// =============================================================================
|
|
220
|
+
|
|
221
|
+
/** CI recipe: optimized for CI pipelines with JSON output */
|
|
222
|
+
const ciRecipe: FitnessRecipe = defineRecipe({
|
|
223
|
+
name: 'ci',
|
|
224
|
+
displayName: 'CI',
|
|
225
|
+
description: 'Optimized for CI pipelines with JSON output',
|
|
226
|
+
checks: { type: 'all', exclude: ['testing/flaky-*', 'performance/*'] },
|
|
227
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 60_000 },
|
|
228
|
+
reporting: { format: 'json', verbose: false },
|
|
229
|
+
tags: ['ci', 'pipeline', 'automated'],
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
// =============================================================================
|
|
233
|
+
// ARCHITECTURE RECIPE
|
|
234
|
+
// =============================================================================
|
|
235
|
+
|
|
236
|
+
/** Architecture recipe: architecture validation and compliance checks */
|
|
237
|
+
const architectureRecipe: FitnessRecipe = defineRecipe({
|
|
238
|
+
name: 'architecture',
|
|
239
|
+
displayName: 'Architecture Review',
|
|
240
|
+
description: 'Architecture validation and compliance',
|
|
241
|
+
checks: { type: 'tags', include: ['architecture'] },
|
|
242
|
+
execution: { mode: 'parallel', stopOnFirstFailure: false, timeout: 30_000 },
|
|
243
|
+
reporting: { format: 'table', verbose: true },
|
|
244
|
+
tags: ['architecture', 'structure'],
|
|
245
|
+
})
|
|
246
|
+
|
|
247
|
+
// =============================================================================
|
|
248
|
+
// EXPORTS
|
|
249
|
+
// =============================================================================
|
|
250
|
+
|
|
251
|
+
/** All built-in fitness recipes */
|
|
252
|
+
export const builtInRecipes: readonly FitnessRecipe[] = Object.freeze([
|
|
253
|
+
defaultRecipe,
|
|
254
|
+
quickSmokeRecipe,
|
|
255
|
+
backendRecipe,
|
|
256
|
+
frontendRecipe,
|
|
257
|
+
securityRecipe,
|
|
258
|
+
preCommitRecipe,
|
|
259
|
+
preReleaseRecipe,
|
|
260
|
+
nightlyFullRecipe,
|
|
261
|
+
ciRecipe,
|
|
262
|
+
architectureRecipe,
|
|
263
|
+
])
|
|
264
|
+
|
|
265
|
+
/** Map of built-in recipe name to recipe definition */
|
|
266
|
+
export const builtInRecipesByName: ReadonlyMap<string, FitnessRecipe> = new Map(
|
|
267
|
+
builtInRecipes.map((recipe) => [recipe.name, recipe]),
|
|
268
|
+
)
|
|
269
|
+
|
|
270
|
+
/** Check whether a recipe name corresponds to a built-in recipe */
|
|
271
|
+
export function isBuiltInRecipe(name: string): boolean {
|
|
272
|
+
return builtInRecipesByName.has(name)
|
|
273
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Per-check recipe configuration plumbing.
|
|
3
|
+
*
|
|
4
|
+
* Recipes can carry a `checks.config` map keyed by check slug. The recipe
|
|
5
|
+
* service projects this map into module-level state before any check runs
|
|
6
|
+
* (`setCurrentRecipeCheckConfig`) and clears it once the run completes
|
|
7
|
+
* (`clearCurrentRecipeCheckConfig`).
|
|
8
|
+
*
|
|
9
|
+
* Individual checks read their slice via `getCheckConfig<T>(slug)` —
|
|
10
|
+
* typically once at module load (when imported by the registry) or at the
|
|
11
|
+
* top of `analyze` — and merge it with their built-in defaults.
|
|
12
|
+
*
|
|
13
|
+
* This is the seam that lets us keep `@opensip-tools/checks-builtin`'s
|
|
14
|
+
* defaults to *generic* conventions (Node stdlib, well-known SDKs, common
|
|
15
|
+
* filename patterns) while letting downstream projects (like opensip)
|
|
16
|
+
* extend the safe-lists with project-specific names.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import type { RecipeCheckConfigMap } from './types.js'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Module-scoped current-recipe config. Populated by the recipe service at
|
|
23
|
+
* the start of a run and cleared at the end. Checks read from it lazily via
|
|
24
|
+
* {@link getCheckConfig}.
|
|
25
|
+
*
|
|
26
|
+
* Module-level singleton is acceptable here because a recipe service runs
|
|
27
|
+
* one session at a time (the service throws SESSION_IN_PROGRESS otherwise).
|
|
28
|
+
* If we ever support concurrent recipe runs in the same process, this needs
|
|
29
|
+
* to move into AsyncLocalStorage.
|
|
30
|
+
*/
|
|
31
|
+
let currentRecipeCheckConfig: RecipeCheckConfigMap | undefined
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Read the per-check config slice for the given slug.
|
|
35
|
+
*
|
|
36
|
+
* Returns an empty object when no recipe-config has been set or no entry
|
|
37
|
+
* exists for the slug — checks that call this should treat the result as
|
|
38
|
+
* "augmentation only" and merge with their own defaults.
|
|
39
|
+
*
|
|
40
|
+
* @typeParam T - The shape the calling check expects. Each check declares
|
|
41
|
+
* its own config interface.
|
|
42
|
+
*/
|
|
43
|
+
export function getCheckConfig<T extends Record<string, unknown>>(slug: string): T {
|
|
44
|
+
if (!currentRecipeCheckConfig) return {} as T
|
|
45
|
+
const entry = currentRecipeCheckConfig[slug]
|
|
46
|
+
if (!entry) return {} as T
|
|
47
|
+
return entry as T
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Replace the module-level recipe config. Called by the recipe service at
|
|
52
|
+
* the start of a recipe run, before any check executes.
|
|
53
|
+
*/
|
|
54
|
+
export function setCurrentRecipeCheckConfig(config: RecipeCheckConfigMap | undefined): void {
|
|
55
|
+
currentRecipeCheckConfig = config
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Clear the module-level recipe config. Called by the recipe service at
|
|
60
|
+
* the end of a recipe run (success or failure).
|
|
61
|
+
*/
|
|
62
|
+
export function clearCurrentRecipeCheckConfig(): void {
|
|
63
|
+
currentRecipeCheckConfig = undefined
|
|
64
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// @fitness-ignore-file batch-operation-limits -- iterates bounded collections (config entries, registry items, or small analysis results)
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Check resolution for fitness recipes
|
|
4
|
+
*
|
|
5
|
+
* Resolves recipe check selectors (explicit, category, pattern, all)
|
|
6
|
+
* into concrete check slug lists using the check registry.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { SystemError } from '@opensip-tools/core'
|
|
10
|
+
import { minimatch } from 'minimatch'
|
|
11
|
+
|
|
12
|
+
import type { CheckSelector } from './types.js'
|
|
13
|
+
import type { CheckRegistry } from '../framework/registry.js'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Resolve a CheckSelector to a list of check slugs from the registry.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveChecks(selector: CheckSelector, registry: CheckRegistry): readonly string[] {
|
|
20
|
+
const allCheckSlugs = registry.listSlugs()
|
|
21
|
+
|
|
22
|
+
switch (selector.type) {
|
|
23
|
+
case 'explicit': {
|
|
24
|
+
return resolveExplicitSelector(selector.checkIds, allCheckSlugs, registry)
|
|
25
|
+
}
|
|
26
|
+
case 'pattern': {
|
|
27
|
+
return resolvePatternSelector(selector.include, selector.exclude ?? [], allCheckSlugs, registry)
|
|
28
|
+
}
|
|
29
|
+
case 'tags': {
|
|
30
|
+
return resolveTagsSelector(selector.include, selector.exclude ?? [], registry)
|
|
31
|
+
}
|
|
32
|
+
case 'all': {
|
|
33
|
+
return resolveAllSelector(selector.exclude ?? [], allCheckSlugs, registry)
|
|
34
|
+
}
|
|
35
|
+
default: {
|
|
36
|
+
const _exhaustive: never = selector
|
|
37
|
+
throw new SystemError(`Unknown selector type: ${JSON.stringify(_exhaustive)}`, { code: 'SYSTEM.FITNESS.UNKNOWN_SELECTOR' })
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function resolveExplicitSelector(
|
|
43
|
+
checkIds: readonly string[],
|
|
44
|
+
allCheckSlugs: readonly string[],
|
|
45
|
+
registry?: CheckRegistry,
|
|
46
|
+
): readonly string[] {
|
|
47
|
+
const existingIds = new Set(allCheckSlugs)
|
|
48
|
+
const result: string[] = []
|
|
49
|
+
|
|
50
|
+
for (const id of checkIds) {
|
|
51
|
+
// Exact match (works for both namespaced and bare slugs already in registry)
|
|
52
|
+
if (existingIds.has(id)) {
|
|
53
|
+
result.push(id)
|
|
54
|
+
continue
|
|
55
|
+
}
|
|
56
|
+
// Bare slug → try registry resolution (handles namespace lookup)
|
|
57
|
+
if (registry && !id.includes(':')) {
|
|
58
|
+
const check = registry.getBySlug(id)
|
|
59
|
+
if (check) {
|
|
60
|
+
// Find the namespaced key for this check
|
|
61
|
+
const key = allCheckSlugs.find(s => s.endsWith(`:${id}`)) ?? id
|
|
62
|
+
result.push(key)
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return result
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function buildMatchTargets(slug: string, registry?: CheckRegistry): string[] {
|
|
70
|
+
const targets = [slug]
|
|
71
|
+
// Extract bare slug from namespaced key (e.g., 'builtin:no-eval' → 'no-eval')
|
|
72
|
+
const bareSlug = slug.includes(':') ? slug.split(':').pop()! : slug
|
|
73
|
+
if (bareSlug !== slug) targets.push(bareSlug)
|
|
74
|
+
|
|
75
|
+
if (registry) {
|
|
76
|
+
const check = registry.getBySlug(slug)
|
|
77
|
+
if (check?.config.tags) {
|
|
78
|
+
for (const tag of check.config.tags) {
|
|
79
|
+
targets.push(`${tag}/${bareSlug}`)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return targets
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function resolvePatternSelector(
|
|
87
|
+
includePatterns: readonly string[],
|
|
88
|
+
excludePatterns: readonly string[],
|
|
89
|
+
allCheckSlugs: readonly string[],
|
|
90
|
+
registry?: CheckRegistry,
|
|
91
|
+
): readonly string[] {
|
|
92
|
+
return allCheckSlugs.filter((slug) => {
|
|
93
|
+
const matchTargets = buildMatchTargets(slug, registry)
|
|
94
|
+
|
|
95
|
+
const included = includePatterns.some((pattern) =>
|
|
96
|
+
matchTargets.some((target) => minimatch(target, pattern, { nocase: false })),
|
|
97
|
+
)
|
|
98
|
+
if (!included) return false
|
|
99
|
+
|
|
100
|
+
const excluded = excludePatterns.some((pattern) =>
|
|
101
|
+
matchTargets.some((target) => minimatch(target, pattern, { nocase: false })),
|
|
102
|
+
)
|
|
103
|
+
return !excluded
|
|
104
|
+
})
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function resolveTagsSelector(
|
|
108
|
+
includeTags: readonly string[],
|
|
109
|
+
excludeTags: readonly string[],
|
|
110
|
+
registry: CheckRegistry,
|
|
111
|
+
): readonly string[] {
|
|
112
|
+
const includeSet = new Set(includeTags)
|
|
113
|
+
const excludeSet = new Set(excludeTags)
|
|
114
|
+
const allSlugs = registry.listSlugs()
|
|
115
|
+
|
|
116
|
+
return allSlugs.filter((key) => {
|
|
117
|
+
const check = registry.getBySlug(key)
|
|
118
|
+
if (!check) return false
|
|
119
|
+
const tags = check.config.tags ?? []
|
|
120
|
+
const hasInclude = tags.some((tag) => includeSet.has(tag))
|
|
121
|
+
if (!hasInclude) return false
|
|
122
|
+
const hasExclude = tags.some((tag) => excludeSet.has(tag))
|
|
123
|
+
return !hasExclude
|
|
124
|
+
})
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function resolveAllSelector(
|
|
128
|
+
excludePatterns: readonly string[],
|
|
129
|
+
allCheckSlugs: readonly string[],
|
|
130
|
+
registry?: CheckRegistry,
|
|
131
|
+
): readonly string[] {
|
|
132
|
+
if (excludePatterns.length === 0) return allCheckSlugs
|
|
133
|
+
|
|
134
|
+
return allCheckSlugs.filter((slug) => {
|
|
135
|
+
const matchTargets = buildMatchTargets(slug, registry)
|
|
136
|
+
|
|
137
|
+
const excluded = excludePatterns.some((pattern) =>
|
|
138
|
+
matchTargets.some((target) => minimatch(target, pattern, { nocase: false })),
|
|
139
|
+
)
|
|
140
|
+
return !excluded
|
|
141
|
+
})
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** Result of validating check references against the registry */
|
|
145
|
+
interface CheckReferenceValidation {
|
|
146
|
+
valid: string[]
|
|
147
|
+
missing: string[]
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Validate a list of check IDs against known IDs, returning valid and missing sets */
|
|
151
|
+
export function validateCheckReferences(
|
|
152
|
+
checkIds: readonly string[],
|
|
153
|
+
allCheckIds: readonly string[],
|
|
154
|
+
): CheckReferenceValidation {
|
|
155
|
+
const existingSet = new Set(allCheckIds)
|
|
156
|
+
const valid: string[] = []
|
|
157
|
+
const missing: string[] = []
|
|
158
|
+
|
|
159
|
+
for (const id of checkIds) {
|
|
160
|
+
if (existingSet.has(id)) {
|
|
161
|
+
valid.push(id)
|
|
162
|
+
} else {
|
|
163
|
+
missing.push(id)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return { valid, missing }
|
|
168
|
+
}
|
|
169
|
+
|