@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,241 @@
|
|
|
1
|
+
// @fitness-ignore-file batch-operation-limits -- iterates bounded collections (config entries, registry items, or small analysis results)
|
|
2
|
+
// @fitness-ignore-file concurrency-safety -- Single-threaded Node.js; Map-based caches are safe without synchronization
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Ignore directive processing for fitness checks
|
|
5
|
+
*
|
|
6
|
+
* Filters signals based on file-level and line-level ignore directives.
|
|
7
|
+
* Signals pointing at lines that contain @fitness-ignore directives are
|
|
8
|
+
* never suppressed — this prevents recursive suppression loops where
|
|
9
|
+
* directive-auditing checks would otherwise flag their own suppressions.
|
|
10
|
+
*/
|
|
11
|
+
import { logger } from '@opensip-tools/core';
|
|
12
|
+
import { countErrors, countWarnings } from '../types/severity.js';
|
|
13
|
+
import { extractGroup, isWeakReason, parseDirectiveLine } from './directive-inventory.js';
|
|
14
|
+
import { parseFileIgnoreDirective, parseIgnoreDirectives } from './directive-parsing.js';
|
|
15
|
+
import { fileCache } from './file-cache.js';
|
|
16
|
+
// =============================================================================
|
|
17
|
+
// DIRECTIVE LINE DETECTION
|
|
18
|
+
// =============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Scan file content and return the set of 1-based line numbers that contain
|
|
21
|
+
* @fitness-ignore directives. These lines are framework infrastructure and
|
|
22
|
+
* must never be suppressed by other directives (prevents recursive loops).
|
|
23
|
+
*/
|
|
24
|
+
function findDirectiveLines(content) {
|
|
25
|
+
const directiveLines = new Set();
|
|
26
|
+
const lines = content.split('\n');
|
|
27
|
+
for (const [i, line] of lines.entries()) {
|
|
28
|
+
const trimmed = (line ?? '').trimStart();
|
|
29
|
+
if ((trimmed.startsWith('//') || trimmed.startsWith('/*')) &&
|
|
30
|
+
trimmed.includes('@fitness-ignore')) {
|
|
31
|
+
directiveLines.add(i + 1);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return directiveLines;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Processes file ignore status and caches the result.
|
|
38
|
+
*/
|
|
39
|
+
async function processFileIgnoreStatus(filePath, checkId, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
|
|
40
|
+
// in-memory: single-threaded Node.js access pattern
|
|
41
|
+
const fileIgnored = fileIgnoreCache.get(filePath);
|
|
42
|
+
if (fileIgnored !== undefined) {
|
|
43
|
+
return {
|
|
44
|
+
fileIgnored,
|
|
45
|
+
ignoredLines: lineIgnoreCache.get(filePath) ?? null,
|
|
46
|
+
directiveLines: directiveLineCache?.get(filePath) ?? new Set(),
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const content = await fileCache.get(filePath);
|
|
51
|
+
const isIgnored = parseFileIgnoreDirective(content, checkId);
|
|
52
|
+
fileIgnoreCache.set(filePath, isIgnored);
|
|
53
|
+
// Always scan for directive lines (needed for recursive loop prevention)
|
|
54
|
+
const dirLines = findDirectiveLines(content);
|
|
55
|
+
directiveLineCache?.set(filePath, dirLines);
|
|
56
|
+
let ignoredLines = null;
|
|
57
|
+
if (!isIgnored) {
|
|
58
|
+
ignoredLines = parseIgnoreDirectives(content, checkId);
|
|
59
|
+
lineIgnoreCache.set(filePath, ignoredLines);
|
|
60
|
+
}
|
|
61
|
+
return { fileIgnored: isIgnored, ignoredLines, directiveLines: dirLines };
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
logger.warn('fitness.ignore.file_read.failed', { evt: 'fitness.ignore.file_read.failed', module: 'fitness:ignore-processing', filePath, err: error });
|
|
65
|
+
fileIgnoreCache.set(filePath, false);
|
|
66
|
+
return { fileIgnored: false, ignoredLines: null, directiveLines: new Set() };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function classifySignals(signals, initialIgnoredCount, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
|
|
70
|
+
const filteredSignals = [];
|
|
71
|
+
let ignoredCount = initialIgnoredCount;
|
|
72
|
+
const appliedFileIgnores = new Set();
|
|
73
|
+
const appliedLineIgnores = new Map();
|
|
74
|
+
for (const signal of signals) {
|
|
75
|
+
if (!isSignalIgnored(signal, fileIgnoreCache, lineIgnoreCache, directiveLineCache)) {
|
|
76
|
+
filteredSignals.push(signal);
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
ignoredCount++;
|
|
80
|
+
const filePath = signal.code?.file;
|
|
81
|
+
if (!filePath)
|
|
82
|
+
continue;
|
|
83
|
+
if (fileIgnoreCache.get(filePath)) {
|
|
84
|
+
appliedFileIgnores.add(filePath);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const line = signal.code?.line;
|
|
88
|
+
if (line) {
|
|
89
|
+
let lineSet = appliedLineIgnores.get(filePath);
|
|
90
|
+
if (!lineSet) {
|
|
91
|
+
lineSet = new Set();
|
|
92
|
+
appliedLineIgnores.set(filePath, lineSet);
|
|
93
|
+
}
|
|
94
|
+
lineSet.add(line);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { filteredSignals, ignoredCount, appliedFileIgnores, appliedLineIgnores };
|
|
99
|
+
}
|
|
100
|
+
/** Filter signals based on file-level and line-level @fitness-ignore directives */
|
|
101
|
+
export async function filterSignalsByDirectives(signals, checkId, initialIgnoredCount) {
|
|
102
|
+
const fileIgnoreCache = new Map();
|
|
103
|
+
const lineIgnoreCache = new Map();
|
|
104
|
+
const directiveLineCache = new Map();
|
|
105
|
+
// Pre-populate file ignore status for all unique file paths in parallel
|
|
106
|
+
const uniqueFiles = new Set();
|
|
107
|
+
for (const signal of signals) {
|
|
108
|
+
const filePath = signal.code?.file;
|
|
109
|
+
if (filePath)
|
|
110
|
+
uniqueFiles.add(filePath);
|
|
111
|
+
}
|
|
112
|
+
await Promise.all([...uniqueFiles].map((filePath) => processFileIgnoreStatus(filePath, checkId, fileIgnoreCache, lineIgnoreCache, directiveLineCache)));
|
|
113
|
+
const { filteredSignals, ignoredCount, appliedFileIgnores, appliedLineIgnores } = classifySignals(signals, initialIgnoredCount, fileIgnoreCache, lineIgnoreCache, directiveLineCache);
|
|
114
|
+
const appliedDirectives = await collectAppliedDirectives(checkId, appliedFileIgnores, appliedLineIgnores);
|
|
115
|
+
return { filteredSignals, ignoredCount, appliedDirectives };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Determines whether a single signal should be ignored based on cached directive data.
|
|
119
|
+
*
|
|
120
|
+
* File-level ignores always apply (the entire file is suppressed).
|
|
121
|
+
* Line-level ignores apply unless the signal points at a directive line itself
|
|
122
|
+
* (prevents recursive loops where directive-auditing checks suppress their own findings).
|
|
123
|
+
*/
|
|
124
|
+
function isSignalIgnored(signal, fileIgnoreCache, lineIgnoreCache, directiveLineCache) {
|
|
125
|
+
const filePath = signal.code?.file;
|
|
126
|
+
if (!filePath)
|
|
127
|
+
return false;
|
|
128
|
+
// File-level ignores always apply — no anti-recursion needed
|
|
129
|
+
if (fileIgnoreCache.get(filePath))
|
|
130
|
+
return true;
|
|
131
|
+
const signalLine = signal.code?.line;
|
|
132
|
+
const dirLines = directiveLineCache.get(filePath);
|
|
133
|
+
// For line-level ignores: never suppress signals pointing at directive lines (anti-recursion)
|
|
134
|
+
if (signalLine && dirLines?.has(signalLine))
|
|
135
|
+
return false;
|
|
136
|
+
const ignoredLines = lineIgnoreCache.get(filePath);
|
|
137
|
+
if (signalLine && ignoredLines?.has(signalLine))
|
|
138
|
+
return true;
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
// =============================================================================
|
|
142
|
+
// APPLIED DIRECTIVE COLLECTION
|
|
143
|
+
// =============================================================================
|
|
144
|
+
function toDirectiveEntry(filePath, lineNumber, parsed) {
|
|
145
|
+
return {
|
|
146
|
+
filePath,
|
|
147
|
+
lineNumber,
|
|
148
|
+
type: parsed.type,
|
|
149
|
+
checkId: parsed.checkId,
|
|
150
|
+
group: extractGroup(parsed.checkId),
|
|
151
|
+
reason: parsed.reason,
|
|
152
|
+
weakReason: isWeakReason(parsed.reason),
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
async function collectFileIgnoreDirectives(checkId, appliedFileIgnores) {
|
|
156
|
+
const results = await Promise.all([...appliedFileIgnores].map(async (filePath) => {
|
|
157
|
+
try {
|
|
158
|
+
const content = await fileCache.get(filePath);
|
|
159
|
+
const lines = content.split('\n');
|
|
160
|
+
for (let i = 0; i < Math.min(lines.length, 50); i++) {
|
|
161
|
+
const parsed = parseDirectiveLine(lines[i] ?? '');
|
|
162
|
+
if (parsed?.type === 'file' && parsed.checkId === checkId) {
|
|
163
|
+
return toDirectiveEntry(filePath, i + 1, parsed);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
logger.warn('fitness.ignore.directive_read.failed', { evt: 'fitness.ignore.directive_read.failed', module: 'fitness:ignore-processing', err: error });
|
|
169
|
+
}
|
|
170
|
+
return null;
|
|
171
|
+
}));
|
|
172
|
+
return results.filter((d) => d !== null);
|
|
173
|
+
}
|
|
174
|
+
async function collectLineIgnoreDirectives(checkId, appliedLineIgnores) {
|
|
175
|
+
const results = await Promise.all([...appliedLineIgnores.entries()].map(async ([filePath, suppressedLines]) => {
|
|
176
|
+
const found = [];
|
|
177
|
+
try {
|
|
178
|
+
const content = await fileCache.get(filePath);
|
|
179
|
+
const lines = content.split('\n');
|
|
180
|
+
for (let i = 0; i < lines.length; i++) {
|
|
181
|
+
const parsed = parseDirectiveLine(lines[i] ?? '');
|
|
182
|
+
if (parsed?.type !== 'next-line' || parsed.checkId !== checkId)
|
|
183
|
+
continue;
|
|
184
|
+
let targetLine = i + 1;
|
|
185
|
+
while (targetLine < lines.length && (lines[targetLine] ?? '').trimStart().startsWith('//')) {
|
|
186
|
+
targetLine++;
|
|
187
|
+
}
|
|
188
|
+
if (suppressedLines.has(targetLine + 1)) {
|
|
189
|
+
found.push(toDirectiveEntry(filePath, i + 1, parsed));
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
logger.warn('fitness.ignore.directive_read.failed', { evt: 'fitness.ignore.directive_read.failed', module: 'fitness:ignore-processing', err: error });
|
|
195
|
+
}
|
|
196
|
+
return found;
|
|
197
|
+
}));
|
|
198
|
+
const directives = [];
|
|
199
|
+
for (const batch of results) {
|
|
200
|
+
for (const d of batch) {
|
|
201
|
+
directives.push(d);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
return directives;
|
|
205
|
+
}
|
|
206
|
+
async function collectAppliedDirectives(checkId, appliedFileIgnores, appliedLineIgnores) {
|
|
207
|
+
const [fileDirectives, lineDirectives] = await Promise.all([
|
|
208
|
+
collectFileIgnoreDirectives(checkId, appliedFileIgnores),
|
|
209
|
+
collectLineIgnoreDirectives(checkId, appliedLineIgnores),
|
|
210
|
+
]);
|
|
211
|
+
return [...fileDirectives, ...lineDirectives];
|
|
212
|
+
}
|
|
213
|
+
// =============================================================================
|
|
214
|
+
// RESULT BUILDING
|
|
215
|
+
// =============================================================================
|
|
216
|
+
/**
|
|
217
|
+
* Builds the filtered result from the original result and filtered signals.
|
|
218
|
+
*/
|
|
219
|
+
export function buildFilteredResult(result, filteredSignals, ignoredCount, start) {
|
|
220
|
+
if (!Array.isArray(filteredSignals)) {
|
|
221
|
+
return result;
|
|
222
|
+
}
|
|
223
|
+
const durationMs = result.metadata.durationMs ?? Date.now() - start;
|
|
224
|
+
const filteredErrors = countErrors(filteredSignals);
|
|
225
|
+
const filteredWarnings = countWarnings(filteredSignals);
|
|
226
|
+
const filteredResult = {
|
|
227
|
+
...result,
|
|
228
|
+
passed: filteredErrors === 0,
|
|
229
|
+
errors: filteredErrors,
|
|
230
|
+
warnings: filteredWarnings,
|
|
231
|
+
signals: filteredSignals,
|
|
232
|
+
metadata: {
|
|
233
|
+
...result.metadata,
|
|
234
|
+
durationMs,
|
|
235
|
+
signals: filteredSignals,
|
|
236
|
+
},
|
|
237
|
+
...(ignoredCount > 0 ? { ignoredCount } : {}),
|
|
238
|
+
};
|
|
239
|
+
return filteredResult;
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=ignore-processing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ignore-processing.js","sourceRoot":"","sources":["../../src/framework/ignore-processing.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Project-wide import graph builder.
|
|
3
|
+
*
|
|
4
|
+
* Builds a file-level dependency graph from a set of TypeScript/JavaScript
|
|
5
|
+
* source files, plus a Tarjan's strongly-connected-components implementation
|
|
6
|
+
* for cycle detection. Used by structural-drift checks like
|
|
7
|
+
* circular-import-detection and module-coupling-fan-out.
|
|
8
|
+
*
|
|
9
|
+
* Module resolution is deliberately a heuristic: relative imports are
|
|
10
|
+
* resolved by trying common extension/index.ts suffixes; bare specifiers
|
|
11
|
+
* (npm packages) are dropped; tsconfig path aliases are NOT resolved
|
|
12
|
+
* (treated as unresolved — they simply don't appear as edges in the graph).
|
|
13
|
+
*
|
|
14
|
+
* This matches the heuristic the existing `phantom-dependency-detection`
|
|
15
|
+
* check uses, which has been shipping reliably. Adding tsconfig-aware
|
|
16
|
+
* resolution is a follow-up plan.
|
|
17
|
+
*/
|
|
18
|
+
/** A file-level import graph for a project. */
|
|
19
|
+
export interface ImportGraph {
|
|
20
|
+
/** All node file paths (absolute, as supplied by the caller). */
|
|
21
|
+
readonly nodes: ReadonlySet<string>;
|
|
22
|
+
/** Adjacency: file → set of files it imports (intra-project edges only). */
|
|
23
|
+
readonly outbound: ReadonlyMap<string, ReadonlySet<string>>;
|
|
24
|
+
/** Reverse adjacency: file → set of files that import it. */
|
|
25
|
+
readonly inbound: ReadonlyMap<string, ReadonlySet<string>>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Build an import graph from a collection of file paths and their content.
|
|
29
|
+
*
|
|
30
|
+
* Each file's TS AST is walked for top-level `import` and `export ... from`
|
|
31
|
+
* declarations. Relative specifiers (`./foo`, `../bar/baz.js`) are resolved
|
|
32
|
+
* against the importing file's directory using the heuristic in
|
|
33
|
+
* `resolveRelativeSpecifier`. Bare specifiers (`react`, `lodash`) are
|
|
34
|
+
* dropped — they don't represent intra-project edges.
|
|
35
|
+
*
|
|
36
|
+
* Files that fail to parse are still added as nodes (with no edges) so the
|
|
37
|
+
* graph remains complete.
|
|
38
|
+
*/
|
|
39
|
+
export declare function buildImportGraph(files: ReadonlyMap<string, string>): ImportGraph;
|
|
40
|
+
/**
|
|
41
|
+
* Find strongly-connected components in the graph using Tarjan's algorithm.
|
|
42
|
+
*
|
|
43
|
+
* Returns an array of SCCs, each represented as an array of node names. SCCs
|
|
44
|
+
* of size 1 represent a node with no cycle (or a self-loop, which is rare in
|
|
45
|
+
* import graphs). Cycle-detection callers typically filter to `scc.length > 1`
|
|
46
|
+
* to get only real multi-file cycles.
|
|
47
|
+
*
|
|
48
|
+
* Algorithm: standard iterative Tarjan's SCC. O(V + E), single pass.
|
|
49
|
+
*/
|
|
50
|
+
export declare function findStronglyConnectedComponents(graph: ImportGraph): readonly (readonly string[])[];
|
|
51
|
+
//# sourceMappingURL=import-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-graph.d.ts","sourceRoot":"","sources":["../../src/framework/import-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAYH,+CAA+C;AAC/C,MAAM,WAAW,WAAW;IAC1B,iEAAiE;IACjE,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACnC,4EAA4E;IAC5E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;IAC3D,6DAA6D;IAC7D,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC,CAAA;CAC3D;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,WAAW,CAwBhF;AAED;;;;;;;;;GASG;AACH,wBAAgB,+BAA+B,CAC7C,KAAK,EAAE,WAAW,GACjB,SAAS,CAAC,SAAS,MAAM,EAAE,CAAC,EAAE,CAiGhC"}
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Project-wide import graph builder.
|
|
3
|
+
*
|
|
4
|
+
* Builds a file-level dependency graph from a set of TypeScript/JavaScript
|
|
5
|
+
* source files, plus a Tarjan's strongly-connected-components implementation
|
|
6
|
+
* for cycle detection. Used by structural-drift checks like
|
|
7
|
+
* circular-import-detection and module-coupling-fan-out.
|
|
8
|
+
*
|
|
9
|
+
* Module resolution is deliberately a heuristic: relative imports are
|
|
10
|
+
* resolved by trying common extension/index.ts suffixes; bare specifiers
|
|
11
|
+
* (npm packages) are dropped; tsconfig path aliases are NOT resolved
|
|
12
|
+
* (treated as unresolved — they simply don't appear as edges in the graph).
|
|
13
|
+
*
|
|
14
|
+
* This matches the heuristic the existing `phantom-dependency-detection`
|
|
15
|
+
* check uses, which has been shipping reliably. Adding tsconfig-aware
|
|
16
|
+
* resolution is a follow-up plan.
|
|
17
|
+
*/
|
|
18
|
+
import * as path from 'node:path';
|
|
19
|
+
import ts from 'typescript';
|
|
20
|
+
import { getSharedSourceFile } from './parse-cache.js';
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// PUBLIC API
|
|
23
|
+
// =============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Build an import graph from a collection of file paths and their content.
|
|
26
|
+
*
|
|
27
|
+
* Each file's TS AST is walked for top-level `import` and `export ... from`
|
|
28
|
+
* declarations. Relative specifiers (`./foo`, `../bar/baz.js`) are resolved
|
|
29
|
+
* against the importing file's directory using the heuristic in
|
|
30
|
+
* `resolveRelativeSpecifier`. Bare specifiers (`react`, `lodash`) are
|
|
31
|
+
* dropped — they don't represent intra-project edges.
|
|
32
|
+
*
|
|
33
|
+
* Files that fail to parse are still added as nodes (with no edges) so the
|
|
34
|
+
* graph remains complete.
|
|
35
|
+
*/
|
|
36
|
+
export function buildImportGraph(files) {
|
|
37
|
+
const nodes = new Set(files.keys());
|
|
38
|
+
const outbound = new Map();
|
|
39
|
+
const inbound = new Map();
|
|
40
|
+
// Initialize empty edge sets for every node so callers can safely
|
|
41
|
+
// outbound.get(file) without checking for undefined.
|
|
42
|
+
for (const node of nodes) {
|
|
43
|
+
outbound.set(node, new Set());
|
|
44
|
+
inbound.set(node, new Set());
|
|
45
|
+
}
|
|
46
|
+
for (const [filePath, content] of files) {
|
|
47
|
+
const specifiers = extractImportSpecifiers(filePath, content);
|
|
48
|
+
for (const spec of specifiers) {
|
|
49
|
+
const resolved = resolveRelativeSpecifier(filePath, spec, nodes);
|
|
50
|
+
if (resolved !== null) {
|
|
51
|
+
outbound.get(filePath).add(resolved);
|
|
52
|
+
inbound.get(resolved).add(filePath);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return { nodes, outbound, inbound };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Find strongly-connected components in the graph using Tarjan's algorithm.
|
|
60
|
+
*
|
|
61
|
+
* Returns an array of SCCs, each represented as an array of node names. SCCs
|
|
62
|
+
* of size 1 represent a node with no cycle (or a self-loop, which is rare in
|
|
63
|
+
* import graphs). Cycle-detection callers typically filter to `scc.length > 1`
|
|
64
|
+
* to get only real multi-file cycles.
|
|
65
|
+
*
|
|
66
|
+
* Algorithm: standard iterative Tarjan's SCC. O(V + E), single pass.
|
|
67
|
+
*/
|
|
68
|
+
export function findStronglyConnectedComponents(graph) {
|
|
69
|
+
const indexOf = new Map();
|
|
70
|
+
const lowlinkOf = new Map();
|
|
71
|
+
const onStack = new Set();
|
|
72
|
+
const stack = [];
|
|
73
|
+
const sccs = [];
|
|
74
|
+
let nextIndex = 0;
|
|
75
|
+
// eslint-disable-next-line sonarjs/cognitive-complexity -- iterative Tarjan SCC: explicit stack to avoid recursion; the algorithm is canonical and reads cleanest as a single function
|
|
76
|
+
function strongConnect(start) {
|
|
77
|
+
const callStack = [];
|
|
78
|
+
indexOf.set(start, nextIndex);
|
|
79
|
+
lowlinkOf.set(start, nextIndex);
|
|
80
|
+
nextIndex++;
|
|
81
|
+
stack.push(start);
|
|
82
|
+
onStack.add(start);
|
|
83
|
+
callStack.push({
|
|
84
|
+
node: start,
|
|
85
|
+
neighbors: [...(graph.outbound.get(start) ?? [])],
|
|
86
|
+
next: 0,
|
|
87
|
+
});
|
|
88
|
+
while (callStack.length > 0) {
|
|
89
|
+
const frame = callStack.at(-1);
|
|
90
|
+
if (frame.next < frame.neighbors.length) {
|
|
91
|
+
const w = frame.neighbors[frame.next];
|
|
92
|
+
frame.next++;
|
|
93
|
+
if (!indexOf.has(w)) {
|
|
94
|
+
// Recurse into w.
|
|
95
|
+
indexOf.set(w, nextIndex);
|
|
96
|
+
lowlinkOf.set(w, nextIndex);
|
|
97
|
+
nextIndex++;
|
|
98
|
+
stack.push(w);
|
|
99
|
+
onStack.add(w);
|
|
100
|
+
callStack.push({
|
|
101
|
+
node: w,
|
|
102
|
+
neighbors: [...(graph.outbound.get(w) ?? [])],
|
|
103
|
+
next: 0,
|
|
104
|
+
});
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
if (onStack.has(w)) {
|
|
108
|
+
// Back edge — update v's lowlink.
|
|
109
|
+
const vLow = lowlinkOf.get(frame.node);
|
|
110
|
+
const wIdx = indexOf.get(w);
|
|
111
|
+
if (wIdx < vLow)
|
|
112
|
+
lowlinkOf.set(frame.node, wIdx);
|
|
113
|
+
}
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
// All neighbors processed — finalize this node.
|
|
117
|
+
const v = frame.node;
|
|
118
|
+
const vLow = lowlinkOf.get(v);
|
|
119
|
+
const vIdx = indexOf.get(v);
|
|
120
|
+
if (vLow === vIdx) {
|
|
121
|
+
// v is the root of an SCC — pop until v is removed.
|
|
122
|
+
const scc = [];
|
|
123
|
+
let w;
|
|
124
|
+
do {
|
|
125
|
+
w = stack.pop();
|
|
126
|
+
onStack.delete(w);
|
|
127
|
+
scc.push(w);
|
|
128
|
+
} while (w !== v);
|
|
129
|
+
sccs.push(scc);
|
|
130
|
+
}
|
|
131
|
+
callStack.pop();
|
|
132
|
+
// Propagate lowlink up to the parent frame.
|
|
133
|
+
if (callStack.length > 0) {
|
|
134
|
+
const parent = callStack.at(-1);
|
|
135
|
+
const parentLow = lowlinkOf.get(parent.node);
|
|
136
|
+
if (vLow < parentLow)
|
|
137
|
+
lowlinkOf.set(parent.node, vLow);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
for (const node of graph.nodes) {
|
|
142
|
+
if (!indexOf.has(node)) {
|
|
143
|
+
strongConnect(node);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return sccs;
|
|
147
|
+
}
|
|
148
|
+
// =============================================================================
|
|
149
|
+
// INTERNAL HELPERS
|
|
150
|
+
// =============================================================================
|
|
151
|
+
/** Walk the AST and collect top-level import / export-from specifiers. */
|
|
152
|
+
function extractImportSpecifiers(filePath, content) {
|
|
153
|
+
const sourceFile = getSharedSourceFile(filePath, content);
|
|
154
|
+
if (sourceFile === null)
|
|
155
|
+
return [];
|
|
156
|
+
const specifiers = [];
|
|
157
|
+
for (const stmt of sourceFile.statements) {
|
|
158
|
+
// import foo from './bar'; import './side-effect'; import * as ns from './m';
|
|
159
|
+
if (ts.isImportDeclaration(stmt) && ts.isStringLiteral(stmt.moduleSpecifier)) {
|
|
160
|
+
specifiers.push(stmt.moduleSpecifier.text);
|
|
161
|
+
continue;
|
|
162
|
+
}
|
|
163
|
+
// export * from './foo'; export { x } from './foo';
|
|
164
|
+
if (ts.isExportDeclaration(stmt) &&
|
|
165
|
+
stmt.moduleSpecifier !== undefined &&
|
|
166
|
+
ts.isStringLiteral(stmt.moduleSpecifier)) {
|
|
167
|
+
specifiers.push(stmt.moduleSpecifier.text);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return specifiers;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Resolve a module specifier to an actual file path in the project, or
|
|
174
|
+
* return null if the specifier is non-relative (npm package, path alias) or
|
|
175
|
+
* doesn't resolve to a known project file.
|
|
176
|
+
*
|
|
177
|
+
* Supports:
|
|
178
|
+
* - `./foo` → `<dir>/foo.ts`, `.tsx`, `/index.ts`, `/index.tsx`
|
|
179
|
+
* - `./foo.js` → `<dir>/foo.ts` (ESM extension swap, common in TS+ESM)
|
|
180
|
+
* - `./foo.ts` → `<dir>/foo.ts` (literal)
|
|
181
|
+
* - `../bar/baz` → resolved relative to importer's directory
|
|
182
|
+
*
|
|
183
|
+
* Does NOT support:
|
|
184
|
+
* - tsconfig `paths` aliases (deferred per plan)
|
|
185
|
+
* - npm packages (correctly dropped — out of scope for intra-project graph)
|
|
186
|
+
*/
|
|
187
|
+
function resolveRelativeSpecifier(importerPath, specifier, knownPaths) {
|
|
188
|
+
// Only relative specifiers participate in the intra-project graph.
|
|
189
|
+
if (!specifier.startsWith('.'))
|
|
190
|
+
return null;
|
|
191
|
+
const importerDir = path.dirname(importerPath);
|
|
192
|
+
const base = path.resolve(importerDir, specifier);
|
|
193
|
+
// Try the candidate paths in priority order. The first one that exists in
|
|
194
|
+
// the project's file set wins.
|
|
195
|
+
const candidates = [base];
|
|
196
|
+
// 1. Literal path (specifier already includes extension).
|
|
197
|
+
// 2. ESM extension swap: `.js` → `.ts` / `.tsx` (TypeScript ESM convention).
|
|
198
|
+
if (base.endsWith('.js')) {
|
|
199
|
+
candidates.push(base.slice(0, -3) + '.ts', base.slice(0, -3) + '.tsx');
|
|
200
|
+
}
|
|
201
|
+
if (base.endsWith('.jsx')) {
|
|
202
|
+
candidates.push(base.slice(0, -4) + '.tsx');
|
|
203
|
+
}
|
|
204
|
+
// 3. Append common extensions if the specifier was extension-less.
|
|
205
|
+
const hasExt = path.extname(base) !== '';
|
|
206
|
+
if (!hasExt) {
|
|
207
|
+
// Direct extensions and index resolution.
|
|
208
|
+
candidates.push(base + '.ts', base + '.tsx', base + '.js', base + '.jsx', path.join(base, 'index.ts'), path.join(base, 'index.tsx'), path.join(base, 'index.js'), path.join(base, 'index.jsx'));
|
|
209
|
+
}
|
|
210
|
+
for (const candidate of candidates) {
|
|
211
|
+
if (knownPaths.has(candidate))
|
|
212
|
+
return candidate;
|
|
213
|
+
}
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
//# sourceMappingURL=import-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"import-graph.js","sourceRoot":"","sources":["../../src/framework/import-graph.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,IAAI,MAAM,WAAW,CAAA;AAEjC,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAA;AAgBtD,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAkC;IACjE,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC/C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAA;IAE9C,kEAAkE;IAClE,qDAAqD;IACrD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;QAC7B,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,KAAK,EAAE,CAAC;QACxC,MAAM,UAAU,GAAG,uBAAuB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC7D,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,MAAM,QAAQ,GAAG,wBAAwB,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,CAAC,CAAA;YAChE,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;gBACtB,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;gBACrC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAA;AACrC,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,+BAA+B,CAC7C,KAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IACzC,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC3C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAA;IACjC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,MAAM,IAAI,GAAe,EAAE,CAAA;IAC3B,IAAI,SAAS,GAAG,CAAC,CAAA;IAUjB,uLAAuL;IACvL,SAAS,aAAa,CAAC,KAAa;QAClC,MAAM,SAAS,GAAY,EAAE,CAAA;QAE7B,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC7B,SAAS,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC/B,SAAS,EAAE,CAAA;QACX,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;QACjB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,KAAK;YACX,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;YACjD,IAAI,EAAE,CAAC;SACR,CAAC,CAAA;QAEF,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAA;YAE/B,IAAI,KAAK,CAAC,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;gBACxC,MAAM,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;gBACrC,KAAK,CAAC,IAAI,EAAE,CAAA;gBAEZ,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpB,kBAAkB;oBAClB,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;oBACzB,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;oBAC3B,SAAS,EAAE,CAAA;oBACX,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;oBACb,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;oBACd,SAAS,CAAC,IAAI,CAAC;wBACb,IAAI,EAAE,CAAC;wBACP,SAAS,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;wBAC7C,IAAI,EAAE,CAAC;qBACR,CAAC,CAAA;oBACF,SAAQ;gBACV,CAAC;gBAED,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBACnB,kCAAkC;oBAClC,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAE,CAAA;oBACvC,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAE,CAAA;oBAC5B,IAAI,IAAI,GAAG,IAAI;wBAAE,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;gBAClD,CAAC;gBACD,SAAQ;YACV,CAAC;YAED,gDAAgD;YAChD,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAA;YACpB,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAE,CAAA;YAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAE,CAAA;YAE5B,IAAI,IAAI,KAAK,IAAI,EAAE,CAAC;gBAClB,oDAAoD;gBACpD,MAAM,GAAG,GAAa,EAAE,CAAA;gBACxB,IAAI,CAAS,CAAA;gBACb,GAAG,CAAC;oBACF,CAAC,GAAG,KAAK,CAAC,GAAG,EAAG,CAAA;oBAChB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;oBACjB,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;gBACb,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAChB,CAAC;YAED,SAAS,CAAC,GAAG,EAAE,CAAA;YAEf,4CAA4C;YAC5C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,CAAE,CAAA;gBAChC,MAAM,SAAS,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAE,CAAA;gBAC7C,IAAI,IAAI,GAAG,SAAS;oBAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;YACxD,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,aAAa,CAAC,IAAI,CAAC,CAAA;QACrB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED,gFAAgF;AAChF,mBAAmB;AACnB,gFAAgF;AAEhF,0EAA0E;AAC1E,SAAS,uBAAuB,CAAC,QAAgB,EAAE,OAAe;IAChE,MAAM,UAAU,GAAG,mBAAmB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;IACzD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,EAAE,CAAA;IAElC,MAAM,UAAU,GAAa,EAAE,CAAA;IAC/B,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;QACzC,gFAAgF;QAChF,IAAI,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;YAC7E,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;YAC1C,SAAQ;QACV,CAAC;QACD,sDAAsD;QACtD,IACE,EAAE,CAAC,mBAAmB,CAAC,IAAI,CAAC;YAC5B,IAAI,CAAC,eAAe,KAAK,SAAS;YAClC,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,eAAe,CAAC,EACxC,CAAC;YACD,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAA;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAA;AACnB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,wBAAwB,CAC/B,YAAoB,EACpB,SAAiB,EACjB,UAA+B;IAE/B,mEAAmE;IACnE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAA;IAE3C,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAEjD,0EAA0E;IAC1E,+BAA+B;IAC/B,MAAM,UAAU,GAAa,CAAE,IAAI,CAAC,CAAA;IAEpC,0DAA0D;IAE1D,6EAA6E;IAC7E,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;IACxE,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAA;IAC7C,CAAC;IAED,mEAAmE;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,CAAA;IACxC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,0CAA0C;QAC1C,UAAU,CAAC,IAAI,CACb,IAAI,GAAG,KAAK,EACZ,IAAI,GAAG,MAAM,EACb,IAAI,GAAG,KAAK,EACZ,IAAI,GAAG,MAAM,EACb,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,EAC5B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,EAC3B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAC7B,CAAA;IACH,CAAC;IAED,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,IAAI,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC;YAAE,OAAO,SAAS,CAAA;IACjD,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Memory profiler for fitness checks
|
|
3
|
+
*
|
|
4
|
+
* Always-on, low-overhead memory tracking for check execution.
|
|
5
|
+
* Collects per-check profiles for trending analysis.
|
|
6
|
+
*/
|
|
7
|
+
/** Memory usage profile recorded for a single check execution */
|
|
8
|
+
export interface CheckMemoryProfile {
|
|
9
|
+
readonly checkId: string;
|
|
10
|
+
readonly memoryBeforeMB: number;
|
|
11
|
+
readonly memoryAfterMB: number;
|
|
12
|
+
readonly memoryDeltaMB: number;
|
|
13
|
+
readonly violationCount: number;
|
|
14
|
+
readonly durationMs: number;
|
|
15
|
+
}
|
|
16
|
+
/** Aggregated memory profiling summary across all check executions */
|
|
17
|
+
interface MemoryProfileSummary {
|
|
18
|
+
readonly prewarmMemoryMB: number;
|
|
19
|
+
readonly peakMemoryMB: number;
|
|
20
|
+
readonly checksExceedingThreshold: number;
|
|
21
|
+
readonly topConsumers: readonly CheckMemoryProfile[];
|
|
22
|
+
readonly allProfiles: readonly CheckMemoryProfile[];
|
|
23
|
+
}
|
|
24
|
+
/** Low-overhead memory profiler that tracks per-check heap usage during fitness runs */
|
|
25
|
+
declare class MemoryProfiler {
|
|
26
|
+
private readonly profiles;
|
|
27
|
+
private prewarmMemoryMB;
|
|
28
|
+
private peakMemoryMB;
|
|
29
|
+
private readonly warningThresholdMB;
|
|
30
|
+
constructor(warningThresholdMB?: number);
|
|
31
|
+
private takeSnapshot;
|
|
32
|
+
private bytesToMB;
|
|
33
|
+
/** Record memory baseline after cache prewarm completes */
|
|
34
|
+
recordPrewarmComplete(): void;
|
|
35
|
+
/** Return current heap usage in megabytes */
|
|
36
|
+
getCurrentMemoryMB(): number;
|
|
37
|
+
/** Record memory before a check starts; returns the pre-check heap in MB */
|
|
38
|
+
recordCheckStart(): number;
|
|
39
|
+
/** Record memory after a check completes and return the check's memory profile */
|
|
40
|
+
recordCheckComplete(checkId: string, memoryBeforeMB: number, violationCount: number, durationMs: number): CheckMemoryProfile;
|
|
41
|
+
/** Check whether a memory delta exceeds the configured warning threshold */
|
|
42
|
+
exceedsThreshold(deltaMB: number): boolean;
|
|
43
|
+
/** Return the configured warning threshold in megabytes */
|
|
44
|
+
getWarningThresholdMB(): number;
|
|
45
|
+
/** Build and return an aggregated summary of all recorded check profiles */
|
|
46
|
+
getSummary(): MemoryProfileSummary;
|
|
47
|
+
/** Reset all recorded profiles and counters */
|
|
48
|
+
reset(): void;
|
|
49
|
+
}
|
|
50
|
+
/** Shared singleton memory profiler instance used across fitness check runs */
|
|
51
|
+
export declare const memoryProfiler: MemoryProfiler;
|
|
52
|
+
export {};
|
|
53
|
+
//# sourceMappingURL=memory-profiler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-profiler.d.ts","sourceRoot":"","sources":["../../src/framework/memory-profiler.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH,iEAAiE;AACjE,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAC/B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAC5B;AAED,sEAAsE;AACtE,UAAU,oBAAoB;IAC5B,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAA;IAC7B,QAAQ,CAAC,wBAAwB,EAAE,MAAM,CAAA;IACzC,QAAQ,CAAC,YAAY,EAAE,SAAS,kBAAkB,EAAE,CAAA;IACpD,QAAQ,CAAC,WAAW,EAAE,SAAS,kBAAkB,EAAE,CAAA;CACpD;AAID,wFAAwF;AACxF,cAAM,cAAc;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA2B;IACpD,OAAO,CAAC,eAAe,CAAI;IAC3B,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAQ;gBAE/B,kBAAkB,SAAsC;IAIpE,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,SAAS;IAIjB,2DAA2D;IAC3D,qBAAqB,IAAI,IAAI;IAM7B,6CAA6C;IAC7C,kBAAkB,IAAI,MAAM;IAK5B,4EAA4E;IAC5E,gBAAgB,IAAI,MAAM;IAI1B,kFAAkF;IAClF,mBAAmB,CACjB,OAAO,EAAE,MAAM,EACf,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,UAAU,EAAE,MAAM,GACjB,kBAAkB;IAqBrB,4EAA4E;IAC5E,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAI1C,2DAA2D;IAC3D,qBAAqB,IAAI,MAAM;IAI/B,4EAA4E;IAC5E,UAAU,IAAI,oBAAoB;IAgBlC,+CAA+C;IAC/C,KAAK,IAAI,IAAI;CAKd;AAED,+EAA+E;AAC/E,eAAO,MAAM,cAAc,gBAAuB,CAAA"}
|