@optave/codegraph 3.4.0 → 3.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/ast-analysis/engine.d.ts.map +1 -1
- package/dist/ast-analysis/engine.js +3 -9
- package/dist/ast-analysis/engine.js.map +1 -1
- package/dist/ast-analysis/shared.d.ts.map +1 -1
- package/dist/ast-analysis/shared.js +0 -1
- package/dist/ast-analysis/shared.js.map +1 -1
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts +5 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js +166 -0
- package/dist/ast-analysis/visitors/cfg-conditionals.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts +7 -0
- package/dist/ast-analysis/visitors/cfg-loops.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-loops.js +73 -0
- package/dist/ast-analysis/visitors/cfg-loops.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts +56 -0
- package/dist/ast-analysis/visitors/cfg-shared.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-shared.js +107 -0
- package/dist/ast-analysis/visitors/cfg-shared.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts +4 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.d.ts.map +1 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js +100 -0
- package/dist/ast-analysis/visitors/cfg-try-catch.js.map +1 -0
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts +2 -2
- package/dist/ast-analysis/visitors/cfg-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/cfg-visitor.js +11 -445
- package/dist/ast-analysis/visitors/cfg-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/complexity-visitor.js.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.d.ts.map +1 -1
- package/dist/ast-analysis/visitors/dataflow-visitor.js.map +1 -1
- package/dist/cli/commands/batch.d.ts.map +1 -1
- package/dist/cli/commands/batch.js +4 -3
- package/dist/cli/commands/batch.js.map +1 -1
- package/dist/cli/commands/branch-compare.js +1 -1
- package/dist/cli/commands/branch-compare.js.map +1 -1
- package/dist/cli/commands/build.js +1 -1
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/info.d.ts.map +1 -1
- package/dist/cli/commands/info.js +1 -2
- package/dist/cli/commands/info.js.map +1 -1
- package/dist/cli/commands/path.d.ts.map +1 -1
- package/dist/cli/commands/path.js +7 -2
- package/dist/cli/commands/path.js.map +1 -1
- package/dist/cli/commands/plot.d.ts.map +1 -1
- package/dist/cli/commands/plot.js +2 -2
- package/dist/cli/commands/plot.js.map +1 -1
- package/dist/cli/commands/watch.js +1 -1
- package/dist/cli/commands/watch.js.map +1 -1
- package/dist/cli/index.js +2 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/shared/open-graph.d.ts +2 -2
- package/dist/cli/shared/open-graph.d.ts.map +1 -1
- package/dist/cli/shared/open-graph.js.map +1 -1
- package/dist/cli/types.d.ts +1 -1
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli.js +2 -3
- package/dist/cli.js.map +1 -1
- package/dist/db/connection.d.ts +17 -0
- package/dist/db/connection.d.ts.map +1 -1
- package/dist/db/connection.js +91 -2
- package/dist/db/connection.js.map +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +7 -0
- package/dist/db/migrations.js.map +1 -1
- package/dist/domain/analysis/brief.d.ts.map +1 -1
- package/dist/domain/analysis/brief.js +1 -3
- package/dist/domain/analysis/brief.js.map +1 -1
- package/dist/domain/analysis/context.d.ts.map +1 -1
- package/dist/domain/analysis/context.js +2 -4
- package/dist/domain/analysis/context.js.map +1 -1
- package/dist/domain/analysis/dependencies.d.ts +49 -0
- package/dist/domain/analysis/dependencies.d.ts.map +1 -1
- package/dist/domain/analysis/dependencies.js +145 -0
- package/dist/domain/analysis/dependencies.js.map +1 -1
- package/dist/domain/analysis/diff-impact.d.ts +76 -0
- package/dist/domain/analysis/diff-impact.d.ts.map +1 -0
- package/dist/domain/analysis/diff-impact.js +282 -0
- package/dist/domain/analysis/diff-impact.js.map +1 -0
- package/dist/domain/analysis/exports.d.ts.map +1 -1
- package/dist/domain/analysis/exports.js +0 -1
- package/dist/domain/analysis/exports.js.map +1 -1
- package/dist/domain/analysis/fn-impact.d.ts +66 -0
- package/dist/domain/analysis/fn-impact.d.ts.map +1 -0
- package/dist/domain/analysis/fn-impact.js +189 -0
- package/dist/domain/analysis/fn-impact.js.map +1 -0
- package/dist/domain/analysis/impact.d.ts +8 -148
- package/dist/domain/analysis/impact.d.ts.map +1 -1
- package/dist/domain/analysis/impact.js +8 -568
- package/dist/domain/analysis/impact.js.map +1 -1
- package/dist/domain/analysis/module-map.d.ts.map +1 -1
- package/dist/domain/analysis/module-map.js +1 -3
- package/dist/domain/analysis/module-map.js.map +1 -1
- package/dist/domain/graph/builder/context.d.ts +2 -3
- package/dist/domain/graph/builder/context.d.ts.map +1 -1
- package/dist/domain/graph/builder/context.js.map +1 -1
- package/dist/domain/graph/builder/helpers.d.ts +4 -5
- package/dist/domain/graph/builder/helpers.d.ts.map +1 -1
- package/dist/domain/graph/builder/helpers.js +1 -2
- package/dist/domain/graph/builder/helpers.js.map +1 -1
- package/dist/domain/graph/builder/incremental.d.ts +2 -3
- package/dist/domain/graph/builder/incremental.d.ts.map +1 -1
- package/dist/domain/graph/builder/incremental.js.map +1 -1
- package/dist/domain/graph/builder/pipeline.d.ts.map +1 -1
- package/dist/domain/graph/builder/pipeline.js +6 -0
- package/dist/domain/graph/builder/pipeline.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-edges.js +12 -2
- package/dist/domain/graph/builder/stages/build-edges.js.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/build-structure.js +155 -59
- package/dist/domain/graph/builder/stages/build-structure.js.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/detect-changes.js +6 -6
- package/dist/domain/graph/builder/stages/detect-changes.js.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/finalize.js +85 -61
- package/dist/domain/graph/builder/stages/finalize.js.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/insert-nodes.js.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.d.ts.map +1 -1
- package/dist/domain/graph/builder/stages/resolve-imports.js +58 -11
- package/dist/domain/graph/builder/stages/resolve-imports.js.map +1 -1
- package/dist/domain/graph/cycles.js +2 -2
- package/dist/domain/graph/cycles.js.map +1 -1
- package/dist/domain/graph/resolve.d.ts.map +1 -1
- package/dist/domain/graph/resolve.js +10 -8
- package/dist/domain/graph/resolve.js.map +1 -1
- package/dist/domain/graph/watcher.d.ts.map +1 -1
- package/dist/domain/graph/watcher.js +1 -3
- package/dist/domain/graph/watcher.js.map +1 -1
- package/dist/domain/parser.d.ts.map +1 -1
- package/dist/domain/parser.js +11 -12
- package/dist/domain/parser.js.map +1 -1
- package/dist/domain/queries.d.ts +3 -2
- package/dist/domain/queries.d.ts.map +1 -1
- package/dist/domain/queries.js +3 -2
- package/dist/domain/queries.js.map +1 -1
- package/dist/domain/search/generator.d.ts.map +1 -1
- package/dist/domain/search/generator.js.map +1 -1
- package/dist/extractors/csharp.js +2 -2
- package/dist/extractors/csharp.js.map +1 -1
- package/dist/extractors/go.js +2 -2
- package/dist/extractors/go.js.map +1 -1
- package/dist/extractors/helpers.d.ts +5 -0
- package/dist/extractors/helpers.d.ts.map +1 -1
- package/dist/extractors/helpers.js +5 -0
- package/dist/extractors/helpers.js.map +1 -1
- package/dist/extractors/javascript.js +58 -60
- package/dist/extractors/javascript.js.map +1 -1
- package/dist/extractors/php.js +2 -2
- package/dist/extractors/php.js.map +1 -1
- package/dist/extractors/python.js +2 -2
- package/dist/extractors/python.js.map +1 -1
- package/dist/extractors/rust.js +2 -2
- package/dist/extractors/rust.js.map +1 -1
- package/dist/features/audit.d.ts.map +1 -1
- package/dist/features/audit.js +1 -2
- package/dist/features/audit.js.map +1 -1
- package/dist/features/branch-compare.d.ts.map +1 -1
- package/dist/features/branch-compare.js +2 -3
- package/dist/features/branch-compare.js.map +1 -1
- package/dist/features/cfg.d.ts.map +1 -1
- package/dist/features/cfg.js +2 -4
- package/dist/features/cfg.js.map +1 -1
- package/dist/features/cochange.js +4 -4
- package/dist/features/cochange.js.map +1 -1
- package/dist/features/communities.js +4 -4
- package/dist/features/communities.js.map +1 -1
- package/dist/features/complexity-query.d.ts +37 -0
- package/dist/features/complexity-query.d.ts.map +1 -0
- package/dist/features/complexity-query.js +263 -0
- package/dist/features/complexity-query.js.map +1 -0
- package/dist/features/complexity.d.ts +2 -30
- package/dist/features/complexity.d.ts.map +1 -1
- package/dist/features/complexity.js +7 -261
- package/dist/features/complexity.js.map +1 -1
- package/dist/features/dataflow.d.ts.map +1 -1
- package/dist/features/dataflow.js +8 -24
- package/dist/features/dataflow.js.map +1 -1
- package/dist/features/export.d.ts +7 -8
- package/dist/features/export.d.ts.map +1 -1
- package/dist/features/export.js.map +1 -1
- package/dist/features/flow.d.ts.map +1 -1
- package/dist/features/flow.js.map +1 -1
- package/dist/features/graph-enrichment.d.ts.map +1 -1
- package/dist/features/graph-enrichment.js +1 -3
- package/dist/features/graph-enrichment.js.map +1 -1
- package/dist/features/manifesto.js +8 -8
- package/dist/features/manifesto.js.map +1 -1
- package/dist/features/snapshot.d.ts.map +1 -1
- package/dist/features/snapshot.js +0 -1
- package/dist/features/snapshot.js.map +1 -1
- package/dist/features/structure-query.d.ts +76 -0
- package/dist/features/structure-query.d.ts.map +1 -0
- package/dist/features/structure-query.js +245 -0
- package/dist/features/structure-query.js.map +1 -0
- package/dist/features/structure.d.ts +12 -67
- package/dist/features/structure.d.ts.map +1 -1
- package/dist/features/structure.js +188 -244
- package/dist/features/structure.js.map +1 -1
- package/dist/features/triage.js +2 -2
- package/dist/features/triage.js.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.d.ts.map +1 -1
- package/dist/graph/algorithms/leiden/adapter.js +2 -9
- package/dist/graph/algorithms/leiden/adapter.js.map +1 -1
- package/dist/graph/classifiers/roles.d.ts +5 -1
- package/dist/graph/classifiers/roles.d.ts.map +1 -1
- package/dist/graph/classifiers/roles.js +20 -12
- package/dist/graph/classifiers/roles.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/config.d.ts.map +1 -1
- package/dist/infrastructure/config.js +12 -11
- package/dist/infrastructure/config.js.map +1 -1
- package/dist/infrastructure/native.d.ts.map +1 -1
- package/dist/infrastructure/native.js +7 -3
- package/dist/infrastructure/native.js.map +1 -1
- package/dist/infrastructure/registry.d.ts.map +1 -1
- package/dist/infrastructure/registry.js +1 -1
- package/dist/infrastructure/registry.js.map +1 -1
- package/dist/infrastructure/update-check.js +3 -3
- package/dist/infrastructure/update-check.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +2 -8
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool-registry.d.ts.map +1 -1
- package/dist/mcp/tool-registry.js +9 -4
- package/dist/mcp/tool-registry.js.map +1 -1
- package/dist/mcp/tools/audit.js +1 -1
- package/dist/mcp/tools/audit.js.map +1 -1
- package/dist/mcp/tools/cfg.js +1 -1
- package/dist/mcp/tools/cfg.js.map +1 -1
- package/dist/mcp/tools/check.js +2 -2
- package/dist/mcp/tools/check.js.map +1 -1
- package/dist/mcp/tools/dataflow.js +2 -2
- package/dist/mcp/tools/dataflow.js.map +1 -1
- package/dist/mcp/tools/export-graph.js +1 -1
- package/dist/mcp/tools/export-graph.js.map +1 -1
- package/dist/mcp/tools/index.d.ts.map +1 -1
- package/dist/mcp/tools/index.js.map +1 -1
- package/dist/mcp/tools/path.d.ts +1 -0
- package/dist/mcp/tools/path.d.ts.map +1 -1
- package/dist/mcp/tools/path.js +9 -0
- package/dist/mcp/tools/path.js.map +1 -1
- package/dist/mcp/tools/query.js +1 -1
- package/dist/mcp/tools/query.js.map +1 -1
- package/dist/mcp/tools/semantic-search.js +1 -1
- package/dist/mcp/tools/semantic-search.js.map +1 -1
- package/dist/mcp/tools/sequence.js +1 -1
- package/dist/mcp/tools/sequence.js.map +1 -1
- package/dist/mcp/tools/symbol-children.js +1 -1
- package/dist/mcp/tools/symbol-children.js.map +1 -1
- package/dist/mcp/tools/triage.js +1 -1
- package/dist/mcp/tools/triage.js.map +1 -1
- package/dist/presentation/audit.d.ts.map +1 -1
- package/dist/presentation/audit.js +0 -1
- package/dist/presentation/audit.js.map +1 -1
- package/dist/presentation/diff-impact-mermaid.d.ts +11 -0
- package/dist/presentation/diff-impact-mermaid.d.ts.map +1 -0
- package/dist/presentation/diff-impact-mermaid.js +105 -0
- package/dist/presentation/diff-impact-mermaid.js.map +1 -0
- package/dist/presentation/flow.d.ts.map +1 -1
- package/dist/presentation/flow.js +0 -2
- package/dist/presentation/flow.js.map +1 -1
- package/dist/presentation/manifesto.d.ts.map +1 -1
- package/dist/presentation/manifesto.js +0 -1
- package/dist/presentation/manifesto.js.map +1 -1
- package/dist/presentation/queries-cli/inspect.d.ts.map +1 -1
- package/dist/presentation/queries-cli/inspect.js.map +1 -1
- package/dist/presentation/queries-cli/path.d.ts.map +1 -1
- package/dist/presentation/queries-cli/path.js +45 -1
- package/dist/presentation/queries-cli/path.js.map +1 -1
- package/dist/presentation/result-formatter.d.ts.map +1 -1
- package/dist/presentation/result-formatter.js +1 -3
- package/dist/presentation/result-formatter.js.map +1 -1
- package/dist/presentation/sequence.d.ts.map +1 -1
- package/dist/presentation/sequence.js +0 -1
- package/dist/presentation/sequence.js.map +1 -1
- package/dist/presentation/structure.d.ts.map +1 -1
- package/dist/presentation/structure.js.map +1 -1
- package/dist/presentation/triage.d.ts.map +1 -1
- package/dist/presentation/triage.js +0 -1
- package/dist/presentation/triage.js.map +1 -1
- package/dist/shared/constants.d.ts +9 -3
- package/dist/shared/constants.d.ts.map +1 -1
- package/dist/shared/constants.js +6 -3
- package/dist/shared/constants.js.map +1 -1
- package/dist/shared/errors.d.ts +2 -0
- package/dist/shared/errors.d.ts.map +1 -1
- package/dist/shared/errors.js +4 -0
- package/dist/shared/errors.js.map +1 -1
- package/dist/shared/version.d.ts +2 -0
- package/dist/shared/version.d.ts.map +1 -0
- package/dist/shared/version.js +5 -0
- package/dist/shared/version.js.map +1 -0
- package/dist/types.d.ts +2 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -7
- package/src/ast-analysis/engine.ts +3 -9
- package/src/ast-analysis/shared.ts +0 -1
- package/src/ast-analysis/visitors/cfg-conditionals.ts +227 -0
- package/src/ast-analysis/visitors/cfg-loops.ts +136 -0
- package/src/ast-analysis/visitors/cfg-shared.ts +196 -0
- package/src/ast-analysis/visitors/cfg-try-catch.ts +142 -0
- package/src/ast-analysis/visitors/cfg-visitor.ts +34 -655
- package/src/ast-analysis/visitors/complexity-visitor.ts +0 -1
- package/src/ast-analysis/visitors/dataflow-visitor.ts +0 -1
- package/src/cli/commands/batch.ts +4 -3
- package/src/cli/commands/branch-compare.ts +1 -1
- package/src/cli/commands/build.ts +1 -1
- package/src/cli/commands/info.ts +1 -2
- package/src/cli/commands/path.ts +7 -2
- package/src/cli/commands/plot.ts +2 -2
- package/src/cli/commands/watch.ts +1 -1
- package/src/cli/index.ts +2 -2
- package/src/cli/shared/open-graph.ts +2 -2
- package/src/cli/types.ts +1 -1
- package/src/cli.ts +2 -3
- package/src/db/connection.ts +97 -13
- package/src/db/index.ts +2 -0
- package/src/db/migrations.ts +7 -0
- package/src/domain/analysis/brief.ts +0 -1
- package/src/domain/analysis/context.ts +2 -6
- package/src/domain/analysis/dependencies.ts +165 -0
- package/src/domain/analysis/diff-impact.ts +354 -0
- package/src/domain/analysis/exports.ts +0 -2
- package/src/domain/analysis/fn-impact.ts +241 -0
- package/src/domain/analysis/impact.ts +8 -718
- package/src/domain/analysis/module-map.ts +1 -5
- package/src/domain/graph/builder/context.ts +2 -2
- package/src/domain/graph/builder/helpers.ts +14 -11
- package/src/domain/graph/builder/incremental.ts +33 -28
- package/src/domain/graph/builder/pipeline.ts +8 -0
- package/src/domain/graph/builder/stages/build-edges.ts +17 -4
- package/src/domain/graph/builder/stages/build-structure.ts +205 -76
- package/src/domain/graph/builder/stages/detect-changes.ts +11 -12
- package/src/domain/graph/builder/stages/finalize.ts +100 -81
- package/src/domain/graph/builder/stages/insert-nodes.ts +12 -8
- package/src/domain/graph/builder/stages/resolve-imports.ts +75 -10
- package/src/domain/graph/cycles.ts +2 -2
- package/src/domain/graph/resolve.ts +14 -8
- package/src/domain/graph/watcher.ts +2 -4
- package/src/domain/parser.ts +11 -13
- package/src/domain/queries.ts +2 -2
- package/src/domain/search/generator.ts +3 -4
- package/src/extractors/csharp.ts +2 -2
- package/src/extractors/go.ts +2 -2
- package/src/extractors/helpers.ts +6 -0
- package/src/extractors/javascript.ts +58 -61
- package/src/extractors/php.ts +2 -2
- package/src/extractors/python.ts +2 -2
- package/src/extractors/rust.ts +2 -2
- package/src/features/audit.ts +1 -2
- package/src/features/branch-compare.ts +3 -9
- package/src/features/cfg.ts +2 -4
- package/src/features/cochange.ts +4 -4
- package/src/features/communities.ts +4 -4
- package/src/features/complexity-query.ts +370 -0
- package/src/features/complexity.ts +6 -365
- package/src/features/dataflow.ts +48 -70
- package/src/features/export.ts +12 -16
- package/src/features/flow.ts +0 -1
- package/src/features/graph-enrichment.ts +1 -3
- package/src/features/manifesto.ts +8 -8
- package/src/features/snapshot.ts +1 -2
- package/src/features/structure-query.ts +387 -0
- package/src/features/structure.ts +231 -376
- package/src/features/triage.ts +2 -2
- package/src/graph/algorithms/leiden/adapter.ts +2 -9
- package/src/graph/classifiers/roles.ts +22 -13
- package/src/index.ts +1 -0
- package/src/infrastructure/config.ts +12 -13
- package/src/infrastructure/native.ts +7 -3
- package/src/infrastructure/registry.ts +1 -1
- package/src/infrastructure/update-check.ts +3 -3
- package/src/mcp/server.ts +2 -10
- package/src/mcp/tool-registry.ts +11 -4
- package/src/mcp/tools/audit.ts +1 -1
- package/src/mcp/tools/cfg.ts +1 -1
- package/src/mcp/tools/check.ts +2 -2
- package/src/mcp/tools/dataflow.ts +2 -2
- package/src/mcp/tools/export-graph.ts +1 -1
- package/src/mcp/tools/index.ts +0 -1
- package/src/mcp/tools/path.ts +10 -0
- package/src/mcp/tools/query.ts +1 -1
- package/src/mcp/tools/semantic-search.ts +1 -1
- package/src/mcp/tools/sequence.ts +1 -1
- package/src/mcp/tools/symbol-children.ts +1 -1
- package/src/mcp/tools/triage.ts +1 -1
- package/src/presentation/audit.ts +0 -1
- package/src/presentation/diff-impact-mermaid.ts +127 -0
- package/src/presentation/flow.ts +0 -2
- package/src/presentation/manifesto.ts +0 -1
- package/src/presentation/queries-cli/inspect.ts +0 -1
- package/src/presentation/queries-cli/path.ts +71 -1
- package/src/presentation/result-formatter.ts +0 -1
- package/src/presentation/sequence.ts +0 -1
- package/src/presentation/structure.ts +0 -12
- package/src/presentation/triage.ts +0 -1
- package/src/shared/constants.ts +33 -19
- package/src/shared/errors.ts +5 -0
- package/src/shared/version.ts +10 -0
- package/src/types.ts +4 -10
- package/src/vendor.d.ts +0 -39
|
@@ -12,15 +12,10 @@ import {
|
|
|
12
12
|
} from '../ast-analysis/shared.js';
|
|
13
13
|
import { walkWithVisitors } from '../ast-analysis/visitor.js';
|
|
14
14
|
import { createComplexityVisitor } from '../ast-analysis/visitors/complexity-visitor.js';
|
|
15
|
-
import { getFunctionNodeId
|
|
16
|
-
import { buildFileConditionSQL } from '../db/query-builder.js';
|
|
17
|
-
import { loadConfig } from '../infrastructure/config.js';
|
|
15
|
+
import { getFunctionNodeId } from '../db/index.js';
|
|
18
16
|
import { debug, info } from '../infrastructure/logger.js';
|
|
19
|
-
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
20
|
-
import { paginateResult } from '../shared/paginate.js';
|
|
21
17
|
import type {
|
|
22
18
|
BetterSqlite3Database,
|
|
23
|
-
CodegraphConfig,
|
|
24
19
|
ComplexityRules,
|
|
25
20
|
HalsteadDerivedMetrics,
|
|
26
21
|
HalsteadRules,
|
|
@@ -305,8 +300,7 @@ export function computeAllMetrics(
|
|
|
305
300
|
nestingNodeTypes: nestingNodes,
|
|
306
301
|
});
|
|
307
302
|
|
|
308
|
-
|
|
309
|
-
const rawResult = results['complexity'] as {
|
|
303
|
+
const rawResult = results.complexity as {
|
|
310
304
|
cognitive: number;
|
|
311
305
|
cyclomatic: number;
|
|
312
306
|
maxNesting: number;
|
|
@@ -388,7 +382,6 @@ function getTreeForFile(
|
|
|
388
382
|
rootDir: string,
|
|
389
383
|
parsers: unknown,
|
|
390
384
|
extToLang: Map<string, string> | null,
|
|
391
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic import from parser.js
|
|
392
385
|
getParser: (parsers: any, absPath: string) => any,
|
|
393
386
|
): { tree: { rootNode: TreeSitterNode }; langId: string } | null {
|
|
394
387
|
let tree = symbols._tree;
|
|
@@ -556,359 +549,7 @@ export async function buildComplexityMetrics(
|
|
|
556
549
|
}
|
|
557
550
|
}
|
|
558
551
|
|
|
559
|
-
// ─── Query-Time Functions
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
kind: string;
|
|
564
|
-
file: string;
|
|
565
|
-
line: number;
|
|
566
|
-
end_line: number | null;
|
|
567
|
-
cognitive: number;
|
|
568
|
-
cyclomatic: number;
|
|
569
|
-
max_nesting: number;
|
|
570
|
-
loc: number;
|
|
571
|
-
sloc: number;
|
|
572
|
-
maintainability_index: number;
|
|
573
|
-
halstead_volume: number;
|
|
574
|
-
halstead_difficulty: number;
|
|
575
|
-
halstead_effort: number;
|
|
576
|
-
halstead_bugs: number;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
export function complexityData(
|
|
580
|
-
customDbPath?: string,
|
|
581
|
-
opts: {
|
|
582
|
-
target?: string;
|
|
583
|
-
limit?: number;
|
|
584
|
-
sort?: string;
|
|
585
|
-
aboveThreshold?: boolean;
|
|
586
|
-
file?: string;
|
|
587
|
-
kind?: string;
|
|
588
|
-
noTests?: boolean;
|
|
589
|
-
config?: CodegraphConfig;
|
|
590
|
-
offset?: number;
|
|
591
|
-
} = {},
|
|
592
|
-
): Record<string, unknown> {
|
|
593
|
-
const db = openReadonlyOrFail(customDbPath);
|
|
594
|
-
try {
|
|
595
|
-
const sort = opts.sort || 'cognitive';
|
|
596
|
-
const noTests = opts.noTests || false;
|
|
597
|
-
const aboveThreshold = opts.aboveThreshold || false;
|
|
598
|
-
const target = opts.target || null;
|
|
599
|
-
const fileFilter = opts.file || null;
|
|
600
|
-
const kindFilter = opts.kind || null;
|
|
601
|
-
|
|
602
|
-
// Load thresholds from config
|
|
603
|
-
const config = opts.config || loadConfig(process.cwd());
|
|
604
|
-
// biome-ignore lint/suspicious/noExplicitAny: thresholds come from config with dynamic keys
|
|
605
|
-
const thresholds: any = config.manifesto?.rules || {
|
|
606
|
-
cognitive: { warn: 15, fail: null },
|
|
607
|
-
cyclomatic: { warn: 10, fail: null },
|
|
608
|
-
maxNesting: { warn: 4, fail: null },
|
|
609
|
-
maintainabilityIndex: { warn: 20, fail: null },
|
|
610
|
-
};
|
|
611
|
-
|
|
612
|
-
// Build query
|
|
613
|
-
let where = "WHERE n.kind IN ('function','method')";
|
|
614
|
-
const params: unknown[] = [];
|
|
615
|
-
|
|
616
|
-
if (noTests) {
|
|
617
|
-
where += ` AND n.file NOT LIKE '%.test.%'
|
|
618
|
-
AND n.file NOT LIKE '%.spec.%'
|
|
619
|
-
AND n.file NOT LIKE '%__test__%'
|
|
620
|
-
AND n.file NOT LIKE '%__tests__%'
|
|
621
|
-
AND n.file NOT LIKE '%.stories.%'`;
|
|
622
|
-
}
|
|
623
|
-
if (target) {
|
|
624
|
-
where += ' AND n.name LIKE ?';
|
|
625
|
-
params.push(`%${target}%`);
|
|
626
|
-
}
|
|
627
|
-
{
|
|
628
|
-
const fc = buildFileConditionSQL(fileFilter as string, 'n.file');
|
|
629
|
-
where += fc.sql;
|
|
630
|
-
params.push(...fc.params);
|
|
631
|
-
}
|
|
632
|
-
if (kindFilter) {
|
|
633
|
-
where += ' AND n.kind = ?';
|
|
634
|
-
params.push(kindFilter);
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
const isValidThreshold = (v: unknown): v is number =>
|
|
638
|
-
typeof v === 'number' && Number.isFinite(v);
|
|
639
|
-
|
|
640
|
-
let having = '';
|
|
641
|
-
if (aboveThreshold) {
|
|
642
|
-
const conditions: string[] = [];
|
|
643
|
-
if (isValidThreshold(thresholds.cognitive?.warn)) {
|
|
644
|
-
conditions.push(`fc.cognitive >= ${thresholds.cognitive.warn}`);
|
|
645
|
-
}
|
|
646
|
-
if (isValidThreshold(thresholds.cyclomatic?.warn)) {
|
|
647
|
-
conditions.push(`fc.cyclomatic >= ${thresholds.cyclomatic.warn}`);
|
|
648
|
-
}
|
|
649
|
-
if (isValidThreshold(thresholds.maxNesting?.warn)) {
|
|
650
|
-
conditions.push(`fc.max_nesting >= ${thresholds.maxNesting.warn}`);
|
|
651
|
-
}
|
|
652
|
-
if (isValidThreshold(thresholds.maintainabilityIndex?.warn)) {
|
|
653
|
-
conditions.push(
|
|
654
|
-
`fc.maintainability_index > 0 AND fc.maintainability_index <= ${thresholds.maintainabilityIndex.warn}`,
|
|
655
|
-
);
|
|
656
|
-
}
|
|
657
|
-
if (conditions.length > 0) {
|
|
658
|
-
having = `AND (${conditions.join(' OR ')})`;
|
|
659
|
-
}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
const orderMap: Record<string, string> = {
|
|
663
|
-
cognitive: 'fc.cognitive DESC',
|
|
664
|
-
cyclomatic: 'fc.cyclomatic DESC',
|
|
665
|
-
nesting: 'fc.max_nesting DESC',
|
|
666
|
-
mi: 'fc.maintainability_index ASC',
|
|
667
|
-
volume: 'fc.halstead_volume DESC',
|
|
668
|
-
effort: 'fc.halstead_effort DESC',
|
|
669
|
-
bugs: 'fc.halstead_bugs DESC',
|
|
670
|
-
loc: 'fc.loc DESC',
|
|
671
|
-
};
|
|
672
|
-
const orderBy = orderMap[sort] || 'fc.cognitive DESC';
|
|
673
|
-
|
|
674
|
-
let rows: ComplexityRow[];
|
|
675
|
-
try {
|
|
676
|
-
rows = db
|
|
677
|
-
.prepare<ComplexityRow>(
|
|
678
|
-
`SELECT n.name, n.kind, n.file, n.line, n.end_line,
|
|
679
|
-
fc.cognitive, fc.cyclomatic, fc.max_nesting,
|
|
680
|
-
fc.loc, fc.sloc, fc.maintainability_index,
|
|
681
|
-
fc.halstead_volume, fc.halstead_difficulty, fc.halstead_effort, fc.halstead_bugs
|
|
682
|
-
FROM function_complexity fc
|
|
683
|
-
JOIN nodes n ON fc.node_id = n.id
|
|
684
|
-
${where} ${having}
|
|
685
|
-
ORDER BY ${orderBy}`,
|
|
686
|
-
)
|
|
687
|
-
.all(...params);
|
|
688
|
-
} catch (e: unknown) {
|
|
689
|
-
debug(`complexity query failed (table may not exist): ${(e as Error).message}`);
|
|
690
|
-
// Check if graph has nodes even though complexity table is missing/empty
|
|
691
|
-
let hasGraph = false;
|
|
692
|
-
try {
|
|
693
|
-
hasGraph = (db.prepare<{ c: number }>('SELECT COUNT(*) as c FROM nodes').get()?.c ?? 0) > 0;
|
|
694
|
-
} catch (e2: unknown) {
|
|
695
|
-
debug(`nodes table check failed: ${(e2 as Error).message}`);
|
|
696
|
-
}
|
|
697
|
-
return { functions: [], summary: null, thresholds, hasGraph };
|
|
698
|
-
}
|
|
699
|
-
|
|
700
|
-
// Post-filter test files if needed (belt-and-suspenders for isTestFile)
|
|
701
|
-
const filtered = noTests ? rows.filter((r) => !isTestFile(r.file)) : rows;
|
|
702
|
-
|
|
703
|
-
const functions = filtered.map((r) => {
|
|
704
|
-
const exceeds: string[] = [];
|
|
705
|
-
if (
|
|
706
|
-
isValidThreshold(thresholds.cognitive?.warn) &&
|
|
707
|
-
r.cognitive >= (thresholds.cognitive?.warn ?? 0)
|
|
708
|
-
)
|
|
709
|
-
exceeds.push('cognitive');
|
|
710
|
-
if (
|
|
711
|
-
isValidThreshold(thresholds.cyclomatic?.warn) &&
|
|
712
|
-
r.cyclomatic >= (thresholds.cyclomatic?.warn ?? 0)
|
|
713
|
-
)
|
|
714
|
-
exceeds.push('cyclomatic');
|
|
715
|
-
if (
|
|
716
|
-
isValidThreshold(thresholds.maxNesting?.warn) &&
|
|
717
|
-
r.max_nesting >= (thresholds.maxNesting?.warn ?? 0)
|
|
718
|
-
)
|
|
719
|
-
exceeds.push('maxNesting');
|
|
720
|
-
if (
|
|
721
|
-
isValidThreshold(thresholds.maintainabilityIndex?.warn) &&
|
|
722
|
-
r.maintainability_index > 0 &&
|
|
723
|
-
r.maintainability_index <= (thresholds.maintainabilityIndex?.warn ?? 0)
|
|
724
|
-
)
|
|
725
|
-
exceeds.push('maintainabilityIndex');
|
|
726
|
-
|
|
727
|
-
return {
|
|
728
|
-
name: r.name,
|
|
729
|
-
kind: r.kind,
|
|
730
|
-
file: r.file,
|
|
731
|
-
line: r.line,
|
|
732
|
-
endLine: r.end_line || null,
|
|
733
|
-
cognitive: r.cognitive,
|
|
734
|
-
cyclomatic: r.cyclomatic,
|
|
735
|
-
maxNesting: r.max_nesting,
|
|
736
|
-
loc: r.loc || 0,
|
|
737
|
-
sloc: r.sloc || 0,
|
|
738
|
-
maintainabilityIndex: r.maintainability_index || 0,
|
|
739
|
-
halstead: {
|
|
740
|
-
volume: r.halstead_volume || 0,
|
|
741
|
-
difficulty: r.halstead_difficulty || 0,
|
|
742
|
-
effort: r.halstead_effort || 0,
|
|
743
|
-
bugs: r.halstead_bugs || 0,
|
|
744
|
-
},
|
|
745
|
-
exceeds: exceeds.length > 0 ? exceeds : undefined,
|
|
746
|
-
};
|
|
747
|
-
});
|
|
748
|
-
|
|
749
|
-
// Summary stats
|
|
750
|
-
let summary: Record<string, unknown> | null = null;
|
|
751
|
-
try {
|
|
752
|
-
const allRows = db
|
|
753
|
-
.prepare<{
|
|
754
|
-
cognitive: number;
|
|
755
|
-
cyclomatic: number;
|
|
756
|
-
max_nesting: number;
|
|
757
|
-
maintainability_index: number;
|
|
758
|
-
}>(
|
|
759
|
-
`SELECT fc.cognitive, fc.cyclomatic, fc.max_nesting, fc.maintainability_index
|
|
760
|
-
FROM function_complexity fc JOIN nodes n ON fc.node_id = n.id
|
|
761
|
-
WHERE n.kind IN ('function','method')
|
|
762
|
-
${noTests ? `AND n.file NOT LIKE '%.test.%' AND n.file NOT LIKE '%.spec.%' AND n.file NOT LIKE '%__test__%' AND n.file NOT LIKE '%__tests__%' AND n.file NOT LIKE '%.stories.%'` : ''}`,
|
|
763
|
-
)
|
|
764
|
-
.all();
|
|
765
|
-
|
|
766
|
-
if (allRows.length > 0) {
|
|
767
|
-
const miValues = allRows.map((r) => r.maintainability_index || 0);
|
|
768
|
-
summary = {
|
|
769
|
-
analyzed: allRows.length,
|
|
770
|
-
avgCognitive: +(allRows.reduce((s, r) => s + r.cognitive, 0) / allRows.length).toFixed(1),
|
|
771
|
-
avgCyclomatic: +(allRows.reduce((s, r) => s + r.cyclomatic, 0) / allRows.length).toFixed(
|
|
772
|
-
1,
|
|
773
|
-
),
|
|
774
|
-
maxCognitive: Math.max(...allRows.map((r) => r.cognitive)),
|
|
775
|
-
maxCyclomatic: Math.max(...allRows.map((r) => r.cyclomatic)),
|
|
776
|
-
avgMI: +(miValues.reduce((s, v) => s + v, 0) / miValues.length).toFixed(1),
|
|
777
|
-
minMI: +Math.min(...miValues).toFixed(1),
|
|
778
|
-
aboveWarn: allRows.filter(
|
|
779
|
-
(r) =>
|
|
780
|
-
(isValidThreshold(thresholds.cognitive?.warn) &&
|
|
781
|
-
r.cognitive >= (thresholds.cognitive?.warn ?? 0)) ||
|
|
782
|
-
(isValidThreshold(thresholds.cyclomatic?.warn) &&
|
|
783
|
-
r.cyclomatic >= (thresholds.cyclomatic?.warn ?? 0)) ||
|
|
784
|
-
(isValidThreshold(thresholds.maxNesting?.warn) &&
|
|
785
|
-
r.max_nesting >= (thresholds.maxNesting?.warn ?? 0)) ||
|
|
786
|
-
(isValidThreshold(thresholds.maintainabilityIndex?.warn) &&
|
|
787
|
-
r.maintainability_index > 0 &&
|
|
788
|
-
r.maintainability_index <= (thresholds.maintainabilityIndex?.warn ?? 0)),
|
|
789
|
-
).length,
|
|
790
|
-
};
|
|
791
|
-
}
|
|
792
|
-
} catch (e: unknown) {
|
|
793
|
-
debug(`complexity summary query failed: ${(e as Error).message}`);
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// When summary is null (no complexity rows), check if graph has nodes
|
|
797
|
-
let hasGraph = false;
|
|
798
|
-
if (summary === null) {
|
|
799
|
-
try {
|
|
800
|
-
hasGraph = (db.prepare<{ c: number }>('SELECT COUNT(*) as c FROM nodes').get()?.c ?? 0) > 0;
|
|
801
|
-
} catch (e: unknown) {
|
|
802
|
-
debug(`nodes table check failed: ${(e as Error).message}`);
|
|
803
|
-
}
|
|
804
|
-
}
|
|
805
|
-
|
|
806
|
-
const base = { functions, summary, thresholds, hasGraph };
|
|
807
|
-
return paginateResult(base, 'functions', { limit: opts.limit, offset: opts.offset });
|
|
808
|
-
} finally {
|
|
809
|
-
db.close();
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
interface IterComplexityRow {
|
|
814
|
-
name: string;
|
|
815
|
-
kind: string;
|
|
816
|
-
file: string;
|
|
817
|
-
line: number;
|
|
818
|
-
end_line: number | null;
|
|
819
|
-
cognitive: number;
|
|
820
|
-
cyclomatic: number;
|
|
821
|
-
max_nesting: number;
|
|
822
|
-
loc: number;
|
|
823
|
-
sloc: number;
|
|
824
|
-
}
|
|
825
|
-
|
|
826
|
-
export function* iterComplexity(
|
|
827
|
-
customDbPath?: string,
|
|
828
|
-
opts: {
|
|
829
|
-
noTests?: boolean;
|
|
830
|
-
file?: string;
|
|
831
|
-
target?: string;
|
|
832
|
-
kind?: string;
|
|
833
|
-
sort?: string;
|
|
834
|
-
} = {},
|
|
835
|
-
): Generator<{
|
|
836
|
-
name: string;
|
|
837
|
-
kind: string;
|
|
838
|
-
file: string;
|
|
839
|
-
line: number;
|
|
840
|
-
endLine: number | null;
|
|
841
|
-
cognitive: number;
|
|
842
|
-
cyclomatic: number;
|
|
843
|
-
maxNesting: number;
|
|
844
|
-
loc: number;
|
|
845
|
-
sloc: number;
|
|
846
|
-
}> {
|
|
847
|
-
const db = openReadonlyOrFail(customDbPath);
|
|
848
|
-
try {
|
|
849
|
-
const noTests = opts.noTests || false;
|
|
850
|
-
const sort = opts.sort || 'cognitive';
|
|
851
|
-
|
|
852
|
-
let where = "WHERE n.kind IN ('function','method')";
|
|
853
|
-
const params: unknown[] = [];
|
|
854
|
-
|
|
855
|
-
if (noTests) {
|
|
856
|
-
where += ` AND n.file NOT LIKE '%.test.%'
|
|
857
|
-
AND n.file NOT LIKE '%.spec.%'
|
|
858
|
-
AND n.file NOT LIKE '%__test__%'
|
|
859
|
-
AND n.file NOT LIKE '%__tests__%'
|
|
860
|
-
AND n.file NOT LIKE '%.stories.%'`;
|
|
861
|
-
}
|
|
862
|
-
if (opts.target) {
|
|
863
|
-
where += ' AND n.name LIKE ?';
|
|
864
|
-
params.push(`%${opts.target}%`);
|
|
865
|
-
}
|
|
866
|
-
{
|
|
867
|
-
const fc = buildFileConditionSQL(opts.file as string, 'n.file');
|
|
868
|
-
where += fc.sql;
|
|
869
|
-
params.push(...fc.params);
|
|
870
|
-
}
|
|
871
|
-
if (opts.kind) {
|
|
872
|
-
where += ' AND n.kind = ?';
|
|
873
|
-
params.push(opts.kind);
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
const orderMap: Record<string, string> = {
|
|
877
|
-
cognitive: 'fc.cognitive DESC',
|
|
878
|
-
cyclomatic: 'fc.cyclomatic DESC',
|
|
879
|
-
nesting: 'fc.max_nesting DESC',
|
|
880
|
-
mi: 'fc.maintainability_index ASC',
|
|
881
|
-
volume: 'fc.halstead_volume DESC',
|
|
882
|
-
effort: 'fc.halstead_effort DESC',
|
|
883
|
-
bugs: 'fc.halstead_bugs DESC',
|
|
884
|
-
loc: 'fc.loc DESC',
|
|
885
|
-
};
|
|
886
|
-
const orderBy = orderMap[sort] || 'fc.cognitive DESC';
|
|
887
|
-
|
|
888
|
-
const stmt = db.prepare<IterComplexityRow>(
|
|
889
|
-
`SELECT n.name, n.kind, n.file, n.line, n.end_line,
|
|
890
|
-
fc.cognitive, fc.cyclomatic, fc.max_nesting, fc.loc, fc.sloc
|
|
891
|
-
FROM function_complexity fc
|
|
892
|
-
JOIN nodes n ON fc.node_id = n.id
|
|
893
|
-
${where}
|
|
894
|
-
ORDER BY ${orderBy}`,
|
|
895
|
-
);
|
|
896
|
-
for (const r of stmt.iterate(...params)) {
|
|
897
|
-
if (noTests && isTestFile(r.file)) continue;
|
|
898
|
-
yield {
|
|
899
|
-
name: r.name,
|
|
900
|
-
kind: r.kind,
|
|
901
|
-
file: r.file,
|
|
902
|
-
line: r.line,
|
|
903
|
-
endLine: r.end_line || null,
|
|
904
|
-
cognitive: r.cognitive,
|
|
905
|
-
cyclomatic: r.cyclomatic,
|
|
906
|
-
maxNesting: r.max_nesting,
|
|
907
|
-
loc: r.loc || 0,
|
|
908
|
-
sloc: r.sloc || 0,
|
|
909
|
-
};
|
|
910
|
-
}
|
|
911
|
-
} finally {
|
|
912
|
-
db.close();
|
|
913
|
-
}
|
|
914
|
-
}
|
|
552
|
+
// ─── Query-Time Functions (re-exported from complexity-query.ts) ──────────
|
|
553
|
+
// Split to separate query-time concerns (DB reads, filtering, pagination)
|
|
554
|
+
// from compute-time concerns (AST traversal, metric algorithms).
|
|
555
|
+
export { complexityData, iterComplexity } from './complexity-query.js';
|
package/src/features/dataflow.ts
CHANGED
|
@@ -65,7 +65,7 @@ export function extractDataflow(
|
|
|
65
65
|
getFunctionName: () => null, // dataflow visitor handles its own name extraction
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
return results
|
|
68
|
+
return results.dataflow as DataflowResult;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// ── Build-Time Helpers ──────────────────────────────────────────────────────
|
|
@@ -79,7 +79,6 @@ interface FileSymbolsDataflow {
|
|
|
79
79
|
|
|
80
80
|
async function initDataflowParsers(
|
|
81
81
|
fileSymbols: Map<string, FileSymbolsDataflow>,
|
|
82
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic import from parser.js
|
|
83
82
|
): Promise<{ parsers: unknown; getParserFn: ((parsers: any, absPath: string) => any) | null }> {
|
|
84
83
|
let needsFallback = false;
|
|
85
84
|
|
|
@@ -94,7 +93,6 @@ async function initDataflowParsers(
|
|
|
94
93
|
}
|
|
95
94
|
|
|
96
95
|
let parsers: unknown = null;
|
|
97
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic import from parser.js
|
|
98
96
|
let getParserFn: ((parsers: any, absPath: string) => any) | null = null;
|
|
99
97
|
|
|
100
98
|
if (needsFallback) {
|
|
@@ -113,7 +111,6 @@ function getDataflowForFile(
|
|
|
113
111
|
rootDir: string,
|
|
114
112
|
extToLang: Map<string, string>,
|
|
115
113
|
parsers: unknown,
|
|
116
|
-
// biome-ignore lint/suspicious/noExplicitAny: dynamic import from parser.js
|
|
117
114
|
getParserFn: ((parsers: any, absPath: string) => any) | null,
|
|
118
115
|
): DataflowResult | null {
|
|
119
116
|
if (symbols.dataflow) return symbols.dataflow;
|
|
@@ -369,74 +366,55 @@ export function dataflowData(
|
|
|
369
366
|
const results = nodes.map((node: NodeRow) => {
|
|
370
367
|
const sym = normalizeSymbol(node, db, hc);
|
|
371
368
|
|
|
372
|
-
const flowsTo = flowsToOut.all(node.id).map(
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
);
|
|
419
|
-
|
|
420
|
-
const mutatesTargets = mutatesOut.all(node.id).map(
|
|
421
|
-
// biome-ignore lint/suspicious/noExplicitAny: raw DB row
|
|
422
|
-
(r: any) => ({
|
|
423
|
-
target: r.target_name,
|
|
424
|
-
expression: r.expression,
|
|
425
|
-
line: r.line,
|
|
426
|
-
}),
|
|
427
|
-
);
|
|
428
|
-
|
|
429
|
-
const mutatedBy = mutatesIn.all(node.id).map(
|
|
430
|
-
// biome-ignore lint/suspicious/noExplicitAny: raw DB row
|
|
431
|
-
(r: any) => ({
|
|
432
|
-
source: r.source_name,
|
|
433
|
-
expression: r.expression,
|
|
434
|
-
line: r.line,
|
|
435
|
-
}),
|
|
436
|
-
);
|
|
369
|
+
const flowsTo = flowsToOut.all(node.id).map((r: any) => ({
|
|
370
|
+
target: r.target_name,
|
|
371
|
+
kind: r.target_kind,
|
|
372
|
+
file: r.target_file,
|
|
373
|
+
line: r.line,
|
|
374
|
+
paramIndex: r.param_index,
|
|
375
|
+
expression: r.expression,
|
|
376
|
+
confidence: r.confidence,
|
|
377
|
+
}));
|
|
378
|
+
|
|
379
|
+
const flowsFrom = flowsToIn.all(node.id).map((r: any) => ({
|
|
380
|
+
source: r.source_name,
|
|
381
|
+
kind: r.source_kind,
|
|
382
|
+
file: r.source_file,
|
|
383
|
+
line: r.line,
|
|
384
|
+
paramIndex: r.param_index,
|
|
385
|
+
expression: r.expression,
|
|
386
|
+
confidence: r.confidence,
|
|
387
|
+
}));
|
|
388
|
+
|
|
389
|
+
const returnConsumers = returnsOut.all(node.id).map((r: any) => ({
|
|
390
|
+
consumer: r.target_name,
|
|
391
|
+
kind: r.target_kind,
|
|
392
|
+
file: r.target_file,
|
|
393
|
+
line: r.line,
|
|
394
|
+
expression: r.expression,
|
|
395
|
+
}));
|
|
396
|
+
|
|
397
|
+
const returnedBy = returnsIn.all(node.id).map((r: any) => ({
|
|
398
|
+
producer: r.source_name,
|
|
399
|
+
kind: r.source_kind,
|
|
400
|
+
file: r.source_file,
|
|
401
|
+
line: r.line,
|
|
402
|
+
expression: r.expression,
|
|
403
|
+
}));
|
|
404
|
+
|
|
405
|
+
const mutatesTargets = mutatesOut.all(node.id).map((r: any) => ({
|
|
406
|
+
target: r.target_name,
|
|
407
|
+
expression: r.expression,
|
|
408
|
+
line: r.line,
|
|
409
|
+
}));
|
|
410
|
+
|
|
411
|
+
const mutatedBy = mutatesIn.all(node.id).map((r: any) => ({
|
|
412
|
+
source: r.source_name,
|
|
413
|
+
expression: r.expression,
|
|
414
|
+
line: r.line,
|
|
415
|
+
}));
|
|
437
416
|
|
|
438
417
|
if (noTests) {
|
|
439
|
-
// biome-ignore lint/suspicious/noExplicitAny: raw DB row results
|
|
440
418
|
const filter = (arr: any[]) => arr.filter((r: any) => !isTestFile(r.file));
|
|
441
419
|
return {
|
|
442
420
|
...sym,
|
package/src/features/export.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
-
import type BetterSqlite3 from 'better-sqlite3';
|
|
3
2
|
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
4
3
|
import {
|
|
5
4
|
renderFileLevelDOT,
|
|
@@ -12,7 +11,7 @@ import {
|
|
|
12
11
|
renderFunctionLevelNeo4jCSV,
|
|
13
12
|
} from '../presentation/export.js';
|
|
14
13
|
import { paginateResult } from '../shared/paginate.js';
|
|
15
|
-
import type { ExportNeo4jCSVResult, ExportOpts } from '../types.js';
|
|
14
|
+
import type { BetterSqlite3Database, ExportNeo4jCSVResult, ExportOpts } from '../types.js';
|
|
16
15
|
|
|
17
16
|
const DEFAULT_MIN_CONFIDENCE = 0.5;
|
|
18
17
|
|
|
@@ -73,7 +72,7 @@ interface FunctionLevelLoadOpts {
|
|
|
73
72
|
* Load file-level edges from DB with filtering.
|
|
74
73
|
*/
|
|
75
74
|
function loadFileLevelEdges(
|
|
76
|
-
db:
|
|
75
|
+
db: BetterSqlite3Database,
|
|
77
76
|
{
|
|
78
77
|
noTests,
|
|
79
78
|
minConfidence,
|
|
@@ -108,7 +107,7 @@ function loadFileLevelEdges(
|
|
|
108
107
|
* Returns the maximal field set needed by any serializer.
|
|
109
108
|
*/
|
|
110
109
|
function loadFunctionLevelEdges(
|
|
111
|
-
db:
|
|
110
|
+
db: BetterSqlite3Database,
|
|
112
111
|
{ noTests, minConfidence, limit }: FunctionLevelLoadOpts,
|
|
113
112
|
): { edges: FunctionLevelEdge[]; totalEdges: number } {
|
|
114
113
|
const minConf = minConfidence ?? DEFAULT_MIN_CONFIDENCE;
|
|
@@ -141,7 +140,7 @@ function loadFunctionLevelEdges(
|
|
|
141
140
|
* Load directory groupings for file-level graphs.
|
|
142
141
|
* Uses DB directory nodes if available, falls back to path.dirname().
|
|
143
142
|
*/
|
|
144
|
-
function loadDirectoryGroups(db:
|
|
143
|
+
function loadDirectoryGroups(db: BetterSqlite3Database, allFiles: Set<string>): DirectoryGroup[] {
|
|
145
144
|
const hasDirectoryNodes =
|
|
146
145
|
(db.prepare("SELECT COUNT(*) as c FROM nodes WHERE kind = 'directory'").get() as { c: number })
|
|
147
146
|
.c > 0;
|
|
@@ -196,7 +195,7 @@ function loadDirectoryGroups(db: BetterSqlite3.Database, allFiles: Set<string>):
|
|
|
196
195
|
* Load directory groupings for Mermaid file-level graphs (simplified — no cohesion, string arrays).
|
|
197
196
|
*/
|
|
198
197
|
function loadMermaidDirectoryGroups(
|
|
199
|
-
db:
|
|
198
|
+
db: BetterSqlite3Database,
|
|
200
199
|
allFiles: Set<string>,
|
|
201
200
|
): MermaidDirectoryGroup[] {
|
|
202
201
|
const hasDirectoryNodes =
|
|
@@ -239,10 +238,7 @@ function loadMermaidDirectoryGroups(
|
|
|
239
238
|
/**
|
|
240
239
|
* Load node roles for Mermaid function-level styling.
|
|
241
240
|
*/
|
|
242
|
-
function loadNodeRoles(
|
|
243
|
-
db: BetterSqlite3.Database,
|
|
244
|
-
edges: FunctionLevelEdge[],
|
|
245
|
-
): Map<string, string> {
|
|
241
|
+
function loadNodeRoles(db: BetterSqlite3Database, edges: FunctionLevelEdge[]): Map<string, string> {
|
|
246
242
|
const roles = new Map<string, string>();
|
|
247
243
|
const seen = new Set<string>();
|
|
248
244
|
for (const e of edges) {
|
|
@@ -267,7 +263,7 @@ function loadNodeRoles(
|
|
|
267
263
|
/**
|
|
268
264
|
* Export the dependency graph in DOT (Graphviz) format.
|
|
269
265
|
*/
|
|
270
|
-
export function exportDOT(db:
|
|
266
|
+
export function exportDOT(db: BetterSqlite3Database, opts: ExportOpts = {}): string {
|
|
271
267
|
const fileLevel = opts.fileLevel !== false;
|
|
272
268
|
const noTests = opts.noTests || false;
|
|
273
269
|
const minConfidence = opts.minConfidence;
|
|
@@ -292,7 +288,7 @@ export function exportDOT(db: BetterSqlite3.Database, opts: ExportOpts = {}): st
|
|
|
292
288
|
* Export the dependency graph in Mermaid format.
|
|
293
289
|
*/
|
|
294
290
|
export function exportMermaid(
|
|
295
|
-
db:
|
|
291
|
+
db: BetterSqlite3Database,
|
|
296
292
|
opts: ExportOpts & { direction?: string } = {},
|
|
297
293
|
): string {
|
|
298
294
|
const fileLevel = opts.fileLevel !== false;
|
|
@@ -332,7 +328,7 @@ export function exportMermaid(
|
|
|
332
328
|
* Export as JSON adjacency list.
|
|
333
329
|
*/
|
|
334
330
|
export function exportJSON(
|
|
335
|
-
db:
|
|
331
|
+
db: BetterSqlite3Database,
|
|
336
332
|
opts: ExportOpts = {},
|
|
337
333
|
): { nodes: unknown[]; edges: unknown[] } {
|
|
338
334
|
const noTests = opts.noTests || false;
|
|
@@ -366,7 +362,7 @@ export function exportJSON(
|
|
|
366
362
|
/**
|
|
367
363
|
* Export the dependency graph in GraphML (XML) format.
|
|
368
364
|
*/
|
|
369
|
-
export function exportGraphML(db:
|
|
365
|
+
export function exportGraphML(db: BetterSqlite3Database, opts: ExportOpts = {}): string {
|
|
370
366
|
const fileLevel = opts.fileLevel !== false;
|
|
371
367
|
const noTests = opts.noTests || false;
|
|
372
368
|
const minConfidence = opts.minConfidence;
|
|
@@ -385,7 +381,7 @@ export function exportGraphML(db: BetterSqlite3.Database, opts: ExportOpts = {})
|
|
|
385
381
|
* Export the dependency graph in TinkerPop GraphSON v3 format.
|
|
386
382
|
*/
|
|
387
383
|
export function exportGraphSON(
|
|
388
|
-
db:
|
|
384
|
+
db: BetterSqlite3Database,
|
|
389
385
|
opts: ExportOpts = {},
|
|
390
386
|
): { vertices: unknown[]; edges: unknown[] } {
|
|
391
387
|
const noTests = opts.noTests || false;
|
|
@@ -459,7 +455,7 @@ export function exportGraphSON(
|
|
|
459
455
|
* Returns { nodes: string, relationships: string }.
|
|
460
456
|
*/
|
|
461
457
|
export function exportNeo4jCSV(
|
|
462
|
-
db:
|
|
458
|
+
db: BetterSqlite3Database,
|
|
463
459
|
opts: ExportOpts = {},
|
|
464
460
|
): ExportNeo4jCSVResult {
|
|
465
461
|
const fileLevel = opts.fileLevel !== false;
|
package/src/features/flow.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { openReadonlyOrFail } from '../db/index.js';
|
|
|
9
9
|
import { CORE_SYMBOL_KINDS, findMatchingNodes } from '../domain/queries.js';
|
|
10
10
|
import { isTestFile } from '../infrastructure/test-filter.js';
|
|
11
11
|
import { paginateResult } from '../shared/paginate.js';
|
|
12
|
-
import type { BetterSqlite3Database } from '../types.js';
|
|
13
12
|
import { FRAMEWORK_ENTRY_PREFIXES } from './structure.js';
|
|
14
13
|
|
|
15
14
|
export function entryPointType(name: string): 'route' | 'event' | 'command' | 'exported' | null {
|
|
@@ -356,9 +356,7 @@ function prepareFileLevelData(
|
|
|
356
356
|
const color: string =
|
|
357
357
|
cfg.colorBy === 'community' && community !== null
|
|
358
358
|
? COMMUNITY_COLORS[community % COMMUNITY_COLORS.length] || '#ccc'
|
|
359
|
-
: cfg.nodeColors?.
|
|
360
|
-
(DEFAULT_NODE_COLORS as Record<string, string>)['file'] ||
|
|
361
|
-
'#ccc';
|
|
359
|
+
: cfg.nodeColors?.file || (DEFAULT_NODE_COLORS as Record<string, string>).file || '#ccc';
|
|
362
360
|
|
|
363
361
|
return {
|
|
364
362
|
id,
|