@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,122 @@
|
|
|
1
|
+
// @fitness-ignore-file concurrency-safety -- single-threaded execution context
|
|
2
|
+
// @fitness-ignore-file error-handling-suite -- catch blocks delegate errors through established patterns
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Execution context creation for fitness checks
|
|
5
|
+
*
|
|
6
|
+
* Provides the runtime context available to check execute functions,
|
|
7
|
+
* including file access, pattern matching, and abort support.
|
|
8
|
+
*/
|
|
9
|
+
import * as fs from 'node:fs/promises';
|
|
10
|
+
import { relative } from 'node:path';
|
|
11
|
+
import { SystemError } from '@opensip-tools/core';
|
|
12
|
+
import { Minimatch } from 'minimatch';
|
|
13
|
+
import { DEFAULT_EXCLUSION_PATTERNS } from './constants.js';
|
|
14
|
+
import { fileCache } from './file-cache.js';
|
|
15
|
+
import { PathMatcher } from './path-matcher.js';
|
|
16
|
+
import { extractSnippet } from './result-builder.js';
|
|
17
|
+
/**
|
|
18
|
+
* Error thrown when a check is aborted via AbortSignal.
|
|
19
|
+
*/
|
|
20
|
+
export class CheckAbortedError extends SystemError {
|
|
21
|
+
name = 'CheckAbortedError';
|
|
22
|
+
checkId;
|
|
23
|
+
constructor(checkId, message) {
|
|
24
|
+
super(message ?? `Check ${checkId} was aborted`, { code: 'SYSTEM.FITNESS.CHECK_ABORTED' });
|
|
25
|
+
this.checkId = checkId;
|
|
26
|
+
Object.setPrototypeOf(this, CheckAbortedError.prototype);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Creates the matchFiles function for the execution context.
|
|
31
|
+
*
|
|
32
|
+
* `globalExcludes` come from the project config's top-level
|
|
33
|
+
* `globalExcludes` array. They are applied ONLY to the fileCache
|
|
34
|
+
* fallback path — the path taken by scope-empty checks. Custom
|
|
35
|
+
* `patterns` arguments are honored as-is (the caller knows what they
|
|
36
|
+
* want), and `targetFiles` from per-check overrides are pre-filtered
|
|
37
|
+
* by `preResolveAllTargets`. Pre-compiled to Minimatch matchers so
|
|
38
|
+
* we don't pay regex compilation per filter call.
|
|
39
|
+
*/
|
|
40
|
+
function createMatchFilesFunction(cwd, matcher, targetFiles, globalExcludes) {
|
|
41
|
+
const compiledGlobalExcludes = globalExcludes && globalExcludes.length > 0
|
|
42
|
+
? globalExcludes.map((pattern) => new Minimatch(pattern, { dot: true }))
|
|
43
|
+
: undefined;
|
|
44
|
+
const applyGlobalExcludes = (files) => {
|
|
45
|
+
if (!compiledGlobalExcludes)
|
|
46
|
+
return files;
|
|
47
|
+
return files.filter((filePath) => {
|
|
48
|
+
const rel = relative(cwd, filePath);
|
|
49
|
+
return !compiledGlobalExcludes.some((m) => m.match(rel));
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
return async (patterns, options) => {
|
|
53
|
+
if (patterns && patterns.length > 0) {
|
|
54
|
+
const customMatcher = PathMatcher.create({
|
|
55
|
+
cwd,
|
|
56
|
+
include: [...patterns],
|
|
57
|
+
exclude: [...(options?.ignore ?? []), ...DEFAULT_EXCLUSION_PATTERNS],
|
|
58
|
+
});
|
|
59
|
+
return customMatcher.files();
|
|
60
|
+
}
|
|
61
|
+
// Per-check target files take priority over cache.
|
|
62
|
+
// These are already filtered by globalExcludes during target
|
|
63
|
+
// pre-resolution (scope-resolver.ts), so don't re-filter.
|
|
64
|
+
if (targetFiles) {
|
|
65
|
+
return targetFiles;
|
|
66
|
+
}
|
|
67
|
+
// When the matcher has no include patterns (checks without targets),
|
|
68
|
+
// fall back to the prewarmed file cache paths. The cache itself
|
|
69
|
+
// honors no exclusion config — that's the layer where globalExcludes
|
|
70
|
+
// must be applied, otherwise scope-empty checks scan every prewarmed
|
|
71
|
+
// file regardless of project intent.
|
|
72
|
+
if (matcher.includePatterns.length === 0) {
|
|
73
|
+
return applyGlobalExcludes(fileCache.paths());
|
|
74
|
+
}
|
|
75
|
+
return matcher.files();
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Creates the execution context for a check.
|
|
80
|
+
*/
|
|
81
|
+
export function createExecutionContext(config, cwd, matcher, options) {
|
|
82
|
+
return {
|
|
83
|
+
cwd,
|
|
84
|
+
checkId: config.id,
|
|
85
|
+
checkSlug: config.slug,
|
|
86
|
+
verbose: options?.verbose ?? false,
|
|
87
|
+
// @fitness-ignore-next-line unbounded-memory -- size validation via fs.stat() is on the next line; false positive on method name
|
|
88
|
+
/** @throws {SystemError} When the file exceeds 10MB */
|
|
89
|
+
async readFile(filePath) {
|
|
90
|
+
const fileStats = await fs.stat(filePath);
|
|
91
|
+
if (fileStats.size > 10_000_000) {
|
|
92
|
+
throw new SystemError(`File too large (${fileStats.size} bytes, max 10MB): ${filePath}`, { code: 'SYSTEM.FITNESS.FILE_TOO_LARGE' });
|
|
93
|
+
}
|
|
94
|
+
return fileCache.get(filePath);
|
|
95
|
+
},
|
|
96
|
+
fileExists(filePath) {
|
|
97
|
+
return fileCache.exists(filePath);
|
|
98
|
+
},
|
|
99
|
+
matchFiles: createMatchFilesFunction(cwd, matcher, options?.targetFiles, options?.globalExcludes),
|
|
100
|
+
getMatcher() {
|
|
101
|
+
return matcher;
|
|
102
|
+
},
|
|
103
|
+
log(message) {
|
|
104
|
+
if (options?.verbose) {
|
|
105
|
+
// @fitness-ignore-next-line no-console-log -- Verbose check-level debug output bypasses structured logger for immediate CLI feedback
|
|
106
|
+
// @fitness-ignore-next-line logging-standards -- Verbose check-level debug output bypasses structured logger for immediate CLI feedback
|
|
107
|
+
console.log(`[${config.slug}] ${message}`);
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
extractSnippet(content, line, contextLines = 2) {
|
|
111
|
+
return extractSnippet(content, line, contextLines);
|
|
112
|
+
},
|
|
113
|
+
...(options?.signal ? { signal: options.signal } : {}),
|
|
114
|
+
/** @throws {CheckAbortedError} When the check has been aborted */
|
|
115
|
+
checkAborted() {
|
|
116
|
+
if (options?.signal?.aborted) {
|
|
117
|
+
throw new CheckAbortedError(config.slug);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=execution-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-context.js","sourceRoot":"","sources":["../../src/framework/execution-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview FileAccessor implementation for lazy file loading
|
|
3
|
+
*
|
|
4
|
+
* Provides lazy-loading file access with LRU caching for
|
|
5
|
+
* analyzeAll mode checks that need to correlate across files.
|
|
6
|
+
*/
|
|
7
|
+
import type { FileAccessor } from './check-config.js';
|
|
8
|
+
/** Options for creating a FileAccessor instance. */
|
|
9
|
+
export interface FileAccessorOptions {
|
|
10
|
+
readonly cacheCapacity?: number;
|
|
11
|
+
readonly signal?: AbortSignal;
|
|
12
|
+
/**
|
|
13
|
+
* Content filtering applied before returning file content. See
|
|
14
|
+
* BaseCheckConfig.contentFilter for the canonical doc.
|
|
15
|
+
*/
|
|
16
|
+
readonly contentFilter?: 'raw' | 'strip-strings' | 'strip-strings-and-comments';
|
|
17
|
+
}
|
|
18
|
+
/** Create a FileAccessor for lazy-loading files with LRU caching. */
|
|
19
|
+
export declare function createFileAccessor(filePaths: readonly string[], options?: FileAccessorOptions): FileAccessor;
|
|
20
|
+
//# sourceMappingURL=file-accessor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-accessor.d.ts","sourceRoot":"","sources":["../../src/framework/file-accessor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAkDrD,oDAAoD;AACpD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,KAAK,GAAG,eAAe,GAAG,4BAA4B,CAAA;CAChF;AA0FD,qEAAqE;AAErE,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,MAAM,EAAE,EAC5B,OAAO,GAAE,mBAAwB,GAChC,YAAY,CAEd"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview FileAccessor implementation for lazy file loading
|
|
3
|
+
*
|
|
4
|
+
* Provides lazy-loading file access with LRU caching for
|
|
5
|
+
* analyzeAll mode checks that need to correlate across files.
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from 'node:fs/promises';
|
|
8
|
+
import { ValidationError, applyContentFilter } from '@opensip-tools/core';
|
|
9
|
+
import { fileCache } from './file-cache.js';
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// LRU CACHE
|
|
12
|
+
// =============================================================================
|
|
13
|
+
class LRUCache {
|
|
14
|
+
cache;
|
|
15
|
+
capacity;
|
|
16
|
+
constructor(capacity) {
|
|
17
|
+
this.cache = new Map();
|
|
18
|
+
this.capacity = capacity;
|
|
19
|
+
}
|
|
20
|
+
get(key) {
|
|
21
|
+
// in-memory: single-threaded Node.js access pattern
|
|
22
|
+
const value = this.cache.get(key);
|
|
23
|
+
if (value !== undefined) {
|
|
24
|
+
this.cache.delete(key);
|
|
25
|
+
this.cache.set(key, value);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
set(key, value) {
|
|
30
|
+
if (this.cache.has(key)) {
|
|
31
|
+
this.cache.delete(key);
|
|
32
|
+
}
|
|
33
|
+
else if (this.cache.size >= this.capacity) {
|
|
34
|
+
const firstKey = this.cache.keys().next().value;
|
|
35
|
+
if (firstKey !== undefined) {
|
|
36
|
+
this.cache.delete(firstKey);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
this.cache.set(key, value);
|
|
40
|
+
}
|
|
41
|
+
get size() {
|
|
42
|
+
return this.cache.size;
|
|
43
|
+
}
|
|
44
|
+
clear() {
|
|
45
|
+
this.cache.clear();
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const DEFAULT_CACHE_CAPACITY = 100;
|
|
49
|
+
/** FileAccessor implementation with LRU caching and abort signal support. */
|
|
50
|
+
class FileAccessorImpl {
|
|
51
|
+
paths;
|
|
52
|
+
cache;
|
|
53
|
+
pathSet;
|
|
54
|
+
signal;
|
|
55
|
+
contentFilterMode;
|
|
56
|
+
constructor(filePaths, options = {}) {
|
|
57
|
+
this.paths = filePaths;
|
|
58
|
+
this.pathSet = new Set(filePaths);
|
|
59
|
+
this.cache = new LRUCache(options.cacheCapacity ?? DEFAULT_CACHE_CAPACITY);
|
|
60
|
+
this.signal = options.signal;
|
|
61
|
+
this.contentFilterMode = options.contentFilter;
|
|
62
|
+
}
|
|
63
|
+
async read(filePath) {
|
|
64
|
+
// in-memory: single-threaded Node.js access pattern
|
|
65
|
+
// @fitness-ignore-next-line detached-promises -- throwIfAborted() is synchronous, optional chaining is not a detached promise
|
|
66
|
+
this.signal?.throwIfAborted();
|
|
67
|
+
if (!this.pathSet.has(filePath)) {
|
|
68
|
+
// @fitness-ignore-next-line result-pattern-consistency -- internal method, exceptions propagate to public Result boundary
|
|
69
|
+
throw new ValidationError(`File path not in matched set: ${filePath}. ` +
|
|
70
|
+
`Only paths from the 'paths' property can be read.`, { code: 'VALIDATION.FITNESS.PATH_NOT_IN_SET' });
|
|
71
|
+
}
|
|
72
|
+
const cached = this.cache.get(filePath);
|
|
73
|
+
if (cached !== undefined) {
|
|
74
|
+
return cached;
|
|
75
|
+
}
|
|
76
|
+
// Try global file cache first (populated by prewarm or previous checks)
|
|
77
|
+
let content = fileCache.getCached(filePath);
|
|
78
|
+
if (content === undefined) {
|
|
79
|
+
const fileStats = await fs.stat(filePath);
|
|
80
|
+
if (fileStats.size > 10_000_000) {
|
|
81
|
+
// @fitness-ignore-next-line result-pattern-consistency -- infrastructure boundary guard, not domain logic
|
|
82
|
+
throw new ValidationError(`File too large (${fileStats.size} bytes, max 10MB): ${filePath}`, { code: 'VALIDATION.FITNESS.FILE_TOO_LARGE' });
|
|
83
|
+
}
|
|
84
|
+
content = await fs.readFile(filePath, 'utf8');
|
|
85
|
+
}
|
|
86
|
+
// Dispatch through the LanguageAdapter for the file's extension.
|
|
87
|
+
// See languages/content-filter-dispatch.ts.
|
|
88
|
+
content = applyContentFilter(filePath, content, this.contentFilterMode ?? 'none');
|
|
89
|
+
this.cache.set(filePath, content);
|
|
90
|
+
return content;
|
|
91
|
+
}
|
|
92
|
+
async readMany(filePaths) {
|
|
93
|
+
// in-memory: single-threaded Node.js access pattern
|
|
94
|
+
const results = new Map();
|
|
95
|
+
// @fitness-ignore-next-line no-unbounded-concurrency -- bounded by FileAccessor path set; LRU cache limits memory
|
|
96
|
+
const entries = await Promise.all(filePaths.map(async (filePath) => {
|
|
97
|
+
const content = await this.read(filePath);
|
|
98
|
+
return [filePath, content];
|
|
99
|
+
}));
|
|
100
|
+
for (const [filePath, content] of entries) {
|
|
101
|
+
results.set(filePath, content);
|
|
102
|
+
}
|
|
103
|
+
return results;
|
|
104
|
+
}
|
|
105
|
+
async readAll() {
|
|
106
|
+
return this.readMany(this.paths);
|
|
107
|
+
}
|
|
108
|
+
/** Number of files currently held in the LRU cache. */
|
|
109
|
+
get cachedCount() {
|
|
110
|
+
return this.cache.size;
|
|
111
|
+
}
|
|
112
|
+
/** Evict all entries from the file cache. */
|
|
113
|
+
clearCache() {
|
|
114
|
+
this.cache.clear();
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/** Create a FileAccessor for lazy-loading files with LRU caching. */
|
|
118
|
+
// @fitness-ignore-next-line result-pattern-consistency -- factory function, cannot fail in domain-meaningful ways
|
|
119
|
+
export function createFileAccessor(filePaths, options = {}) {
|
|
120
|
+
return new FileAccessorImpl(filePaths, options);
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=file-accessor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-accessor.js","sourceRoot":"","sources":["../../src/framework/file-accessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview In-memory file cache for fitness checks
|
|
3
|
+
*
|
|
4
|
+
* Simple file content cache with optional prewarming.
|
|
5
|
+
* Used by all checks during a run for efficient file access.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Prewarm statistics.
|
|
9
|
+
*/
|
|
10
|
+
interface PrewarmStats {
|
|
11
|
+
/** Number of files loaded */
|
|
12
|
+
readonly filesLoaded: number;
|
|
13
|
+
/** Duration in milliseconds */
|
|
14
|
+
readonly durationMs: number;
|
|
15
|
+
/** Total bytes loaded */
|
|
16
|
+
readonly totalBytes: number;
|
|
17
|
+
}
|
|
18
|
+
declare class FileCache {
|
|
19
|
+
private readonly cache;
|
|
20
|
+
private _prewarmed;
|
|
21
|
+
private _cleared;
|
|
22
|
+
private _autoClearTimer;
|
|
23
|
+
/**
|
|
24
|
+
* Prewarm the cache by loading all files matching patterns.
|
|
25
|
+
* @param cwd - Working directory for file resolution
|
|
26
|
+
* @param patterns - Glob patterns to prewarm file contents for
|
|
27
|
+
* @returns Prewarm statistics
|
|
28
|
+
*/
|
|
29
|
+
prewarm(cwd: string, patterns: readonly string[]): Promise<PrewarmStats>;
|
|
30
|
+
/**
|
|
31
|
+
* Get file content from cache, falling back to disk if not cached.
|
|
32
|
+
* @throws {Error} If the path is a directory instead of a file
|
|
33
|
+
*/
|
|
34
|
+
/** Synchronously check if a file is in cache. Returns content or undefined. */
|
|
35
|
+
getCached(filePath: string): string | undefined;
|
|
36
|
+
get(filePath: string): Promise<string>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a file exists (in cache or on disk).
|
|
39
|
+
*/
|
|
40
|
+
exists(filePath: string): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* Clear the cache. Must be called after checks complete.
|
|
43
|
+
*/
|
|
44
|
+
clear(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Get all cached file paths.
|
|
47
|
+
* Returns the paths of all files loaded during prewarm or on-demand reads.
|
|
48
|
+
*/
|
|
49
|
+
paths(): readonly string[];
|
|
50
|
+
/**
|
|
51
|
+
* Get cache statistics.
|
|
52
|
+
*/
|
|
53
|
+
/** Auto-clear after timeout to prevent memory leaks from missed lifecycle cleanup */
|
|
54
|
+
private scheduleAutoClear;
|
|
55
|
+
get stats(): {
|
|
56
|
+
size: number;
|
|
57
|
+
prewarmed: boolean;
|
|
58
|
+
cleared: boolean;
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Shared file cache instance.
|
|
63
|
+
*/
|
|
64
|
+
export declare const fileCache: FileCache;
|
|
65
|
+
/**
|
|
66
|
+
* Default patterns to prewarm for fitness checks.
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEFAULT_PREWARM_PATTERNS: readonly ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.json", "**/*.md"];
|
|
69
|
+
export {};
|
|
70
|
+
//# sourceMappingURL=file-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache.d.ts","sourceRoot":"","sources":["../../src/framework/file-cache.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AAQH;;GAEG;AACH,UAAU,YAAY;IACpB,6BAA6B;IAC7B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,yBAAyB;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAYD,cAAM,SAAS;IACb,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA4B;IAClD,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,eAAe,CAA6C;IAEpE;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IAwD9E;;;OAGG;IACH,+EAA+E;IAC/E,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAKzC,GAAG,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB5C;;OAEG;IACG,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBhD;;OAEG;IACH,KAAK,IAAI,IAAI;IAUb;;;OAGG;IACH,KAAK,IAAI,SAAS,MAAM,EAAE;IAI1B;;OAEG;IACH,qFAAqF;IACrF,OAAO,CAAC,iBAAiB;IAazB,IAAI,KAAK,IAAI;QACX,IAAI,EAAE,MAAM,CAAA;QACZ,SAAS,EAAE,OAAO,CAAA;QAClB,OAAO,EAAE,OAAO,CAAA;KACjB,CAMA;CACF;AAED;;GAEG;AACH,eAAO,MAAM,SAAS,WAAkB,CAAA;AAExC;;GAEG;AACH,eAAO,MAAM,wBAAwB,iFAO3B,CAAA"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// @fitness-ignore-file public-api-jsdoc -- internal framework module; public API documented at package level
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview In-memory file cache for fitness checks
|
|
4
|
+
*
|
|
5
|
+
* Simple file content cache with optional prewarming.
|
|
6
|
+
* Used by all checks during a run for efficient file access.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'node:fs/promises';
|
|
9
|
+
import * as path from 'node:path';
|
|
10
|
+
import { ValidationError } from '@opensip-tools/core';
|
|
11
|
+
import { glob } from 'glob';
|
|
12
|
+
/**
|
|
13
|
+
* Simple in-memory file cache.
|
|
14
|
+
*
|
|
15
|
+
* Usage:
|
|
16
|
+
* 1. Call prewarm() before running checks (loads file contents)
|
|
17
|
+
* 2. Use get() to read file contents (falls back to disk if not cached)
|
|
18
|
+
* 3. Call clear() after checks complete
|
|
19
|
+
*/
|
|
20
|
+
const PREWARM_BATCH_SIZE = 100;
|
|
21
|
+
class FileCache {
|
|
22
|
+
cache = new Map();
|
|
23
|
+
_prewarmed = false;
|
|
24
|
+
_cleared = false;
|
|
25
|
+
_autoClearTimer = null;
|
|
26
|
+
/**
|
|
27
|
+
* Prewarm the cache by loading all files matching patterns.
|
|
28
|
+
* @param cwd - Working directory for file resolution
|
|
29
|
+
* @param patterns - Glob patterns to prewarm file contents for
|
|
30
|
+
* @returns Prewarm statistics
|
|
31
|
+
*/
|
|
32
|
+
async prewarm(cwd, patterns) {
|
|
33
|
+
const start = Date.now();
|
|
34
|
+
let totalBytes = 0;
|
|
35
|
+
// Find all matching files for content caching
|
|
36
|
+
const allFiles = new Set();
|
|
37
|
+
for (const pattern of patterns) {
|
|
38
|
+
// @fitness-ignore-next-line performance-anti-patterns -- sequential glob calls: each pattern must resolve before deduplication
|
|
39
|
+
const files = await glob(pattern, {
|
|
40
|
+
cwd,
|
|
41
|
+
absolute: true,
|
|
42
|
+
nodir: true,
|
|
43
|
+
ignore: ['**/node_modules/**', '**/dist/**', '**/.git/**'],
|
|
44
|
+
});
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
allFiles.add(file);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Load file contents in parallel batches
|
|
50
|
+
const files = [...allFiles];
|
|
51
|
+
for (let i = 0; i < files.length; i += PREWARM_BATCH_SIZE) {
|
|
52
|
+
const batch = files.slice(i, i + PREWARM_BATCH_SIZE);
|
|
53
|
+
// @fitness-ignore-next-line performance-anti-patterns -- intentional batching: limits concurrent file reads to control memory pressure
|
|
54
|
+
const results = await Promise.allSettled(batch.map(async (filePath) => {
|
|
55
|
+
const stats = await fs.stat(filePath);
|
|
56
|
+
if (stats.isDirectory()) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const content = await fs.readFile(filePath, 'utf8');
|
|
60
|
+
return { filePath, content };
|
|
61
|
+
}));
|
|
62
|
+
for (const result of results) {
|
|
63
|
+
if (result.status === 'fulfilled' && result.value !== null) {
|
|
64
|
+
this.cache.set(result.value.filePath, result.value.content);
|
|
65
|
+
totalBytes += result.value.content.length;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
this._prewarmed = true;
|
|
70
|
+
this._cleared = false;
|
|
71
|
+
this.scheduleAutoClear();
|
|
72
|
+
const durationMs = Date.now() - start;
|
|
73
|
+
return {
|
|
74
|
+
filesLoaded: this.cache.size,
|
|
75
|
+
durationMs,
|
|
76
|
+
totalBytes,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Get file content from cache, falling back to disk if not cached.
|
|
81
|
+
* @throws {Error} If the path is a directory instead of a file
|
|
82
|
+
*/
|
|
83
|
+
/** Synchronously check if a file is in cache. Returns content or undefined. */
|
|
84
|
+
getCached(filePath) {
|
|
85
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
86
|
+
return this.cache.get(absolutePath);
|
|
87
|
+
}
|
|
88
|
+
async get(filePath) {
|
|
89
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
90
|
+
const cached = this.cache.get(absolutePath);
|
|
91
|
+
if (cached !== undefined) {
|
|
92
|
+
return cached;
|
|
93
|
+
}
|
|
94
|
+
const stats = await fs.stat(absolutePath);
|
|
95
|
+
if (stats.isDirectory()) {
|
|
96
|
+
// @fitness-ignore-next-line result-pattern-consistency -- internal method, exceptions propagate to public Result boundary
|
|
97
|
+
throw new ValidationError(`Cannot read directory as file: ${absolutePath}`, { code: 'VALIDATION.FITNESS.DIRECTORY_AS_FILE' });
|
|
98
|
+
}
|
|
99
|
+
const content = await fs.readFile(absolutePath, 'utf8');
|
|
100
|
+
this.cache.set(absolutePath, content);
|
|
101
|
+
return content;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Check if a file exists (in cache or on disk).
|
|
105
|
+
*/
|
|
106
|
+
async exists(filePath) {
|
|
107
|
+
const absolutePath = path.isAbsolute(filePath) ? filePath : path.resolve(filePath);
|
|
108
|
+
if (this.cache.has(absolutePath)) {
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
await fs.access(absolutePath);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
// @swallow-ok File access check failed — treat as not accessible
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clear the cache. Must be called after checks complete.
|
|
122
|
+
*/
|
|
123
|
+
clear() {
|
|
124
|
+
this.cache.clear();
|
|
125
|
+
this._prewarmed = false;
|
|
126
|
+
this._cleared = true;
|
|
127
|
+
if (this._autoClearTimer) {
|
|
128
|
+
clearTimeout(this._autoClearTimer);
|
|
129
|
+
this._autoClearTimer = null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get all cached file paths.
|
|
134
|
+
* Returns the paths of all files loaded during prewarm or on-demand reads.
|
|
135
|
+
*/
|
|
136
|
+
paths() {
|
|
137
|
+
return [...this.cache.keys()].sort();
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Get cache statistics.
|
|
141
|
+
*/
|
|
142
|
+
/** Auto-clear after timeout to prevent memory leaks from missed lifecycle cleanup */
|
|
143
|
+
scheduleAutoClear() {
|
|
144
|
+
if (this._autoClearTimer) {
|
|
145
|
+
clearTimeout(this._autoClearTimer);
|
|
146
|
+
}
|
|
147
|
+
this._autoClearTimer = setTimeout(() => {
|
|
148
|
+
if (this.cache.size > 0) {
|
|
149
|
+
this.clear();
|
|
150
|
+
}
|
|
151
|
+
}, 10 * 60 * 1000); // 10 minutes
|
|
152
|
+
// Unref so the timer doesn't keep the process alive
|
|
153
|
+
this._autoClearTimer.unref();
|
|
154
|
+
}
|
|
155
|
+
get stats() {
|
|
156
|
+
return {
|
|
157
|
+
size: this.cache.size,
|
|
158
|
+
prewarmed: this._prewarmed,
|
|
159
|
+
cleared: this._cleared,
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Shared file cache instance.
|
|
165
|
+
*/
|
|
166
|
+
export const fileCache = new FileCache();
|
|
167
|
+
/**
|
|
168
|
+
* Default patterns to prewarm for fitness checks.
|
|
169
|
+
*/
|
|
170
|
+
export const DEFAULT_PREWARM_PATTERNS = [
|
|
171
|
+
'**/*.ts',
|
|
172
|
+
'**/*.tsx',
|
|
173
|
+
'**/*.js',
|
|
174
|
+
'**/*.jsx',
|
|
175
|
+
'**/*.json',
|
|
176
|
+
'**/*.md',
|
|
177
|
+
];
|
|
178
|
+
//# sourceMappingURL=file-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-cache.js","sourceRoot":"","sources":["../../src/framework/file-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview File type filtering for per-check file extension matching
|
|
3
|
+
*
|
|
4
|
+
* Filters matched files by extension based on a check's declared fileTypes.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Filter files by extension based on a check's declared fileTypes.
|
|
8
|
+
* If fileTypes is undefined or empty, returns all files (universal).
|
|
9
|
+
*/
|
|
10
|
+
export declare function filterFilesByType(files: readonly string[], fileTypes: readonly string[] | undefined): string[];
|
|
11
|
+
//# sourceMappingURL=file-type-filter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-type-filter.d.ts","sourceRoot":"","sources":["../../src/framework/file-type-filter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GACvC,MAAM,EAAE,CASV"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview File type filtering for per-check file extension matching
|
|
3
|
+
*
|
|
4
|
+
* Filters matched files by extension based on a check's declared fileTypes.
|
|
5
|
+
*/
|
|
6
|
+
import * as path from 'node:path';
|
|
7
|
+
/**
|
|
8
|
+
* Filter files by extension based on a check's declared fileTypes.
|
|
9
|
+
* If fileTypes is undefined or empty, returns all files (universal).
|
|
10
|
+
*/
|
|
11
|
+
export function filterFilesByType(files, fileTypes) {
|
|
12
|
+
if (!fileTypes || fileTypes.length === 0) {
|
|
13
|
+
return [...files];
|
|
14
|
+
}
|
|
15
|
+
const extensions = new Set(fileTypes);
|
|
16
|
+
return files.filter((f) => {
|
|
17
|
+
const ext = path.extname(f).slice(1); // remove leading dot
|
|
18
|
+
return extensions.has(ext);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=file-type-filter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-type-filter.js","sourceRoot":"","sources":["../../src/framework/file-type-filter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAwB,EACxB,SAAwC;IAExC,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAA;IACnB,CAAC;IACD,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAA;IACrC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA,CAAC,qBAAqB;QAC1D,OAAO,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Ignore directive processing for fitness checks
|
|
3
|
+
*
|
|
4
|
+
* Filters signals based on file-level and line-level ignore directives.
|
|
5
|
+
* Signals pointing at lines that contain @fitness-ignore directives are
|
|
6
|
+
* never suppressed — this prevents recursive suppression loops where
|
|
7
|
+
* directive-auditing checks would otherwise flag their own suppressions.
|
|
8
|
+
*/
|
|
9
|
+
import type { DirectiveEntry } from './directive-inventory.js';
|
|
10
|
+
import type { CheckResult } from '../types/findings.js';
|
|
11
|
+
import type { Signal } from '@opensip-tools/core';
|
|
12
|
+
/** Filter signals based on file-level and line-level @fitness-ignore directives */
|
|
13
|
+
export declare function filterSignalsByDirectives(signals: readonly Signal[], checkId: string, initialIgnoredCount: number): Promise<{
|
|
14
|
+
filteredSignals: Signal[];
|
|
15
|
+
ignoredCount: number;
|
|
16
|
+
appliedDirectives: DirectiveEntry[];
|
|
17
|
+
}>;
|
|
18
|
+
/**
|
|
19
|
+
* Builds the filtered result from the original result and filtered signals.
|
|
20
|
+
*/
|
|
21
|
+
export declare function buildFilteredResult(result: CheckResult, filteredSignals: Signal[], ignoredCount: number, start: number): CheckResult;
|
|
22
|
+
//# sourceMappingURL=ignore-processing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore-processing.d.ts","sourceRoot":"","sources":["../../src/framework/ignore-processing.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAWH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AA2IjD,mFAAmF;AACnF,wBAAsB,yBAAyB,CAC7C,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC;IAAE,eAAe,EAAE,MAAM,EAAE,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,iBAAiB,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAuBnG;AAgID;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,WAAW,EACnB,eAAe,EAAE,MAAM,EAAE,EACzB,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,GACZ,WAAW,CAwBb"}
|