@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,339 @@
|
|
|
1
|
+
// @fitness-ignore-file zod-schema-strictness -- flexible schema for external data
|
|
2
|
+
// @fitness-ignore-file null-safety -- Zod schema builder chains (z.string().regex(), z.object().passthrough().superRefine().pipe()) always return valid schema objects
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Unified check configuration schema
|
|
5
|
+
*
|
|
6
|
+
* Defines the configuration types for fitness checks with three analysis modes:
|
|
7
|
+
* - analyze: Per-file analysis with content and path
|
|
8
|
+
* - analyzeAll: Multi-file analysis with lazy loading FileAccessor
|
|
9
|
+
* - command: External tool execution with output parsing
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { z } from 'zod'
|
|
13
|
+
|
|
14
|
+
import type { ItemType } from '../types/findings.js'
|
|
15
|
+
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// CHECK SLUGS AND IDS
|
|
18
|
+
// =============================================================================
|
|
19
|
+
|
|
20
|
+
/** Zod schema for validating kebab-case check slugs. */
|
|
21
|
+
const CheckSlugSchema = z
|
|
22
|
+
.string()
|
|
23
|
+
.regex(/^[a-z][a-z0-9-]*(?:-[a-z0-9]+)*$/, 'Check slug must be kebab-case (e.g., no-console-log)')
|
|
24
|
+
|
|
25
|
+
/** Zod schema for validating UUID-format check IDs. */
|
|
26
|
+
const CheckIdSchema = z
|
|
27
|
+
.string()
|
|
28
|
+
.regex(
|
|
29
|
+
/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/,
|
|
30
|
+
'Check ID must be plain UUID format',
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
/** Type alias for a kebab-case check slug string. */
|
|
34
|
+
// eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents intent ("a slug" vs raw string)
|
|
35
|
+
type CheckSlug = string
|
|
36
|
+
|
|
37
|
+
// =============================================================================
|
|
38
|
+
// RESOLVED SCOPE (glob-based file matching)
|
|
39
|
+
// =============================================================================
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Resolved scope with concrete glob patterns for file matching.
|
|
43
|
+
* Produced by resolving a CheckScope against targets configuration.
|
|
44
|
+
*/
|
|
45
|
+
export interface ResolvedScope {
|
|
46
|
+
readonly include: readonly string[]
|
|
47
|
+
readonly exclude: readonly string[]
|
|
48
|
+
readonly description: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// =============================================================================
|
|
52
|
+
// CHECK SCOPE (semantic, marketplace-ready)
|
|
53
|
+
// =============================================================================
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Semantic concern describing what kind of code a check targets.
|
|
57
|
+
* Used for automatic target matching: a check with `concerns: ['backend']`
|
|
58
|
+
* matches any target that declares `concerns: ['backend', ...]`.
|
|
59
|
+
*/
|
|
60
|
+
// eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents the marketplace concern dimension
|
|
61
|
+
export type CheckConcern = string
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Language a check is designed for. Used for automatic target matching:
|
|
65
|
+
* a check with `languages: ['typescript']` matches any target with
|
|
66
|
+
* `languages: ['typescript', ...]`.
|
|
67
|
+
*/
|
|
68
|
+
// eslint-disable-next-line sonarjs/redundant-type-aliases -- semantic alias documents the marketplace language dimension
|
|
69
|
+
export type CheckLanguage = string
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Portable scope declaration for a fitness check.
|
|
73
|
+
*
|
|
74
|
+
* Instead of referencing project-specific target names, checks declare
|
|
75
|
+
* what kind of code they analyze. The platform matches this intent
|
|
76
|
+
* against project targets automatically.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* ```typescript
|
|
80
|
+
* scope: {
|
|
81
|
+
* languages: ['typescript'],
|
|
82
|
+
* concerns: ['backend', 'server'],
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export interface CheckScope {
|
|
87
|
+
/** File type affinity — which languages this check analyzes. */
|
|
88
|
+
readonly languages: readonly CheckLanguage[]
|
|
89
|
+
/** Semantic hints — what kind of code this check targets. */
|
|
90
|
+
readonly concerns: readonly CheckConcern[]
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// =============================================================================
|
|
94
|
+
// CHECK VIOLATION (AUTHOR'S RETURN TYPE)
|
|
95
|
+
// =============================================================================
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Violation returned by check authors.
|
|
99
|
+
* This is the simplified shape - the framework converts it to a Signal.
|
|
100
|
+
*/
|
|
101
|
+
export interface CheckViolation {
|
|
102
|
+
readonly line: number
|
|
103
|
+
readonly column?: number
|
|
104
|
+
readonly message: string
|
|
105
|
+
readonly severity: 'error' | 'warning'
|
|
106
|
+
readonly suggestion?: string
|
|
107
|
+
readonly match?: string
|
|
108
|
+
readonly type?: string
|
|
109
|
+
readonly filePath?: string
|
|
110
|
+
readonly fix?: {
|
|
111
|
+
readonly action: 'replace' | 'insert' | 'delete' | 'refactor' | 'configure' | 'investigate'
|
|
112
|
+
readonly replacement?: string
|
|
113
|
+
readonly confidence: number
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// =============================================================================
|
|
118
|
+
// FILE ACCESSOR (FOR ANALYZE ALL MODE)
|
|
119
|
+
// =============================================================================
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Lazy-loading file accessor for analyzeAll mode.
|
|
123
|
+
*/
|
|
124
|
+
export interface FileAccessor {
|
|
125
|
+
/** List of matched file paths */
|
|
126
|
+
readonly paths: readonly string[]
|
|
127
|
+
/** Read a single file on demand (cached after first read) */
|
|
128
|
+
read(filePath: string): Promise<string>
|
|
129
|
+
/** Read multiple files in batch */
|
|
130
|
+
readMany(filePaths: readonly string[]): Promise<Map<string, string>>
|
|
131
|
+
/** Read all matched files */
|
|
132
|
+
readAll(): Promise<Map<string, string>>
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// =============================================================================
|
|
136
|
+
// COMMAND MODE TYPES
|
|
137
|
+
// =============================================================================
|
|
138
|
+
|
|
139
|
+
/** Configuration for an external command-based check. */
|
|
140
|
+
export interface CommandConfig {
|
|
141
|
+
readonly bin: string
|
|
142
|
+
readonly args: readonly string[] | ((files: readonly string[]) => readonly string[])
|
|
143
|
+
parseOutput(
|
|
144
|
+
stdout: string,
|
|
145
|
+
stderr: string,
|
|
146
|
+
exitCode: number,
|
|
147
|
+
files: readonly string[],
|
|
148
|
+
cwd: string,
|
|
149
|
+
): CheckViolation[]
|
|
150
|
+
readonly expectedExitCodes?: readonly number[]
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const CommandArgsSchema = z.union([z.array(z.string()), z.function()])
|
|
154
|
+
|
|
155
|
+
/** Zod schema for validating command configurations. */
|
|
156
|
+
const CommandConfigSchema = z.object({
|
|
157
|
+
bin: z.string().min(1),
|
|
158
|
+
args: CommandArgsSchema,
|
|
159
|
+
parseOutput: z.function(),
|
|
160
|
+
expectedExitCodes: z.array(z.number().int()).optional(),
|
|
161
|
+
})
|
|
162
|
+
|
|
163
|
+
// =============================================================================
|
|
164
|
+
// ANALYSIS MODE SCHEMAS
|
|
165
|
+
// =============================================================================
|
|
166
|
+
|
|
167
|
+
const AnalyzeModeSchema = z.object({ analyze: z.function() })
|
|
168
|
+
const AnalyzeAllModeSchema = z.object({ analyzeAll: z.function() })
|
|
169
|
+
const CommandModeSchema = z.object({ command: CommandConfigSchema })
|
|
170
|
+
|
|
171
|
+
// =============================================================================
|
|
172
|
+
// BASE CHECK CONFIG
|
|
173
|
+
// =============================================================================
|
|
174
|
+
|
|
175
|
+
/** Common configuration fields shared by all check types. */
|
|
176
|
+
interface BaseCheckConfig {
|
|
177
|
+
readonly id: string
|
|
178
|
+
readonly slug: CheckSlug
|
|
179
|
+
readonly description: string
|
|
180
|
+
readonly longDescription?: string
|
|
181
|
+
readonly tags: readonly string[]
|
|
182
|
+
readonly docs?: string
|
|
183
|
+
readonly timeout?: number
|
|
184
|
+
readonly disabled?: boolean
|
|
185
|
+
readonly fileTypes?: readonly string[]
|
|
186
|
+
/** Signal provider name for external tool checks (default: 'opensip') */
|
|
187
|
+
readonly provider?: string
|
|
188
|
+
/** The type of items this check validates (default: 'files'). Used for display in results table. */
|
|
189
|
+
readonly itemType?: ItemType
|
|
190
|
+
/** Portable scope declaration for marketplace-ready target matching. */
|
|
191
|
+
readonly scope?: CheckScope
|
|
192
|
+
/**
|
|
193
|
+
* Content filtering mode for the analyze() function. Names describe
|
|
194
|
+
* what the filter strips so rule authors don't have to guess at intent.
|
|
195
|
+
*
|
|
196
|
+
* - 'raw' (default): Full file content, unchanged. Use for checks that
|
|
197
|
+
* need to analyze string content (e.g., hardcoded secrets, PII detection).
|
|
198
|
+
* - 'strip-strings': String literals replaced with whitespace,
|
|
199
|
+
* preserving line/column positions. COMMENTS PRESERVED — use when
|
|
200
|
+
* the check reads comment-based directives like the deprecation
|
|
201
|
+
* marker, the swallow-ok marker, or `// @fitness-ignore-...` (we
|
|
202
|
+
* don't reference those tag names verbatim in this JSDoc to avoid
|
|
203
|
+
* confusing static analyzers).
|
|
204
|
+
* - 'strip-strings-and-comments': BOTH string literals and comments
|
|
205
|
+
* replaced with whitespace, preserving line/column positions. Use
|
|
206
|
+
* for checks that pattern-match identifiers via regex and would
|
|
207
|
+
* false-positive on the same banned phrase appearing in JSDoc /
|
|
208
|
+
* line / block comments documenting the rule itself.
|
|
209
|
+
*
|
|
210
|
+
* The legacy `'code-only'` / `'no-strings-no-comments'` aliases were
|
|
211
|
+
* retained through 0.4.x for backwards-compat and removed in 0.5.0.
|
|
212
|
+
* Migrate any remaining call sites to the strip-* names.
|
|
213
|
+
*/
|
|
214
|
+
readonly contentFilter?: 'raw' | 'strip-strings' | 'strip-strings-and-comments'
|
|
215
|
+
/**
|
|
216
|
+
* Confidence level of this check's findings. Consumers of opensip-tools
|
|
217
|
+
* signals (via --report-to) use this to decide how aggressively to act
|
|
218
|
+
* on findings; this package treats it as pure metadata.
|
|
219
|
+
*
|
|
220
|
+
* - 'high': AST-based or structurally guaranteed no false positives.
|
|
221
|
+
* - 'medium': Regex with context filtering — some false positives expected.
|
|
222
|
+
* - 'low': Naive regex or heuristic — surfaced in reports but easily noisy.
|
|
223
|
+
*
|
|
224
|
+
* Default: 'medium' (applied at runtime, not in schema).
|
|
225
|
+
*/
|
|
226
|
+
readonly confidence?: 'high' | 'medium' | 'low'
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Zod schema for validating check scope declarations.
|
|
231
|
+
*
|
|
232
|
+
* Empty `languages` and empty `concerns` are both valid and mean
|
|
233
|
+
* "matches any". This is how cross-language ("universal") checks
|
|
234
|
+
* declare themselves — see @opensip-tools/checks-universal.
|
|
235
|
+
*
|
|
236
|
+
* findByScope() in TargetRegistry treats empty arrays as match-any
|
|
237
|
+
* already; the schema mirrors that behavior so callers can author
|
|
238
|
+
* universal checks without inventing a wildcard sentinel.
|
|
239
|
+
*/
|
|
240
|
+
const CheckScopeSchema = z.object({
|
|
241
|
+
languages: z.array(z.string()),
|
|
242
|
+
concerns: z.array(z.string()),
|
|
243
|
+
})
|
|
244
|
+
|
|
245
|
+
const BaseCheckConfigSchema = z.object({
|
|
246
|
+
id: CheckIdSchema,
|
|
247
|
+
slug: CheckSlugSchema,
|
|
248
|
+
description: z.string().min(1, 'Description is required'),
|
|
249
|
+
longDescription: z.string().optional(),
|
|
250
|
+
tags: z.array(z.string()).min(1, 'At least one tag is required'),
|
|
251
|
+
docs: z.string().optional(),
|
|
252
|
+
timeout: z.number().positive().optional(),
|
|
253
|
+
disabled: z.boolean().optional(),
|
|
254
|
+
fileTypes: z.array(z.string()).optional(),
|
|
255
|
+
provider: z.string().optional(),
|
|
256
|
+
scope: CheckScopeSchema.optional(),
|
|
257
|
+
contentFilter: z.enum(['raw', 'strip-strings', 'strip-strings-and-comments']).optional(),
|
|
258
|
+
confidence: z.enum(['high', 'medium', 'low']).optional(),
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
// =============================================================================
|
|
262
|
+
// UNIFIED CHECK CONFIG
|
|
263
|
+
// =============================================================================
|
|
264
|
+
|
|
265
|
+
/** Check config with per-file analysis mode. */
|
|
266
|
+
export interface AnalyzeCheckConfig extends BaseCheckConfig {
|
|
267
|
+
analyze(content: string, filePath: string): CheckViolation[]
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Check config with multi-file analysis mode using FileAccessor. */
|
|
271
|
+
export interface AnalyzeAllCheckConfig extends BaseCheckConfig {
|
|
272
|
+
analyzeAll(files: FileAccessor): Promise<CheckViolation[]>
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** Check config with external command execution mode. */
|
|
276
|
+
export interface CommandCheckConfig extends BaseCheckConfig {
|
|
277
|
+
command: CommandConfig
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/** Union of all check configuration types (analyze, analyzeAll, command). */
|
|
281
|
+
export type UnifiedCheckConfig = AnalyzeCheckConfig | AnalyzeAllCheckConfig | CommandCheckConfig
|
|
282
|
+
|
|
283
|
+
// =============================================================================
|
|
284
|
+
// VALIDATION
|
|
285
|
+
// =============================================================================
|
|
286
|
+
|
|
287
|
+
/** Zod schema for validating unified check configurations (exactly one analysis mode required). */
|
|
288
|
+
const UnifiedCheckConfigSchema = z
|
|
289
|
+
.object({})
|
|
290
|
+
.passthrough()
|
|
291
|
+
.superRefine((config, ctx) => {
|
|
292
|
+
const modes = ['analyze' in config, 'analyzeAll' in config, 'command' in config].filter(
|
|
293
|
+
Boolean,
|
|
294
|
+
).length
|
|
295
|
+
|
|
296
|
+
if (modes === 0) {
|
|
297
|
+
ctx.addIssue({
|
|
298
|
+
code: z.ZodIssueCode.custom,
|
|
299
|
+
message: 'Check config must specify an analysis mode: analyze, analyzeAll, or command',
|
|
300
|
+
})
|
|
301
|
+
} else if (modes > 1) {
|
|
302
|
+
ctx.addIssue({
|
|
303
|
+
code: z.ZodIssueCode.custom,
|
|
304
|
+
message: 'Check config must specify exactly one analysis mode (found multiple)',
|
|
305
|
+
})
|
|
306
|
+
}
|
|
307
|
+
})
|
|
308
|
+
.pipe(
|
|
309
|
+
BaseCheckConfigSchema.and(
|
|
310
|
+
z.union([AnalyzeModeSchema, AnalyzeAllModeSchema, CommandModeSchema]),
|
|
311
|
+
),
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
/** Validate and parse a check configuration, throwing on invalid input. */
|
|
315
|
+
export function validateCheckConfig(config: unknown): UnifiedCheckConfig {
|
|
316
|
+
return UnifiedCheckConfigSchema.parse(config) as UnifiedCheckConfig
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/** Type guard for per-file analyze mode checks. */
|
|
320
|
+
export function isAnalyzeConfig(config: UnifiedCheckConfig): config is AnalyzeCheckConfig {
|
|
321
|
+
return 'analyze' in config && typeof config.analyze === 'function'
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/** Type guard for multi-file analyzeAll mode checks. */
|
|
325
|
+
export function isAnalyzeAllConfig(config: UnifiedCheckConfig): config is AnalyzeAllCheckConfig {
|
|
326
|
+
return 'analyzeAll' in config && typeof config.analyzeAll === 'function'
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/** Type guard for external command mode checks. */
|
|
330
|
+
export function isCommandConfig(config: UnifiedCheckConfig): config is CommandCheckConfig {
|
|
331
|
+
return 'command' in config && typeof config.command === 'object'
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
/** Determine which analysis mode a check config uses. */
|
|
335
|
+
export function getAnalysisMode(config: UnifiedCheckConfig): 'analyze' | 'analyzeAll' | 'command' {
|
|
336
|
+
if (isAnalyzeConfig(config)) return 'analyze'
|
|
337
|
+
if (isAnalyzeAllConfig(config)) return 'analyzeAll'
|
|
338
|
+
return 'command'
|
|
339
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Core type definitions for fitness checks
|
|
3
|
+
*
|
|
4
|
+
* Check interface is the return type of defineCheck.
|
|
5
|
+
* CheckConfig represents the internal configuration structure.
|
|
6
|
+
* CheckResult carries Signal[].
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
import type { CheckScope, ResolvedScope } from './check-config.js'
|
|
11
|
+
import type { ExecutionContext, RunOptions } from './execution-context.js'
|
|
12
|
+
import type { PathMatcher } from './path-matcher.js'
|
|
13
|
+
import type { CheckResult, ItemType } from '../types/findings.js'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Check configuration options.
|
|
19
|
+
*/
|
|
20
|
+
export interface CheckConfig {
|
|
21
|
+
readonly id: string
|
|
22
|
+
readonly slug: string
|
|
23
|
+
readonly tags: readonly string[]
|
|
24
|
+
readonly description: string
|
|
25
|
+
readonly longDescription?: string | undefined
|
|
26
|
+
readonly analysisMode: 'analyze' | 'analyzeAll' | 'command'
|
|
27
|
+
readonly scope: ResolvedScope
|
|
28
|
+
readonly itemType: ItemType
|
|
29
|
+
readonly unit?: string | undefined
|
|
30
|
+
readonly additionalExcludes?: readonly string[] | undefined
|
|
31
|
+
readonly docs?: string | undefined
|
|
32
|
+
readonly disabled?: boolean | undefined
|
|
33
|
+
readonly confidence?: 'high' | 'medium' | 'low' | undefined
|
|
34
|
+
readonly timeout?: number | undefined
|
|
35
|
+
readonly scansFiles?: boolean | undefined
|
|
36
|
+
readonly fileTypes?: readonly string[] | undefined
|
|
37
|
+
/** Portable scope declaration for marketplace-ready target matching. */
|
|
38
|
+
readonly checkScope?: CheckScope | undefined
|
|
39
|
+
readonly execute: (ctx: ExecutionContext) => Promise<CheckResult>
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A defined check, ready to run.
|
|
44
|
+
*/
|
|
45
|
+
export interface Check {
|
|
46
|
+
readonly config: CheckConfig
|
|
47
|
+
readonly run: (cwd: string, options?: RunOptions) => Promise<CheckResult>
|
|
48
|
+
readonly getScope: () => ResolvedScope
|
|
49
|
+
readonly getMatcher: (cwd: string) => PathMatcher
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Type guard: is this value a Check object?
|
|
54
|
+
*
|
|
55
|
+
* Checks for the shape of a Check object:
|
|
56
|
+
* - Has a `config` property that is an object
|
|
57
|
+
* - config has an `id` property that is a string
|
|
58
|
+
* - config has a `slug` property that is a string
|
|
59
|
+
* - config has an `execute` property that is a function
|
|
60
|
+
* - Has a `run` property that is a function
|
|
61
|
+
*/
|
|
62
|
+
export function isCheck(value: unknown): value is Check {
|
|
63
|
+
if (value === null || typeof value !== 'object') return false
|
|
64
|
+
|
|
65
|
+
const obj = value as Record<string, unknown>
|
|
66
|
+
if (!obj.config || typeof obj.config !== 'object') return false
|
|
67
|
+
|
|
68
|
+
const config = obj.config as Record<string, unknown>
|
|
69
|
+
if (typeof config.id !== 'string') return false
|
|
70
|
+
if (typeof config.slug !== 'string') return false
|
|
71
|
+
if (typeof config.execute !== 'function') return false
|
|
72
|
+
if (typeof obj.run !== 'function') return false
|
|
73
|
+
|
|
74
|
+
return true
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export {type ResolvedScope} from './check-config.js'
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Command executor for external tool checks
|
|
3
|
+
*
|
|
4
|
+
* Executes external commands (eslint, prettier, etc.) with abort
|
|
5
|
+
* and timeout support, then parses output into violations.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execAbortable, type AbortableExecOptions } from './abortable-exec.js'
|
|
9
|
+
|
|
10
|
+
import type { CheckViolation, CommandConfig } from './check-config.js'
|
|
11
|
+
|
|
12
|
+
// =============================================================================
|
|
13
|
+
// TYPES
|
|
14
|
+
// =============================================================================
|
|
15
|
+
|
|
16
|
+
/** Options for executing an external command. */
|
|
17
|
+
export interface CommandExecutorOptions {
|
|
18
|
+
readonly cwd: string
|
|
19
|
+
readonly signal?: AbortSignal | undefined
|
|
20
|
+
readonly timeout?: number | undefined
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Result of executing an external command, including parsed violations. */
|
|
24
|
+
export interface CommandExecutionResult {
|
|
25
|
+
readonly violations: CheckViolation[]
|
|
26
|
+
readonly aborted: boolean
|
|
27
|
+
readonly exitCode: number | null
|
|
28
|
+
readonly error?: string
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// =============================================================================
|
|
32
|
+
// EXECUTOR
|
|
33
|
+
// =============================================================================
|
|
34
|
+
|
|
35
|
+
const DEFAULT_EXPECTED_EXIT_CODES: readonly number[] = [0, 1]
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Execute an external command and parse its output into violations.
|
|
39
|
+
*/
|
|
40
|
+
export async function executeCommand(
|
|
41
|
+
config: CommandConfig,
|
|
42
|
+
files: readonly string[],
|
|
43
|
+
options: CommandExecutorOptions,
|
|
44
|
+
): Promise<CommandExecutionResult> {
|
|
45
|
+
const { cwd, signal, timeout } = options
|
|
46
|
+
|
|
47
|
+
const args = typeof config.args === 'function' ? config.args(files) : config.args
|
|
48
|
+
const command = [config.bin, ...args]
|
|
49
|
+
|
|
50
|
+
const execOptions: AbortableExecOptions = { cwd, signal, timeout }
|
|
51
|
+
|
|
52
|
+
let result: Awaited<ReturnType<typeof execAbortable>>
|
|
53
|
+
try {
|
|
54
|
+
result = await execAbortable(command, execOptions)
|
|
55
|
+
} catch (error) {
|
|
56
|
+
// ENOENT = tool not installed (spawn fails before the process starts)
|
|
57
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
58
|
+
if (message.includes('ENOENT') || message.includes('not found')) {
|
|
59
|
+
return {
|
|
60
|
+
violations: [],
|
|
61
|
+
aborted: false,
|
|
62
|
+
exitCode: null,
|
|
63
|
+
error: `${config.bin} is not installed. Install it to enable this check.`,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
throw error
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (result.aborted) {
|
|
70
|
+
return { violations: [], aborted: true, exitCode: result.exitCode }
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Exit code 127 = command not found (shell mode)
|
|
74
|
+
if (result.exitCode === 127) {
|
|
75
|
+
return {
|
|
76
|
+
violations: [],
|
|
77
|
+
aborted: false,
|
|
78
|
+
exitCode: 127,
|
|
79
|
+
error: `${config.bin} is not installed. Install it to enable this check.`,
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const expectedCodes = config.expectedExitCodes ?? DEFAULT_EXPECTED_EXIT_CODES
|
|
84
|
+
if (result.exitCode !== null && !expectedCodes.includes(result.exitCode)) {
|
|
85
|
+
return {
|
|
86
|
+
violations: [],
|
|
87
|
+
aborted: false,
|
|
88
|
+
exitCode: result.exitCode,
|
|
89
|
+
error:
|
|
90
|
+
`Command exited with unexpected code ${result.exitCode}. ` +
|
|
91
|
+
`Expected one of: ${expectedCodes.join(', ')}. ` +
|
|
92
|
+
`stderr: ${result.stderr.slice(0, 500)}${result.stderr.length > 500 ? ' [truncated]' : ''}`,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const violations = config.parseOutput(result.stdout, result.stderr, result.exitCode ?? 0, files, cwd)
|
|
97
|
+
|
|
98
|
+
return { violations, aborted: false, exitCode: result.exitCode }
|
|
99
|
+
}
|
|
100
|
+
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// @fitness-ignore-file project-readme-existence -- internal module, not a package root
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Shared constants for the fitness framework
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Standard exclusion patterns for file matching across the framework.
|
|
8
|
+
* Used by execution context, directive inventory, and file cache.
|
|
9
|
+
*/
|
|
10
|
+
export const DEFAULT_EXCLUSION_PATTERNS = [
|
|
11
|
+
'**/node_modules/**',
|
|
12
|
+
'**/dist/**',
|
|
13
|
+
'**/.git/**',
|
|
14
|
+
'**/coverage/**',
|
|
15
|
+
'**/*.tsbuildinfo',
|
|
16
|
+
] as const
|