kirograph 0.17.0 → 0.19.0
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/LICENSE +1 -1
- package/README.md +103 -1822
- package/dist/architecture/layers/dart.js +112 -0
- package/dist/architecture/layers/dart.js.map +7 -0
- package/dist/architecture/layers/index.js +3 -1
- package/dist/architecture/layers/index.js.map +2 -2
- package/dist/bin/banner.js +74 -6
- package/dist/bin/banner.js.map +2 -2
- package/dist/bin/commands/attack-surface.js +157 -0
- package/dist/bin/commands/attack-surface.js.map +7 -0
- package/dist/bin/commands/benchmark.js +206 -0
- package/dist/bin/commands/benchmark.js.map +7 -0
- package/dist/bin/commands/budget.js +70 -0
- package/dist/bin/commands/budget.js.map +7 -0
- package/dist/bin/commands/communities.js +77 -0
- package/dist/bin/commands/communities.js.map +7 -0
- package/dist/bin/commands/dep-confusion.js +119 -0
- package/dist/bin/commands/dep-confusion.js.map +7 -0
- package/dist/bin/commands/export.js +304 -10
- package/dist/bin/commands/export.js.map +2 -2
- package/dist/bin/commands/flows.js +97 -0
- package/dist/bin/commands/flows.js.map +7 -0
- package/dist/bin/commands/help.js +382 -101
- package/dist/bin/commands/help.js.map +2 -2
- package/dist/bin/commands/install.js +90 -8
- package/dist/bin/commands/install.js.map +2 -2
- package/dist/bin/commands/licenses.js +201 -0
- package/dist/bin/commands/licenses.js.map +7 -0
- package/dist/bin/commands/reachability.js +160 -0
- package/dist/bin/commands/reachability.js.map +7 -0
- package/dist/bin/commands/read.js +100 -0
- package/dist/bin/commands/read.js.map +7 -0
- package/dist/bin/commands/refactor.js +116 -0
- package/dist/bin/commands/refactor.js.map +7 -0
- package/dist/bin/commands/remediation.js +133 -0
- package/dist/bin/commands/remediation.js.map +7 -0
- package/dist/bin/commands/sbom.js +76 -0
- package/dist/bin/commands/sbom.js.map +7 -0
- package/dist/bin/commands/security-ci-report.js +267 -0
- package/dist/bin/commands/security-ci-report.js.map +7 -0
- package/dist/bin/commands/security-export.js +1349 -0
- package/dist/bin/commands/security-export.js.map +7 -0
- package/dist/bin/commands/security-flows.js +126 -0
- package/dist/bin/commands/security-flows.js.map +7 -0
- package/dist/bin/commands/security-secrets.js +170 -0
- package/dist/bin/commands/security-secrets.js.map +7 -0
- package/dist/bin/commands/security.js +193 -0
- package/dist/bin/commands/security.js.map +7 -0
- package/dist/bin/commands/staleness.js +144 -0
- package/dist/bin/commands/staleness.js.map +7 -0
- package/dist/bin/commands/status.js +102 -2
- package/dist/bin/commands/status.js.map +2 -2
- package/dist/bin/commands/supply-chain.js +138 -0
- package/dist/bin/commands/supply-chain.js.map +7 -0
- package/dist/bin/commands/uninit.js +109 -60
- package/dist/bin/commands/uninit.js.map +2 -2
- package/dist/bin/commands/vex.js +76 -0
- package/dist/bin/commands/vex.js.map +7 -0
- package/dist/bin/commands/vuln-suppress.js +95 -0
- package/dist/bin/commands/vuln-suppress.js.map +7 -0
- package/dist/bin/commands/vulns.js +382 -0
- package/dist/bin/commands/vulns.js.map +7 -0
- package/dist/bin/installer/auto-detect.js +125 -0
- package/dist/bin/installer/auto-detect.js.map +7 -0
- package/dist/bin/installer/cli-agent.js +28 -5
- package/dist/bin/installer/cli-agent.js.map +2 -2
- package/dist/bin/installer/common.js +47 -0
- package/dist/bin/installer/common.js.map +2 -2
- package/dist/bin/installer/config-prompt.js +12 -1
- package/dist/bin/installer/config-prompt.js.map +2 -2
- package/dist/bin/installer/detect.js +309 -0
- package/dist/bin/installer/detect.js.map +7 -0
- package/dist/bin/installer/index.js +9 -1
- package/dist/bin/installer/index.js.map +2 -2
- package/dist/bin/installer/instructions.js +195 -3
- package/dist/bin/installer/instructions.js.map +2 -2
- package/dist/bin/installer/steering.js +407 -0
- package/dist/bin/installer/steering.js.map +2 -2
- package/dist/bin/installer/targets/aider.js +3 -3
- package/dist/bin/installer/targets/aider.js.map +2 -2
- package/dist/bin/installer/targets/amp.js +3 -3
- package/dist/bin/installer/targets/amp.js.map +2 -2
- package/dist/bin/installer/targets/antigravity.js +35 -6
- package/dist/bin/installer/targets/antigravity.js.map +2 -2
- package/dist/bin/installer/targets/augment.js +3 -3
- package/dist/bin/installer/targets/augment.js.map +2 -2
- package/dist/bin/installer/targets/claude.js +49 -5
- package/dist/bin/installer/targets/claude.js.map +2 -2
- package/dist/bin/installer/targets/cline.js +32 -6
- package/dist/bin/installer/targets/cline.js.map +2 -2
- package/dist/bin/installer/targets/codex.js +64 -12
- package/dist/bin/installer/targets/codex.js.map +2 -2
- package/dist/bin/installer/targets/continue.js +2 -2
- package/dist/bin/installer/targets/continue.js.map +2 -2
- package/dist/bin/installer/targets/copilot-cli.js +101 -0
- package/dist/bin/installer/targets/copilot-cli.js.map +7 -0
- package/dist/bin/installer/targets/copilot.js +31 -5
- package/dist/bin/installer/targets/copilot.js.map +2 -2
- package/dist/bin/installer/targets/cursor.js +4 -4
- package/dist/bin/installer/targets/cursor.js.map +2 -2
- package/dist/bin/installer/targets/devin.js +2 -2
- package/dist/bin/installer/targets/devin.js.map +2 -2
- package/dist/bin/installer/targets/gemini-cli.js +2 -2
- package/dist/bin/installer/targets/gemini-cli.js.map +2 -2
- package/dist/bin/installer/targets/generic.js +2 -14
- package/dist/bin/installer/targets/generic.js.map +2 -2
- package/dist/bin/installer/targets/goose.js +3 -3
- package/dist/bin/installer/targets/goose.js.map +2 -2
- package/dist/bin/installer/targets/index.js +250 -0
- package/dist/bin/installer/targets/index.js.map +2 -2
- package/dist/bin/installer/targets/junie.js +2 -2
- package/dist/bin/installer/targets/junie.js.map +2 -2
- package/dist/bin/installer/targets/kilo.js +2 -2
- package/dist/bin/installer/targets/kilo.js.map +2 -2
- package/dist/bin/installer/targets/kiro.js +3 -3
- package/dist/bin/installer/targets/kiro.js.map +2 -2
- package/dist/bin/installer/targets/opencode.js +2 -2
- package/dist/bin/installer/targets/opencode.js.map +2 -2
- package/dist/bin/installer/targets/openhands.js +3 -3
- package/dist/bin/installer/targets/openhands.js.map +2 -2
- package/dist/bin/installer/targets/qoder.js +91 -0
- package/dist/bin/installer/targets/qoder.js.map +7 -0
- package/dist/bin/installer/targets/qwen.js +96 -0
- package/dist/bin/installer/targets/qwen.js.map +7 -0
- package/dist/bin/installer/targets/replit.js +3 -3
- package/dist/bin/installer/targets/replit.js.map +2 -2
- package/dist/bin/installer/targets/roo.js +2 -2
- package/dist/bin/installer/targets/roo.js.map +2 -2
- package/dist/bin/installer/targets/tabnine.js +3 -3
- package/dist/bin/installer/targets/tabnine.js.map +2 -2
- package/dist/bin/installer/targets/trae.js +5 -5
- package/dist/bin/installer/targets/trae.js.map +2 -2
- package/dist/bin/installer/targets/warp.js +2 -2
- package/dist/bin/installer/targets/warp.js.map +2 -2
- package/dist/bin/installer/targets/windsurf.js +35 -6
- package/dist/bin/installer/targets/windsurf.js.map +2 -2
- package/dist/bin/kirograph.js +72 -6
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/compression/tracker.js +80 -0
- package/dist/compression/tracker.js.map +2 -2
- package/dist/config.js +90 -3
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +36 -2
- package/dist/core/pipeline.js.map +2 -2
- package/dist/db/database.js +56 -5
- package/dist/db/database.js.map +2 -2
- package/dist/db/memory-schema.sql +5 -1
- package/dist/db/schema.sql +3 -1
- package/dist/db/security-schema.sql +72 -0
- package/dist/extraction/extractor.js +81 -0
- package/dist/extraction/extractor.js.map +2 -2
- package/dist/extraction/grammars.js +32 -8
- package/dist/extraction/grammars.js.map +2 -2
- package/dist/extraction/languages.js +43 -1
- package/dist/extraction/languages.js.map +2 -2
- package/dist/extraction/notebook.js +300 -0
- package/dist/extraction/notebook.js.map +7 -0
- package/dist/extraction/wasm/tree-sitter-astro.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-gdscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-julia.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-perl.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-powershell.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-r.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-sql.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-verilog.wasm +0 -0
- package/dist/frameworks/flutter.js +130 -0
- package/dist/frameworks/flutter.js.map +7 -0
- package/dist/frameworks/index.js +7 -1
- package/dist/frameworks/index.js.map +3 -3
- package/dist/graph/communities.js +317 -0
- package/dist/graph/communities.js.map +7 -0
- package/dist/graph/flows.js +138 -0
- package/dist/graph/flows.js.map +7 -0
- package/dist/graph/refactor.js +155 -0
- package/dist/graph/refactor.js.map +7 -0
- package/dist/index.js +1 -1
- package/dist/index.js.map +2 -2
- package/dist/mcp/cache.js +172 -0
- package/dist/mcp/cache.js.map +7 -0
- package/dist/mcp/read-modes.js +295 -0
- package/dist/mcp/read-modes.js.map +7 -0
- package/dist/mcp/server.js +2 -1
- package/dist/mcp/server.js.map +2 -2
- package/dist/mcp/tool-names.js +21 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +1160 -1
- package/dist/mcp/tools.js.map +3 -3
- package/dist/memory/database.js +32 -2
- package/dist/memory/database.js.map +2 -2
- package/dist/memory/types.js.map +1 -1
- package/dist/resolution/bridges/android-rn.js +298 -0
- package/dist/resolution/bridges/android-rn.js.map +7 -0
- package/dist/resolution/bridges/expo-modules.js +155 -0
- package/dist/resolution/bridges/expo-modules.js.map +7 -0
- package/dist/resolution/bridges/flutter-channel.js +385 -0
- package/dist/resolution/bridges/flutter-channel.js.map +7 -0
- package/dist/resolution/bridges/index.js +80 -0
- package/dist/resolution/bridges/index.js.map +7 -0
- package/dist/resolution/bridges/native-events.js +188 -0
- package/dist/resolution/bridges/native-events.js.map +7 -0
- package/dist/resolution/bridges/native-views.js +244 -0
- package/dist/resolution/bridges/native-views.js.map +7 -0
- package/dist/resolution/bridges/react-native.js +161 -0
- package/dist/resolution/bridges/react-native.js.map +7 -0
- package/dist/resolution/bridges/swift-objc.js +227 -0
- package/dist/resolution/bridges/swift-objc.js.map +7 -0
- package/dist/resolution/bridges/turbomodules.js +216 -0
- package/dist/resolution/bridges/turbomodules.js.map +7 -0
- package/dist/resolution/index.js +61 -2
- package/dist/resolution/index.js.map +2 -2
- package/dist/security/attack-surface.js +164 -0
- package/dist/security/attack-surface.js.map +7 -0
- package/dist/security/context-warnings.js +123 -0
- package/dist/security/context-warnings.js.map +7 -0
- package/dist/security/context-warnings.test.js +300 -0
- package/dist/security/context-warnings.test.js.map +7 -0
- package/dist/security/data-flows.js +228 -0
- package/dist/security/data-flows.js.map +7 -0
- package/dist/security/dep-confusion.js +255 -0
- package/dist/security/dep-confusion.js.map +7 -0
- package/dist/security/errors.js +51 -0
- package/dist/security/errors.js.map +7 -0
- package/dist/security/export/fix-suggestions.js +58 -0
- package/dist/security/export/fix-suggestions.js.map +7 -0
- package/dist/security/export/fix-suggestions.test.js +74 -0
- package/dist/security/export/fix-suggestions.test.js.map +7 -0
- package/dist/security/export/sbom.js +230 -0
- package/dist/security/export/sbom.js.map +7 -0
- package/dist/security/export/sbom.test.js +288 -0
- package/dist/security/export/sbom.test.js.map +7 -0
- package/dist/security/export/serialization.js +142 -0
- package/dist/security/export/serialization.js.map +7 -0
- package/dist/security/export/serialization.test.js +310 -0
- package/dist/security/export/serialization.test.js.map +7 -0
- package/dist/security/export/vex.js +220 -0
- package/dist/security/export/vex.js.map +7 -0
- package/dist/security/export/vex.test.js +278 -0
- package/dist/security/export/vex.test.js.map +7 -0
- package/dist/security/index.js +67 -0
- package/dist/security/index.js.map +7 -0
- package/dist/security/integrator-transitives.test.js +359 -0
- package/dist/security/integrator-transitives.test.js.map +7 -0
- package/dist/security/integrator.js +491 -0
- package/dist/security/integrator.js.map +7 -0
- package/dist/security/integrator.test.js +237 -0
- package/dist/security/integrator.test.js.map +7 -0
- package/dist/security/license.js +70 -0
- package/dist/security/license.js.map +7 -0
- package/dist/security/manifest/adapter.js +243 -0
- package/dist/security/manifest/adapter.js.map +7 -0
- package/dist/security/manifest/adapter.test.js +272 -0
- package/dist/security/manifest/adapter.test.js.map +7 -0
- package/dist/security/manifest/parser.js +376 -0
- package/dist/security/manifest/parser.js.map +7 -0
- package/dist/security/manifest/parser.test.js +110 -0
- package/dist/security/manifest/parser.test.js.map +7 -0
- package/dist/security/manifest/plugins/cargo.js +233 -0
- package/dist/security/manifest/plugins/cargo.js.map +7 -0
- package/dist/security/manifest/plugins/cargo.test.js +304 -0
- package/dist/security/manifest/plugins/cargo.test.js.map +7 -0
- package/dist/security/manifest/plugins/composer.js +152 -0
- package/dist/security/manifest/plugins/composer.js.map +7 -0
- package/dist/security/manifest/plugins/go.js +146 -0
- package/dist/security/manifest/plugins/go.js.map +7 -0
- package/dist/security/manifest/plugins/go.test.js +341 -0
- package/dist/security/manifest/plugins/go.test.js.map +7 -0
- package/dist/security/manifest/plugins/gradle.js +159 -0
- package/dist/security/manifest/plugins/gradle.js.map +7 -0
- package/dist/security/manifest/plugins/hex.js +159 -0
- package/dist/security/manifest/plugins/hex.js.map +7 -0
- package/dist/security/manifest/plugins/maven.js +128 -0
- package/dist/security/manifest/plugins/maven.js.map +7 -0
- package/dist/security/manifest/plugins/maven.test.js +389 -0
- package/dist/security/manifest/plugins/maven.test.js.map +7 -0
- package/dist/security/manifest/plugins/npm.js +284 -0
- package/dist/security/manifest/plugins/npm.js.map +7 -0
- package/dist/security/manifest/plugins/npm.test.js +298 -0
- package/dist/security/manifest/plugins/npm.test.js.map +7 -0
- package/dist/security/manifest/plugins/nuget.js +186 -0
- package/dist/security/manifest/plugins/nuget.js.map +7 -0
- package/dist/security/manifest/plugins/pip.js +123 -0
- package/dist/security/manifest/plugins/pip.js.map +7 -0
- package/dist/security/manifest/plugins/pip.test.js +208 -0
- package/dist/security/manifest/plugins/pip.test.js.map +7 -0
- package/dist/security/manifest/plugins/pubspec.js +212 -0
- package/dist/security/manifest/plugins/pubspec.js.map +7 -0
- package/dist/security/manifest/plugins/pyproject.js +261 -0
- package/dist/security/manifest/plugins/pyproject.js.map +7 -0
- package/dist/security/manifest/plugins/rubygems.js +185 -0
- package/dist/security/manifest/plugins/rubygems.js.map +7 -0
- package/dist/security/manifest/plugins/swift.js +200 -0
- package/dist/security/manifest/plugins/swift.js.map +7 -0
- package/dist/security/owasp.js +104 -0
- package/dist/security/owasp.js.map +7 -0
- package/dist/security/pipeline.js +125 -0
- package/dist/security/pipeline.js.map +7 -0
- package/dist/security/reachability.js +276 -0
- package/dist/security/reachability.js.map +7 -0
- package/dist/security/reachability.test.js +394 -0
- package/dist/security/reachability.test.js.map +7 -0
- package/dist/security/remediation.js +126 -0
- package/dist/security/remediation.js.map +7 -0
- package/dist/security/secrets.js +176 -0
- package/dist/security/secrets.js.map +7 -0
- package/dist/security/staleness.js +231 -0
- package/dist/security/staleness.js.map +7 -0
- package/dist/security/supply-chain.js +301 -0
- package/dist/security/supply-chain.js.map +7 -0
- package/dist/security/suppressions.js +106 -0
- package/dist/security/suppressions.js.map +7 -0
- package/dist/security/types.js +17 -0
- package/dist/security/types.js.map +7 -0
- package/dist/security/vuln/client.js +355 -0
- package/dist/security/vuln/client.js.map +7 -0
- package/dist/security/vuln/client.test.js +288 -0
- package/dist/security/vuln/client.test.js.map +7 -0
- package/dist/security/vuln/epss-client.js +95 -0
- package/dist/security/vuln/epss-client.js.map +7 -0
- package/dist/security/vuln/index.js +29 -0
- package/dist/security/vuln/index.js.map +7 -0
- package/dist/security/vuln/osv-adapter.js +321 -0
- package/dist/security/vuln/osv-adapter.js.map +7 -0
- package/dist/security/vuln/osv-adapter.test.js +391 -0
- package/dist/security/vuln/osv-adapter.test.js.map +7 -0
- package/dist/security/vuln/types.js +17 -0
- package/dist/security/vuln/types.js.map +7 -0
- package/dist/types.js.map +2 -2
- package/package.json +2 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/security/index.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * KiroGraph-Sec Module Index\n *\n * Exports all public interfaces, classes, and types for the security module.\n * Used by MCP tools, CLI commands, and pipeline integration.\n */\n\n// \u2500\u2500 Pipeline \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { SecurityPipeline } from './pipeline';\n\n// \u2500\u2500 Manifest Parsing \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { ManifestParser } from './manifest/parser';\n\n// \u2500\u2500 Dependency Graph Integration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { DependencyGraphIntegrator } from './integrator';\n\n// \u2500\u2500 Vulnerability Database \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { VulnerabilityDatabaseClient } from './vuln/client';\nexport { OsvAdapter } from './vuln/osv-adapter';\nexport type { VulnDatabaseAdapter } from './vuln/types';\n\n// \u2500\u2500 Reachability Analysis \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { ReachabilityAnalyzer } from './reachability';\n\n// \u2500\u2500 Export (SBOM / VEX) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { SBOMExporter } from './export/sbom';\nexport { VEXExporter } from './export/vex';\nexport { buildFixSuggestion, formatFixSuggestion } from './export/fix-suggestions';\n\n// \u2500\u2500 Context Warnings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { getSecurityWarningsForNodes, formatSecurityWarnings } from './context-warnings';\nexport type { SecurityWarning } from './context-warnings';\n\n// \u2500\u2500 Types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport type {\n ParsedDependency,\n ManifestParseResult,\n IntegrationResult,\n TransitiveResult,\n CleanupResult,\n CVERecord,\n VersionRange,\n EnrichmentResult,\n ReachabilityVerdict,\n ReachabilityPath,\n ReachabilityResult,\n ImpactSummary,\n SecurityResult,\n SBOMMetadata,\n CycloneDXSBOM,\n CycloneDXComponent,\n CycloneDXDependencyEntry,\n CycloneDXVEX,\n CycloneDXVulnerability,\n} from './types';\n\n// \u2500\u2500 Errors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nexport { SecurityError, ManifestParseError, VulnDatabaseError } from './errors';\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,sBAAiC;AAGjC,oBAA+B;AAG/B,wBAA0C;AAG1C,oBAA4C;AAC5C,yBAA2B;AAI3B,0BAAqC;AAGrC,kBAA6B;AAC7B,iBAA4B;AAC5B,6BAAwD;AAGxD,8BAAoE;AA2BpE,oBAAqE;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
var import_vitest = require("vitest");
|
|
25
|
+
var fs = __toESM(require("fs"));
|
|
26
|
+
var path = __toESM(require("path"));
|
|
27
|
+
var os = __toESM(require("os"));
|
|
28
|
+
var import_integrator = require("./integrator");
|
|
29
|
+
var import_database = require("../db/database");
|
|
30
|
+
(0, import_vitest.describe)("DependencyGraphIntegrator.resolveTransitives()", () => {
|
|
31
|
+
let db;
|
|
32
|
+
let tmpDir;
|
|
33
|
+
(0, import_vitest.beforeEach)(() => {
|
|
34
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "kirograph-transitives-test-"));
|
|
35
|
+
db = new import_database.GraphDatabase(tmpDir);
|
|
36
|
+
db.applySecuritySchema();
|
|
37
|
+
});
|
|
38
|
+
(0, import_vitest.afterEach)(() => {
|
|
39
|
+
db.close();
|
|
40
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
41
|
+
});
|
|
42
|
+
function createDepNode(name, ecosystem, version) {
|
|
43
|
+
const nodeId = `dep:${ecosystem}:${name}`;
|
|
44
|
+
const rawDb = db.getRawDb();
|
|
45
|
+
const node = {
|
|
46
|
+
id: nodeId,
|
|
47
|
+
kind: "dependency",
|
|
48
|
+
name,
|
|
49
|
+
qualifiedName: `${ecosystem}/${name}`,
|
|
50
|
+
filePath: "package.json",
|
|
51
|
+
language: "unknown",
|
|
52
|
+
startLine: 0,
|
|
53
|
+
endLine: 0,
|
|
54
|
+
startColumn: 0,
|
|
55
|
+
endColumn: 0,
|
|
56
|
+
isExported: false,
|
|
57
|
+
isAsync: false,
|
|
58
|
+
isStatic: false,
|
|
59
|
+
isAbstract: false,
|
|
60
|
+
updatedAt: Date.now()
|
|
61
|
+
};
|
|
62
|
+
db.upsertNode(node);
|
|
63
|
+
rawDb.run(
|
|
64
|
+
`INSERT OR REPLACE INTO sec_dependencies
|
|
65
|
+
(node_id, ecosystem, package_name, declared_constraint,
|
|
66
|
+
resolved_version, scope, source_manifests)
|
|
67
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)`,
|
|
68
|
+
[
|
|
69
|
+
nodeId,
|
|
70
|
+
ecosystem,
|
|
71
|
+
name,
|
|
72
|
+
version ?? "^1.0.0",
|
|
73
|
+
version ?? "1.0.0",
|
|
74
|
+
"production",
|
|
75
|
+
'["package.json"]'
|
|
76
|
+
]
|
|
77
|
+
);
|
|
78
|
+
return nodeId;
|
|
79
|
+
}
|
|
80
|
+
(0, import_vitest.it)("should create depends_on edges from npm package-lock.json", async () => {
|
|
81
|
+
createDepNode("express", "npm");
|
|
82
|
+
createDepNode("body-parser", "npm");
|
|
83
|
+
createDepNode("accepts", "npm");
|
|
84
|
+
const lockData = {
|
|
85
|
+
name: "test-project",
|
|
86
|
+
lockfileVersion: 3,
|
|
87
|
+
packages: {
|
|
88
|
+
"": { name: "test-project", version: "1.0.0" },
|
|
89
|
+
"node_modules/express": {
|
|
90
|
+
version: "4.18.2",
|
|
91
|
+
dependencies: { "body-parser": "^1.20.0", accepts: "~1.3.8" }
|
|
92
|
+
},
|
|
93
|
+
"node_modules/body-parser": {
|
|
94
|
+
version: "1.20.2",
|
|
95
|
+
dependencies: {}
|
|
96
|
+
},
|
|
97
|
+
"node_modules/accepts": {
|
|
98
|
+
version: "1.3.8",
|
|
99
|
+
dependencies: {}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
fs.writeFileSync(
|
|
104
|
+
path.join(tmpDir, "package-lock.json"),
|
|
105
|
+
JSON.stringify(lockData, null, 2)
|
|
106
|
+
);
|
|
107
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
108
|
+
const result = await integrator.resolveTransitives(10);
|
|
109
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(2);
|
|
110
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(0);
|
|
111
|
+
const edges = db.getAllEdges();
|
|
112
|
+
const dependsOnEdges = edges.filter((e) => e.kind === "depends_on");
|
|
113
|
+
(0, import_vitest.expect)(dependsOnEdges).toHaveLength(2);
|
|
114
|
+
(0, import_vitest.expect)(dependsOnEdges).toContainEqual(
|
|
115
|
+
import_vitest.expect.objectContaining({
|
|
116
|
+
source: "dep:npm:express",
|
|
117
|
+
target: "dep:npm:body-parser",
|
|
118
|
+
kind: "depends_on"
|
|
119
|
+
})
|
|
120
|
+
);
|
|
121
|
+
(0, import_vitest.expect)(dependsOnEdges).toContainEqual(
|
|
122
|
+
import_vitest.expect.objectContaining({
|
|
123
|
+
source: "dep:npm:express",
|
|
124
|
+
target: "dep:npm:accepts",
|
|
125
|
+
kind: "depends_on"
|
|
126
|
+
})
|
|
127
|
+
);
|
|
128
|
+
});
|
|
129
|
+
(0, import_vitest.it)("should mark dependencies as incomplete when no lock file exists", async () => {
|
|
130
|
+
createDepNode("serde", "cargo");
|
|
131
|
+
createDepNode("tokio", "cargo");
|
|
132
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
133
|
+
const result = await integrator.resolveTransitives(10);
|
|
134
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(0);
|
|
135
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(2);
|
|
136
|
+
(0, import_vitest.expect)(result.incompleteNodes).toContain("dep:cargo:serde");
|
|
137
|
+
(0, import_vitest.expect)(result.incompleteNodes).toContain("dep:cargo:tokio");
|
|
138
|
+
const rawDb = db.getRawDb();
|
|
139
|
+
const row = rawDb.get(
|
|
140
|
+
"SELECT transitive_status FROM sec_dependencies WHERE node_id = ?",
|
|
141
|
+
["dep:cargo:serde"]
|
|
142
|
+
);
|
|
143
|
+
(0, import_vitest.expect)(row.transitive_status).toBe("incomplete");
|
|
144
|
+
});
|
|
145
|
+
(0, import_vitest.it)("should respect maxDepth limit", async () => {
|
|
146
|
+
createDepNode("a", "npm");
|
|
147
|
+
createDepNode("b", "npm");
|
|
148
|
+
createDepNode("c", "npm");
|
|
149
|
+
createDepNode("d", "npm");
|
|
150
|
+
const lockData = {
|
|
151
|
+
name: "test-project",
|
|
152
|
+
lockfileVersion: 3,
|
|
153
|
+
packages: {
|
|
154
|
+
"": { name: "test-project", version: "1.0.0" },
|
|
155
|
+
"node_modules/a": {
|
|
156
|
+
version: "1.0.0",
|
|
157
|
+
dependencies: { b: "^1.0.0" }
|
|
158
|
+
},
|
|
159
|
+
"node_modules/b": {
|
|
160
|
+
version: "1.0.0",
|
|
161
|
+
dependencies: { c: "^1.0.0" }
|
|
162
|
+
},
|
|
163
|
+
"node_modules/c": {
|
|
164
|
+
version: "1.0.0",
|
|
165
|
+
dependencies: { d: "^1.0.0" }
|
|
166
|
+
},
|
|
167
|
+
"node_modules/d": {
|
|
168
|
+
version: "1.0.0",
|
|
169
|
+
dependencies: {}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
fs.writeFileSync(
|
|
174
|
+
path.join(tmpDir, "package-lock.json"),
|
|
175
|
+
JSON.stringify(lockData, null, 2)
|
|
176
|
+
);
|
|
177
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
178
|
+
const result = await integrator.resolveTransitives(1);
|
|
179
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(3);
|
|
180
|
+
const edges = db.getAllEdges();
|
|
181
|
+
const dependsOnEdges = edges.filter((e) => e.kind === "depends_on");
|
|
182
|
+
const edgePairs = dependsOnEdges.map((e) => `${e.source}->${e.target}`);
|
|
183
|
+
(0, import_vitest.expect)(edgePairs).toContain("dep:npm:a->dep:npm:b");
|
|
184
|
+
(0, import_vitest.expect)(edgePairs).toContain("dep:npm:b->dep:npm:c");
|
|
185
|
+
(0, import_vitest.expect)(edgePairs).toContain("dep:npm:c->dep:npm:d");
|
|
186
|
+
(0, import_vitest.expect)(edgePairs).not.toContain("dep:npm:a->dep:npm:c");
|
|
187
|
+
(0, import_vitest.expect)(edgePairs).not.toContain("dep:npm:a->dep:npm:d");
|
|
188
|
+
});
|
|
189
|
+
(0, import_vitest.it)("should handle Cargo.lock transitive dependencies", async () => {
|
|
190
|
+
createDepNode("serde", "cargo");
|
|
191
|
+
createDepNode("serde_derive", "cargo");
|
|
192
|
+
const cargoLock = `[[package]]
|
|
193
|
+
name = "serde"
|
|
194
|
+
version = "1.0.193"
|
|
195
|
+
dependencies = [
|
|
196
|
+
"serde_derive",
|
|
197
|
+
]
|
|
198
|
+
|
|
199
|
+
[[package]]
|
|
200
|
+
name = "serde_derive"
|
|
201
|
+
version = "1.0.193"
|
|
202
|
+
`;
|
|
203
|
+
fs.writeFileSync(path.join(tmpDir, "Cargo.lock"), cargoLock);
|
|
204
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
205
|
+
const result = await integrator.resolveTransitives(10);
|
|
206
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(1);
|
|
207
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(0);
|
|
208
|
+
const edges = db.getAllEdges();
|
|
209
|
+
const dependsOnEdges = edges.filter((e) => e.kind === "depends_on");
|
|
210
|
+
(0, import_vitest.expect)(dependsOnEdges).toContainEqual(
|
|
211
|
+
import_vitest.expect.objectContaining({
|
|
212
|
+
source: "dep:cargo:serde",
|
|
213
|
+
target: "dep:cargo:serde_derive",
|
|
214
|
+
kind: "depends_on"
|
|
215
|
+
})
|
|
216
|
+
);
|
|
217
|
+
});
|
|
218
|
+
(0, import_vitest.it)("should mark Go dependencies as incomplete (no tree in go.sum)", async () => {
|
|
219
|
+
createDepNode("github.com/gin-gonic/gin", "go");
|
|
220
|
+
fs.writeFileSync(
|
|
221
|
+
path.join(tmpDir, "go.sum"),
|
|
222
|
+
"github.com/gin-gonic/gin v1.9.1 h1:abc=\n"
|
|
223
|
+
);
|
|
224
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
225
|
+
const result = await integrator.resolveTransitives(10);
|
|
226
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(0);
|
|
227
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(1);
|
|
228
|
+
(0, import_vitest.expect)(result.incompleteNodes).toContain("dep:go:github.com/gin-gonic/gin");
|
|
229
|
+
});
|
|
230
|
+
(0, import_vitest.it)("should return empty result when no dependencies exist", async () => {
|
|
231
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
232
|
+
const result = await integrator.resolveTransitives(10);
|
|
233
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(0);
|
|
234
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(0);
|
|
235
|
+
});
|
|
236
|
+
(0, import_vitest.it)("should not create duplicate depends_on edges", async () => {
|
|
237
|
+
createDepNode("express", "npm");
|
|
238
|
+
createDepNode("body-parser", "npm");
|
|
239
|
+
const lockData = {
|
|
240
|
+
name: "test-project",
|
|
241
|
+
lockfileVersion: 3,
|
|
242
|
+
packages: {
|
|
243
|
+
"": { name: "test-project", version: "1.0.0" },
|
|
244
|
+
"node_modules/express": {
|
|
245
|
+
version: "4.18.2",
|
|
246
|
+
dependencies: { "body-parser": "^1.20.0" }
|
|
247
|
+
},
|
|
248
|
+
"node_modules/body-parser": {
|
|
249
|
+
version: "1.20.2",
|
|
250
|
+
dependencies: {}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
fs.writeFileSync(
|
|
255
|
+
path.join(tmpDir, "package-lock.json"),
|
|
256
|
+
JSON.stringify(lockData, null, 2)
|
|
257
|
+
);
|
|
258
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
259
|
+
const result = await integrator.resolveTransitives(10);
|
|
260
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(1);
|
|
261
|
+
const edges = db.getAllEdges();
|
|
262
|
+
const dependsOnEdges = edges.filter((e) => e.kind === "depends_on");
|
|
263
|
+
(0, import_vitest.expect)(dependsOnEdges).toHaveLength(1);
|
|
264
|
+
});
|
|
265
|
+
(0, import_vitest.it)("should handle npm lockfileVersion 1 format", async () => {
|
|
266
|
+
createDepNode("express", "npm");
|
|
267
|
+
createDepNode("debug", "npm");
|
|
268
|
+
const lockData = {
|
|
269
|
+
name: "test-project",
|
|
270
|
+
lockfileVersion: 1,
|
|
271
|
+
dependencies: {
|
|
272
|
+
express: {
|
|
273
|
+
version: "4.18.2",
|
|
274
|
+
requires: { debug: "2.6.9" }
|
|
275
|
+
},
|
|
276
|
+
debug: {
|
|
277
|
+
version: "2.6.9"
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
fs.writeFileSync(
|
|
282
|
+
path.join(tmpDir, "package-lock.json"),
|
|
283
|
+
JSON.stringify(lockData, null, 2)
|
|
284
|
+
);
|
|
285
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
286
|
+
const result = await integrator.resolveTransitives(10);
|
|
287
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(1);
|
|
288
|
+
const edges = db.getAllEdges();
|
|
289
|
+
const dependsOnEdges = edges.filter((e) => e.kind === "depends_on");
|
|
290
|
+
(0, import_vitest.expect)(dependsOnEdges).toContainEqual(
|
|
291
|
+
import_vitest.expect.objectContaining({
|
|
292
|
+
source: "dep:npm:express",
|
|
293
|
+
target: "dep:npm:debug",
|
|
294
|
+
kind: "depends_on"
|
|
295
|
+
})
|
|
296
|
+
);
|
|
297
|
+
});
|
|
298
|
+
(0, import_vitest.it)("should handle deep transitive chains with maxDepth=10", async () => {
|
|
299
|
+
createDepNode("a", "npm");
|
|
300
|
+
createDepNode("b", "npm");
|
|
301
|
+
createDepNode("c", "npm");
|
|
302
|
+
createDepNode("d", "npm");
|
|
303
|
+
createDepNode("e", "npm");
|
|
304
|
+
const lockData = {
|
|
305
|
+
name: "test-project",
|
|
306
|
+
lockfileVersion: 3,
|
|
307
|
+
packages: {
|
|
308
|
+
"": { name: "test-project", version: "1.0.0" },
|
|
309
|
+
"node_modules/a": { version: "1.0.0", dependencies: { b: "1.0.0" } },
|
|
310
|
+
"node_modules/b": { version: "1.0.0", dependencies: { c: "1.0.0" } },
|
|
311
|
+
"node_modules/c": { version: "1.0.0", dependencies: { d: "1.0.0" } },
|
|
312
|
+
"node_modules/d": { version: "1.0.0", dependencies: { e: "1.0.0" } },
|
|
313
|
+
"node_modules/e": { version: "1.0.0", dependencies: {} }
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
fs.writeFileSync(
|
|
317
|
+
path.join(tmpDir, "package-lock.json"),
|
|
318
|
+
JSON.stringify(lockData, null, 2)
|
|
319
|
+
);
|
|
320
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
321
|
+
const result = await integrator.resolveTransitives(10);
|
|
322
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(4);
|
|
323
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(0);
|
|
324
|
+
});
|
|
325
|
+
(0, import_vitest.it)("should handle circular dependencies in lock file gracefully", async () => {
|
|
326
|
+
createDepNode("a", "npm");
|
|
327
|
+
createDepNode("b", "npm");
|
|
328
|
+
const lockData = {
|
|
329
|
+
name: "test-project",
|
|
330
|
+
lockfileVersion: 3,
|
|
331
|
+
packages: {
|
|
332
|
+
"": { name: "test-project", version: "1.0.0" },
|
|
333
|
+
"node_modules/a": { version: "1.0.0", dependencies: { b: "1.0.0" } },
|
|
334
|
+
"node_modules/b": { version: "1.0.0", dependencies: { a: "1.0.0" } }
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
fs.writeFileSync(
|
|
338
|
+
path.join(tmpDir, "package-lock.json"),
|
|
339
|
+
JSON.stringify(lockData, null, 2)
|
|
340
|
+
);
|
|
341
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
342
|
+
const result = await integrator.resolveTransitives(10);
|
|
343
|
+
(0, import_vitest.expect)(result.dependsOnEdgesCreated).toBe(2);
|
|
344
|
+
(0, import_vitest.expect)(result.incompleteNodes).toHaveLength(0);
|
|
345
|
+
});
|
|
346
|
+
(0, import_vitest.it)("should log warning with dependency name when marking incomplete", async () => {
|
|
347
|
+
createDepNode("flask", "python");
|
|
348
|
+
const integrator = new import_integrator.DependencyGraphIntegrator(db, tmpDir);
|
|
349
|
+
const result = await integrator.resolveTransitives(10);
|
|
350
|
+
(0, import_vitest.expect)(result.incompleteNodes).toContain("dep:python:flask");
|
|
351
|
+
const rawDb = db.getRawDb();
|
|
352
|
+
const row = rawDb.get(
|
|
353
|
+
"SELECT transitive_status FROM sec_dependencies WHERE node_id = ?",
|
|
354
|
+
["dep:python:flask"]
|
|
355
|
+
);
|
|
356
|
+
(0, import_vitest.expect)(row.transitive_status).toBe("incomplete");
|
|
357
|
+
});
|
|
358
|
+
});
|
|
359
|
+
//# sourceMappingURL=integrator-transitives.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/security/integrator-transitives.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Tests for DependencyGraphIntegrator.resolveTransitives()\n *\n * Verifies transitive dependency resolution from lock files,\n * creation of depends_on edges, and incomplete status marking.\n *\n * Requirements: 2.3, 2.5\n */\nimport { describe, it, expect, beforeEach, afterEach } from 'vitest';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as os from 'os';\nimport { DependencyGraphIntegrator } from './integrator';\nimport { GraphDatabase } from '../db/database';\nimport type { Node, Edge } from '../types';\n\ndescribe('DependencyGraphIntegrator.resolveTransitives()', () => {\n let db: GraphDatabase;\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'kirograph-transitives-test-'));\n db = new GraphDatabase(tmpDir);\n db.applySecuritySchema();\n });\n\n afterEach(() => {\n db.close();\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n /**\n * Helper to create a dependency node in the database.\n */\n function createDepNode(\n name: string,\n ecosystem: string,\n version?: string,\n ): string {\n const nodeId = `dep:${ecosystem}:${name}`;\n const rawDb = db.getRawDb();\n\n const node: Node = {\n id: nodeId,\n kind: 'dependency',\n name,\n qualifiedName: `${ecosystem}/${name}`,\n filePath: 'package.json',\n language: 'unknown',\n startLine: 0,\n endLine: 0,\n startColumn: 0,\n endColumn: 0,\n isExported: false,\n isAsync: false,\n isStatic: false,\n isAbstract: false,\n updatedAt: Date.now(),\n };\n db.upsertNode(node);\n\n rawDb.run(\n `INSERT OR REPLACE INTO sec_dependencies\n (node_id, ecosystem, package_name, declared_constraint,\n resolved_version, scope, source_manifests)\n VALUES (?, ?, ?, ?, ?, ?, ?)`,\n [\n nodeId,\n ecosystem,\n name,\n version ?? '^1.0.0',\n version ?? '1.0.0',\n 'production',\n '[\"package.json\"]',\n ],\n );\n return nodeId;\n }\n\n it('should create depends_on edges from npm package-lock.json', async () => {\n createDepNode('express', 'npm');\n createDepNode('body-parser', 'npm');\n createDepNode('accepts', 'npm');\n\n // Create a package-lock.json with transitive relationships\n const lockData = {\n name: 'test-project',\n lockfileVersion: 3,\n packages: {\n '': { name: 'test-project', version: '1.0.0' },\n 'node_modules/express': {\n version: '4.18.2',\n dependencies: { 'body-parser': '^1.20.0', accepts: '~1.3.8' },\n },\n 'node_modules/body-parser': {\n version: '1.20.2',\n dependencies: {},\n },\n 'node_modules/accepts': {\n version: '1.3.8',\n dependencies: {},\n },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(2);\n expect(result.incompleteNodes).toHaveLength(0);\n\n // Verify edges exist\n const edges = db.getAllEdges();\n const dependsOnEdges = edges.filter(e => e.kind === 'depends_on');\n expect(dependsOnEdges).toHaveLength(2);\n\n // express depends_on body-parser\n expect(dependsOnEdges).toContainEqual(\n expect.objectContaining({\n source: 'dep:npm:express',\n target: 'dep:npm:body-parser',\n kind: 'depends_on',\n }),\n );\n // express depends_on accepts\n expect(dependsOnEdges).toContainEqual(\n expect.objectContaining({\n source: 'dep:npm:express',\n target: 'dep:npm:accepts',\n kind: 'depends_on',\n }),\n );\n });\n\n it('should mark dependencies as incomplete when no lock file exists', async () => {\n createDepNode('serde', 'cargo');\n createDepNode('tokio', 'cargo');\n\n // No Cargo.lock in tmpDir\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(0);\n expect(result.incompleteNodes).toHaveLength(2);\n expect(result.incompleteNodes).toContain('dep:cargo:serde');\n expect(result.incompleteNodes).toContain('dep:cargo:tokio');\n\n // Verify transitive_status is set to incomplete in the database\n const rawDb = db.getRawDb();\n const row = rawDb.get(\n 'SELECT transitive_status FROM sec_dependencies WHERE node_id = ?',\n ['dep:cargo:serde'],\n );\n expect(row.transitive_status).toBe('incomplete');\n });\n\n it('should respect maxDepth limit', async () => {\n // Create a chain: a -> b -> c -> d\n createDepNode('a', 'npm');\n createDepNode('b', 'npm');\n createDepNode('c', 'npm');\n createDepNode('d', 'npm');\n\n const lockData = {\n name: 'test-project',\n lockfileVersion: 3,\n packages: {\n '': { name: 'test-project', version: '1.0.0' },\n 'node_modules/a': {\n version: '1.0.0',\n dependencies: { b: '^1.0.0' },\n },\n 'node_modules/b': {\n version: '1.0.0',\n dependencies: { c: '^1.0.0' },\n },\n 'node_modules/c': {\n version: '1.0.0',\n dependencies: { d: '^1.0.0' },\n },\n 'node_modules/d': {\n version: '1.0.0',\n dependencies: {},\n },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n // With maxDepth=1, each node resolves only 1 level of its own transitives\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(1);\n\n // a->b (depth 1 from a), b->c (depth 1 from b), c->d (depth 1 from c)\n expect(result.dependsOnEdgesCreated).toBe(3);\n\n // Verify that deeper transitive edges are NOT created\n // (e.g., a should NOT have a depends_on edge to c or d)\n const edges = db.getAllEdges();\n const dependsOnEdges = edges.filter(e => e.kind === 'depends_on');\n\n // Only direct transitive edges should exist\n const edgePairs = dependsOnEdges.map(e => `${e.source}->${e.target}`);\n expect(edgePairs).toContain('dep:npm:a->dep:npm:b');\n expect(edgePairs).toContain('dep:npm:b->dep:npm:c');\n expect(edgePairs).toContain('dep:npm:c->dep:npm:d');\n // a should NOT directly depend on c or d at depth 1\n expect(edgePairs).not.toContain('dep:npm:a->dep:npm:c');\n expect(edgePairs).not.toContain('dep:npm:a->dep:npm:d');\n });\n\n it('should handle Cargo.lock transitive dependencies', async () => {\n createDepNode('serde', 'cargo');\n createDepNode('serde_derive', 'cargo');\n\n // Create a Cargo.lock with dependency relationships\n const cargoLock = `[[package]]\nname = \"serde\"\nversion = \"1.0.193\"\ndependencies = [\n \"serde_derive\",\n]\n\n[[package]]\nname = \"serde_derive\"\nversion = \"1.0.193\"\n`;\n fs.writeFileSync(path.join(tmpDir, 'Cargo.lock'), cargoLock);\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(1);\n expect(result.incompleteNodes).toHaveLength(0);\n\n const edges = db.getAllEdges();\n const dependsOnEdges = edges.filter(e => e.kind === 'depends_on');\n expect(dependsOnEdges).toContainEqual(\n expect.objectContaining({\n source: 'dep:cargo:serde',\n target: 'dep:cargo:serde_derive',\n kind: 'depends_on',\n }),\n );\n });\n\n it('should mark Go dependencies as incomplete (no tree in go.sum)', async () => {\n createDepNode('github.com/gin-gonic/gin', 'go');\n\n // Create a go.sum file (doesn't encode dependency tree)\n fs.writeFileSync(\n path.join(tmpDir, 'go.sum'),\n 'github.com/gin-gonic/gin v1.9.1 h1:abc=\\n',\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(0);\n expect(result.incompleteNodes).toHaveLength(1);\n expect(result.incompleteNodes).toContain('dep:go:github.com/gin-gonic/gin');\n });\n\n it('should return empty result when no dependencies exist', async () => {\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(0);\n expect(result.incompleteNodes).toHaveLength(0);\n });\n\n it('should not create duplicate depends_on edges', async () => {\n createDepNode('express', 'npm');\n createDepNode('body-parser', 'npm');\n\n const lockData = {\n name: 'test-project',\n lockfileVersion: 3,\n packages: {\n '': { name: 'test-project', version: '1.0.0' },\n 'node_modules/express': {\n version: '4.18.2',\n dependencies: { 'body-parser': '^1.20.0' },\n },\n 'node_modules/body-parser': {\n version: '1.20.2',\n dependencies: {},\n },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(1);\n\n // Verify only one edge exists\n const edges = db.getAllEdges();\n const dependsOnEdges = edges.filter(e => e.kind === 'depends_on');\n expect(dependsOnEdges).toHaveLength(1);\n });\n\n it('should handle npm lockfileVersion 1 format', async () => {\n createDepNode('express', 'npm');\n createDepNode('debug', 'npm');\n\n const lockData = {\n name: 'test-project',\n lockfileVersion: 1,\n dependencies: {\n express: {\n version: '4.18.2',\n requires: { debug: '2.6.9' },\n },\n debug: {\n version: '2.6.9',\n },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.dependsOnEdgesCreated).toBe(1);\n\n const edges = db.getAllEdges();\n const dependsOnEdges = edges.filter(e => e.kind === 'depends_on');\n expect(dependsOnEdges).toContainEqual(\n expect.objectContaining({\n source: 'dep:npm:express',\n target: 'dep:npm:debug',\n kind: 'depends_on',\n }),\n );\n });\n\n it('should handle deep transitive chains with maxDepth=10', async () => {\n // Create a chain of 5 dependencies: a -> b -> c -> d -> e\n createDepNode('a', 'npm');\n createDepNode('b', 'npm');\n createDepNode('c', 'npm');\n createDepNode('d', 'npm');\n createDepNode('e', 'npm');\n\n const lockData = {\n name: 'test-project',\n lockfileVersion: 3,\n packages: {\n '': { name: 'test-project', version: '1.0.0' },\n 'node_modules/a': { version: '1.0.0', dependencies: { b: '1.0.0' } },\n 'node_modules/b': { version: '1.0.0', dependencies: { c: '1.0.0' } },\n 'node_modules/c': { version: '1.0.0', dependencies: { d: '1.0.0' } },\n 'node_modules/d': { version: '1.0.0', dependencies: { e: '1.0.0' } },\n 'node_modules/e': { version: '1.0.0', dependencies: {} },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n // All edges in the chain should be created\n expect(result.dependsOnEdgesCreated).toBe(4);\n expect(result.incompleteNodes).toHaveLength(0);\n });\n\n it('should handle circular dependencies in lock file gracefully', async () => {\n createDepNode('a', 'npm');\n createDepNode('b', 'npm');\n\n // a depends on b, b depends on a (circular)\n const lockData = {\n name: 'test-project',\n lockfileVersion: 3,\n packages: {\n '': { name: 'test-project', version: '1.0.0' },\n 'node_modules/a': { version: '1.0.0', dependencies: { b: '1.0.0' } },\n 'node_modules/b': { version: '1.0.0', dependencies: { a: '1.0.0' } },\n },\n };\n fs.writeFileSync(\n path.join(tmpDir, 'package-lock.json'),\n JSON.stringify(lockData, null, 2),\n );\n\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n // Should create edges without infinite loop\n expect(result.dependsOnEdgesCreated).toBe(2);\n expect(result.incompleteNodes).toHaveLength(0);\n });\n\n it('should log warning with dependency name when marking incomplete', async () => {\n createDepNode('flask', 'python');\n\n // No pip lock file exists\n const integrator = new DependencyGraphIntegrator(db, tmpDir);\n const result = await integrator.resolveTransitives(10);\n\n expect(result.incompleteNodes).toContain('dep:python:flask');\n\n // Verify the database was updated\n const rawDb = db.getRawDb();\n const row = rawDb.get(\n 'SELECT transitive_status FROM sec_dependencies WHERE node_id = ?',\n ['dep:python:flask'],\n );\n expect(row.transitive_status).toBe('incomplete');\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|