kirograph 0.16.1 → 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 -1605
- 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/affected.js +40 -5
- package/dist/bin/commands/affected.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/data.js +665 -0
- package/dist/bin/commands/data.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 +386 -100
- 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 +39 -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 +36 -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 +440 -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 +74 -6
- package/dist/bin/kirograph.js.map +3 -3
- package/dist/bin/progress.js +30 -0
- package/dist/bin/progress.js.map +2 -2
- package/dist/compression/naive-cost.js +25 -0
- package/dist/compression/naive-cost.js.map +2 -2
- package/dist/compression/tracker.js +91 -2
- package/dist/compression/tracker.js.map +2 -2
- package/dist/compression/types.js.map +1 -1
- package/dist/config.js +126 -3
- package/dist/config.js.map +2 -2
- package/dist/core/pipeline.js +92 -4
- package/dist/core/pipeline.js.map +2 -2
- package/dist/data/filters.js +105 -0
- package/dist/data/filters.js.map +7 -0
- package/dist/data/indexer.js +225 -0
- package/dist/data/indexer.js.map +7 -0
- package/dist/data/linker.js +150 -0
- package/dist/data/linker.js.map +7 -0
- package/dist/data/lint.js +109 -0
- package/dist/data/lint.js.map +7 -0
- package/dist/data/parsers/csv.js +132 -0
- package/dist/data/parsers/csv.js.map +7 -0
- package/dist/data/parsers/excel.js +88 -0
- package/dist/data/parsers/excel.js.map +7 -0
- package/dist/data/parsers/index.js +79 -0
- package/dist/data/parsers/index.js.map +7 -0
- package/dist/data/parsers/json-array.js +89 -0
- package/dist/data/parsers/json-array.js.map +7 -0
- package/dist/data/parsers/jsonl.js +84 -0
- package/dist/data/parsers/jsonl.js.map +7 -0
- package/dist/data/parsers/parquet.js +95 -0
- package/dist/data/parsers/parquet.js.map +7 -0
- package/dist/data/profiler.js +182 -0
- package/dist/data/profiler.js.map +7 -0
- package/dist/data/queries.js +512 -0
- package/dist/data/queries.js.map +7 -0
- package/dist/data/types.js +17 -0
- package/dist/data/types.js.map +7 -0
- package/dist/db/data-schema.sql +61 -0
- package/dist/db/database.js +67 -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 +29 -1
- package/dist/mcp/tool-names.js.map +2 -2
- package/dist/mcp/tools.js +1588 -6
- 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 +5 -2
|
@@ -0,0 +1,341 @@
|
|
|
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_go = require("./go");
|
|
29
|
+
(0, import_vitest.describe)("parseGoManifest", () => {
|
|
30
|
+
let tmpDir;
|
|
31
|
+
(0, import_vitest.beforeEach)(() => {
|
|
32
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "kirograph-go-test-"));
|
|
33
|
+
});
|
|
34
|
+
(0, import_vitest.afterEach)(() => {
|
|
35
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
function writeGoMod(content, dir) {
|
|
38
|
+
const targetDir = dir ?? tmpDir;
|
|
39
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
40
|
+
const filePath = path.join(targetDir, "go.mod");
|
|
41
|
+
fs.writeFileSync(filePath, content);
|
|
42
|
+
return filePath;
|
|
43
|
+
}
|
|
44
|
+
function writeGoSum(content, dir) {
|
|
45
|
+
const targetDir = dir ?? tmpDir;
|
|
46
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
47
|
+
fs.writeFileSync(path.join(targetDir, "go.sum"), content);
|
|
48
|
+
}
|
|
49
|
+
(0, import_vitest.it)("extracts dependencies from require block", async () => {
|
|
50
|
+
const manifestPath = writeGoMod(`
|
|
51
|
+
module github.com/example/myproject
|
|
52
|
+
|
|
53
|
+
go 1.21
|
|
54
|
+
|
|
55
|
+
require (
|
|
56
|
+
github.com/gin-gonic/gin v1.9.1
|
|
57
|
+
github.com/stretchr/testify v1.8.4
|
|
58
|
+
)
|
|
59
|
+
`);
|
|
60
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
61
|
+
(0, import_vitest.expect)(deps).toHaveLength(2);
|
|
62
|
+
const gin = deps.find((d) => d.name === "github.com/gin-gonic/gin");
|
|
63
|
+
(0, import_vitest.expect)(gin).toBeDefined();
|
|
64
|
+
(0, import_vitest.expect)(gin.declaredConstraint).toBe("v1.9.1");
|
|
65
|
+
(0, import_vitest.expect)(gin.resolvedVersion).toBe("v1.9.1");
|
|
66
|
+
(0, import_vitest.expect)(gin.scope).toBe("production");
|
|
67
|
+
(0, import_vitest.expect)(gin.ecosystem).toBe("go");
|
|
68
|
+
const testify = deps.find((d) => d.name === "github.com/stretchr/testify");
|
|
69
|
+
(0, import_vitest.expect)(testify).toBeDefined();
|
|
70
|
+
(0, import_vitest.expect)(testify.declaredConstraint).toBe("v1.8.4");
|
|
71
|
+
(0, import_vitest.expect)(testify.resolvedVersion).toBe("v1.8.4");
|
|
72
|
+
});
|
|
73
|
+
(0, import_vitest.it)("extracts single-line require directives", async () => {
|
|
74
|
+
const manifestPath = writeGoMod(`
|
|
75
|
+
module github.com/example/myproject
|
|
76
|
+
|
|
77
|
+
go 1.21
|
|
78
|
+
|
|
79
|
+
require github.com/pkg/errors v0.9.1
|
|
80
|
+
require golang.org/x/text v0.14.0
|
|
81
|
+
`);
|
|
82
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
83
|
+
(0, import_vitest.expect)(deps).toHaveLength(2);
|
|
84
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/pkg/errors")).toBeDefined();
|
|
85
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "golang.org/x/text")).toBeDefined();
|
|
86
|
+
});
|
|
87
|
+
(0, import_vitest.it)("handles both block and single-line requires together", async () => {
|
|
88
|
+
const manifestPath = writeGoMod(`
|
|
89
|
+
module github.com/example/myproject
|
|
90
|
+
|
|
91
|
+
go 1.21
|
|
92
|
+
|
|
93
|
+
require github.com/pkg/errors v0.9.1
|
|
94
|
+
|
|
95
|
+
require (
|
|
96
|
+
github.com/gin-gonic/gin v1.9.1
|
|
97
|
+
github.com/stretchr/testify v1.8.4
|
|
98
|
+
)
|
|
99
|
+
`);
|
|
100
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
101
|
+
(0, import_vitest.expect)(deps).toHaveLength(3);
|
|
102
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/pkg/errors")).toBeDefined();
|
|
103
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/gin-gonic/gin")).toBeDefined();
|
|
104
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/stretchr/testify")).toBeDefined();
|
|
105
|
+
});
|
|
106
|
+
(0, import_vitest.it)("all dependencies have production scope", async () => {
|
|
107
|
+
const manifestPath = writeGoMod(`
|
|
108
|
+
module github.com/example/myproject
|
|
109
|
+
|
|
110
|
+
go 1.21
|
|
111
|
+
|
|
112
|
+
require (
|
|
113
|
+
github.com/gin-gonic/gin v1.9.1
|
|
114
|
+
github.com/stretchr/testify v1.8.4
|
|
115
|
+
)
|
|
116
|
+
`);
|
|
117
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
118
|
+
(0, import_vitest.expect)(deps.every((d) => d.scope === "production")).toBe(true);
|
|
119
|
+
});
|
|
120
|
+
(0, import_vitest.it)("sets declaredConstraint and resolvedVersion to the same value", async () => {
|
|
121
|
+
const manifestPath = writeGoMod(`
|
|
122
|
+
module github.com/example/myproject
|
|
123
|
+
|
|
124
|
+
go 1.21
|
|
125
|
+
|
|
126
|
+
require github.com/gin-gonic/gin v1.9.1
|
|
127
|
+
`);
|
|
128
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
129
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
130
|
+
(0, import_vitest.expect)(deps[0].declaredConstraint).toBe("v1.9.1");
|
|
131
|
+
(0, import_vitest.expect)(deps[0].resolvedVersion).toBe("v1.9.1");
|
|
132
|
+
});
|
|
133
|
+
(0, import_vitest.it)("skips comment lines in require block", async () => {
|
|
134
|
+
const manifestPath = writeGoMod(`
|
|
135
|
+
module github.com/example/myproject
|
|
136
|
+
|
|
137
|
+
go 1.21
|
|
138
|
+
|
|
139
|
+
require (
|
|
140
|
+
// This is a comment
|
|
141
|
+
github.com/gin-gonic/gin v1.9.1
|
|
142
|
+
// Another comment
|
|
143
|
+
github.com/stretchr/testify v1.8.4
|
|
144
|
+
)
|
|
145
|
+
`);
|
|
146
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
147
|
+
(0, import_vitest.expect)(deps).toHaveLength(2);
|
|
148
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/gin-gonic/gin")).toBeDefined();
|
|
149
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/stretchr/testify")).toBeDefined();
|
|
150
|
+
});
|
|
151
|
+
(0, import_vitest.it)("handles indirect dependencies (// indirect comment)", async () => {
|
|
152
|
+
const manifestPath = writeGoMod(`
|
|
153
|
+
module github.com/example/myproject
|
|
154
|
+
|
|
155
|
+
go 1.21
|
|
156
|
+
|
|
157
|
+
require (
|
|
158
|
+
github.com/gin-gonic/gin v1.9.1
|
|
159
|
+
golang.org/x/sys v0.15.0 // indirect
|
|
160
|
+
)
|
|
161
|
+
`);
|
|
162
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
163
|
+
(0, import_vitest.expect)(deps).toHaveLength(2);
|
|
164
|
+
const sys = deps.find((d) => d.name === "golang.org/x/sys");
|
|
165
|
+
(0, import_vitest.expect)(sys).toBeDefined();
|
|
166
|
+
(0, import_vitest.expect)(sys.declaredConstraint).toBe("v0.15.0");
|
|
167
|
+
});
|
|
168
|
+
(0, import_vitest.it)("handles pseudo-versions", async () => {
|
|
169
|
+
const manifestPath = writeGoMod(`
|
|
170
|
+
module github.com/example/myproject
|
|
171
|
+
|
|
172
|
+
go 1.21
|
|
173
|
+
|
|
174
|
+
require (
|
|
175
|
+
github.com/some/module v0.0.0-20230101120000-abcdef123456
|
|
176
|
+
)
|
|
177
|
+
`);
|
|
178
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
179
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
180
|
+
(0, import_vitest.expect)(deps[0].declaredConstraint).toBe("v0.0.0-20230101120000-abcdef123456");
|
|
181
|
+
(0, import_vitest.expect)(deps[0].resolvedVersion).toBe("v0.0.0-20230101120000-abcdef123456");
|
|
182
|
+
});
|
|
183
|
+
(0, import_vitest.it)("handles +incompatible versions", async () => {
|
|
184
|
+
const manifestPath = writeGoMod(`
|
|
185
|
+
module github.com/example/myproject
|
|
186
|
+
|
|
187
|
+
go 1.21
|
|
188
|
+
|
|
189
|
+
require github.com/some/legacy v3.2.1+incompatible
|
|
190
|
+
`);
|
|
191
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
192
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
193
|
+
(0, import_vitest.expect)(deps[0].declaredConstraint).toBe("v3.2.1+incompatible");
|
|
194
|
+
});
|
|
195
|
+
(0, import_vitest.it)("skips entries with invalid module paths", async () => {
|
|
196
|
+
const manifestPath = writeGoMod(`
|
|
197
|
+
module github.com/example/myproject
|
|
198
|
+
|
|
199
|
+
go 1.21
|
|
200
|
+
|
|
201
|
+
require (
|
|
202
|
+
github.com/valid/module v1.0.0
|
|
203
|
+
invalidpath v1.0.0
|
|
204
|
+
)
|
|
205
|
+
`);
|
|
206
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
207
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
208
|
+
(0, import_vitest.expect)(deps[0].name).toBe("github.com/valid/module");
|
|
209
|
+
});
|
|
210
|
+
(0, import_vitest.it)("skips entries with invalid version format", async () => {
|
|
211
|
+
const manifestPath = writeGoMod(`
|
|
212
|
+
module github.com/example/myproject
|
|
213
|
+
|
|
214
|
+
go 1.21
|
|
215
|
+
|
|
216
|
+
require (
|
|
217
|
+
github.com/valid/module v1.0.0
|
|
218
|
+
github.com/bad/version 1.0.0
|
|
219
|
+
github.com/bad/version2 latest
|
|
220
|
+
)
|
|
221
|
+
`);
|
|
222
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
223
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
224
|
+
(0, import_vitest.expect)(deps[0].name).toBe("github.com/valid/module");
|
|
225
|
+
});
|
|
226
|
+
(0, import_vitest.it)("returns empty array for unreadable file", async () => {
|
|
227
|
+
const deps = await (0, import_go.parseGoManifest)("/nonexistent/go.mod", tmpDir);
|
|
228
|
+
(0, import_vitest.expect)(deps).toEqual([]);
|
|
229
|
+
});
|
|
230
|
+
(0, import_vitest.it)("returns empty array for go.mod with no require directives", async () => {
|
|
231
|
+
const manifestPath = writeGoMod(`
|
|
232
|
+
module github.com/example/myproject
|
|
233
|
+
|
|
234
|
+
go 1.21
|
|
235
|
+
`);
|
|
236
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
237
|
+
(0, import_vitest.expect)(deps).toEqual([]);
|
|
238
|
+
});
|
|
239
|
+
(0, import_vitest.it)("sets sourceManifest as relative path", async () => {
|
|
240
|
+
const subDir = path.join(tmpDir, "services", "api");
|
|
241
|
+
const manifestPath = writeGoMod(`
|
|
242
|
+
module github.com/example/api
|
|
243
|
+
|
|
244
|
+
go 1.21
|
|
245
|
+
|
|
246
|
+
require github.com/gin-gonic/gin v1.9.1
|
|
247
|
+
`, subDir);
|
|
248
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
249
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
250
|
+
(0, import_vitest.expect)(deps[0].sourceManifest).toBe("services/api/go.mod");
|
|
251
|
+
});
|
|
252
|
+
(0, import_vitest.it)("reads go.sum for integrity verification", async () => {
|
|
253
|
+
const manifestPath = writeGoMod(`
|
|
254
|
+
module github.com/example/myproject
|
|
255
|
+
|
|
256
|
+
go 1.21
|
|
257
|
+
|
|
258
|
+
require github.com/gin-gonic/gin v1.9.1
|
|
259
|
+
`);
|
|
260
|
+
writeGoSum(`github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqFPSKw=
|
|
261
|
+
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL/0KcuqOSEXQHxOGZp0Lg2g/4wZIgGMnG3w3gI=
|
|
262
|
+
`);
|
|
263
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
264
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
265
|
+
(0, import_vitest.expect)(deps[0].name).toBe("github.com/gin-gonic/gin");
|
|
266
|
+
(0, import_vitest.expect)(deps[0].resolvedVersion).toBe("v1.9.1");
|
|
267
|
+
});
|
|
268
|
+
(0, import_vitest.it)("handles go.mod with multiple require blocks", async () => {
|
|
269
|
+
const manifestPath = writeGoMod(`
|
|
270
|
+
module github.com/example/myproject
|
|
271
|
+
|
|
272
|
+
go 1.21
|
|
273
|
+
|
|
274
|
+
require (
|
|
275
|
+
github.com/gin-gonic/gin v1.9.1
|
|
276
|
+
)
|
|
277
|
+
|
|
278
|
+
require (
|
|
279
|
+
golang.org/x/text v0.14.0
|
|
280
|
+
golang.org/x/sys v0.15.0
|
|
281
|
+
)
|
|
282
|
+
`);
|
|
283
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
284
|
+
(0, import_vitest.expect)(deps).toHaveLength(3);
|
|
285
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "github.com/gin-gonic/gin")).toBeDefined();
|
|
286
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "golang.org/x/text")).toBeDefined();
|
|
287
|
+
(0, import_vitest.expect)(deps.find((d) => d.name === "golang.org/x/sys")).toBeDefined();
|
|
288
|
+
});
|
|
289
|
+
(0, import_vitest.it)("handles empty require block", async () => {
|
|
290
|
+
const manifestPath = writeGoMod(`
|
|
291
|
+
module github.com/example/myproject
|
|
292
|
+
|
|
293
|
+
go 1.21
|
|
294
|
+
|
|
295
|
+
require (
|
|
296
|
+
)
|
|
297
|
+
`);
|
|
298
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
299
|
+
(0, import_vitest.expect)(deps).toEqual([]);
|
|
300
|
+
});
|
|
301
|
+
(0, import_vitest.it)("handles pre-release versions", async () => {
|
|
302
|
+
const manifestPath = writeGoMod(`
|
|
303
|
+
module github.com/example/myproject
|
|
304
|
+
|
|
305
|
+
go 1.21
|
|
306
|
+
|
|
307
|
+
require github.com/some/module v1.2.3-beta.1
|
|
308
|
+
`);
|
|
309
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
310
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
311
|
+
(0, import_vitest.expect)(deps[0].declaredConstraint).toBe("v1.2.3-beta.1");
|
|
312
|
+
});
|
|
313
|
+
(0, import_vitest.it)("works without go.sum present", async () => {
|
|
314
|
+
const manifestPath = writeGoMod(`
|
|
315
|
+
module github.com/example/myproject
|
|
316
|
+
|
|
317
|
+
go 1.21
|
|
318
|
+
|
|
319
|
+
require github.com/gin-gonic/gin v1.9.1
|
|
320
|
+
`);
|
|
321
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
322
|
+
(0, import_vitest.expect)(deps).toHaveLength(1);
|
|
323
|
+
(0, import_vitest.expect)(deps[0].name).toBe("github.com/gin-gonic/gin");
|
|
324
|
+
(0, import_vitest.expect)(deps[0].resolvedVersion).toBe("v1.9.1");
|
|
325
|
+
});
|
|
326
|
+
(0, import_vitest.it)("sets ecosystem to go for all dependencies", async () => {
|
|
327
|
+
const manifestPath = writeGoMod(`
|
|
328
|
+
module github.com/example/myproject
|
|
329
|
+
|
|
330
|
+
go 1.21
|
|
331
|
+
|
|
332
|
+
require (
|
|
333
|
+
github.com/gin-gonic/gin v1.9.1
|
|
334
|
+
golang.org/x/text v0.14.0
|
|
335
|
+
)
|
|
336
|
+
`);
|
|
337
|
+
const deps = await (0, import_go.parseGoManifest)(manifestPath, tmpDir);
|
|
338
|
+
(0, import_vitest.expect)(deps.every((d) => d.ecosystem === "go")).toBe(true);
|
|
339
|
+
});
|
|
340
|
+
});
|
|
341
|
+
//# sourceMappingURL=go.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/security/manifest/plugins/go.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Unit tests for the Go security manifest plugin.\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 { parseGoManifest } from './go';\n\ndescribe('parseGoManifest', () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'kirograph-go-test-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n function writeGoMod(content: string, dir?: string): string {\n const targetDir = dir ?? tmpDir;\n fs.mkdirSync(targetDir, { recursive: true });\n const filePath = path.join(targetDir, 'go.mod');\n fs.writeFileSync(filePath, content);\n return filePath;\n }\n\n function writeGoSum(content: string, dir?: string): void {\n const targetDir = dir ?? tmpDir;\n fs.mkdirSync(targetDir, { recursive: true });\n fs.writeFileSync(path.join(targetDir, 'go.sum'), content);\n }\n\n it('extracts dependencies from require block', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n\tgithub.com/stretchr/testify v1.8.4\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(2);\n const gin = deps.find(d => d.name === 'github.com/gin-gonic/gin');\n expect(gin).toBeDefined();\n expect(gin!.declaredConstraint).toBe('v1.9.1');\n expect(gin!.resolvedVersion).toBe('v1.9.1');\n expect(gin!.scope).toBe('production');\n expect(gin!.ecosystem).toBe('go');\n\n const testify = deps.find(d => d.name === 'github.com/stretchr/testify');\n expect(testify).toBeDefined();\n expect(testify!.declaredConstraint).toBe('v1.8.4');\n expect(testify!.resolvedVersion).toBe('v1.8.4');\n });\n\n it('extracts single-line require directives', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/pkg/errors v0.9.1\nrequire golang.org/x/text v0.14.0\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(2);\n expect(deps.find(d => d.name === 'github.com/pkg/errors')).toBeDefined();\n expect(deps.find(d => d.name === 'golang.org/x/text')).toBeDefined();\n });\n\n it('handles both block and single-line requires together', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/pkg/errors v0.9.1\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n\tgithub.com/stretchr/testify v1.8.4\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(3);\n expect(deps.find(d => d.name === 'github.com/pkg/errors')).toBeDefined();\n expect(deps.find(d => d.name === 'github.com/gin-gonic/gin')).toBeDefined();\n expect(deps.find(d => d.name === 'github.com/stretchr/testify')).toBeDefined();\n });\n\n it('all dependencies have production scope', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n\tgithub.com/stretchr/testify v1.8.4\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps.every(d => d.scope === 'production')).toBe(true);\n });\n\n it('sets declaredConstraint and resolvedVersion to the same value', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/gin-gonic/gin v1.9.1\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].declaredConstraint).toBe('v1.9.1');\n expect(deps[0].resolvedVersion).toBe('v1.9.1');\n });\n\n it('skips comment lines in require block', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\t// This is a comment\n\tgithub.com/gin-gonic/gin v1.9.1\n\t// Another comment\n\tgithub.com/stretchr/testify v1.8.4\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(2);\n expect(deps.find(d => d.name === 'github.com/gin-gonic/gin')).toBeDefined();\n expect(deps.find(d => d.name === 'github.com/stretchr/testify')).toBeDefined();\n });\n\n it('handles indirect dependencies (// indirect comment)', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n\tgolang.org/x/sys v0.15.0 // indirect\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(2);\n const sys = deps.find(d => d.name === 'golang.org/x/sys');\n expect(sys).toBeDefined();\n expect(sys!.declaredConstraint).toBe('v0.15.0');\n });\n\n it('handles pseudo-versions', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/some/module v0.0.0-20230101120000-abcdef123456\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].declaredConstraint).toBe('v0.0.0-20230101120000-abcdef123456');\n expect(deps[0].resolvedVersion).toBe('v0.0.0-20230101120000-abcdef123456');\n });\n\n it('handles +incompatible versions', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/some/legacy v3.2.1+incompatible\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].declaredConstraint).toBe('v3.2.1+incompatible');\n });\n\n it('skips entries with invalid module paths', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/valid/module v1.0.0\n\tinvalidpath v1.0.0\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].name).toBe('github.com/valid/module');\n });\n\n it('skips entries with invalid version format', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/valid/module v1.0.0\n\tgithub.com/bad/version 1.0.0\n\tgithub.com/bad/version2 latest\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].name).toBe('github.com/valid/module');\n });\n\n it('returns empty array for unreadable file', async () => {\n const deps = await parseGoManifest('/nonexistent/go.mod', tmpDir);\n expect(deps).toEqual([]);\n });\n\n it('returns empty array for go.mod with no require directives', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n expect(deps).toEqual([]);\n });\n\n it('sets sourceManifest as relative path', async () => {\n const subDir = path.join(tmpDir, 'services', 'api');\n const manifestPath = writeGoMod(`\nmodule github.com/example/api\n\ngo 1.21\n\nrequire github.com/gin-gonic/gin v1.9.1\n`, subDir);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].sourceManifest).toBe('services/api/go.mod');\n });\n\n it('reads go.sum for integrity verification', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/gin-gonic/gin v1.9.1\n`);\n\n writeGoSum(`github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqFPSKw=\ngithub.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL/0KcuqOSEXQHxOGZp0Lg2g/4wZIgGMnG3w3gI=\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n // The dependency should still be extracted correctly\n // go.sum is used for integrity verification awareness\n expect(deps).toHaveLength(1);\n expect(deps[0].name).toBe('github.com/gin-gonic/gin');\n expect(deps[0].resolvedVersion).toBe('v1.9.1');\n });\n\n it('handles go.mod with multiple require blocks', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n)\n\nrequire (\n\tgolang.org/x/text v0.14.0\n\tgolang.org/x/sys v0.15.0\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(3);\n expect(deps.find(d => d.name === 'github.com/gin-gonic/gin')).toBeDefined();\n expect(deps.find(d => d.name === 'golang.org/x/text')).toBeDefined();\n expect(deps.find(d => d.name === 'golang.org/x/sys')).toBeDefined();\n });\n\n it('handles empty require block', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n expect(deps).toEqual([]);\n });\n\n it('handles pre-release versions', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/some/module v1.2.3-beta.1\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].declaredConstraint).toBe('v1.2.3-beta.1');\n });\n\n it('works without go.sum present', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire github.com/gin-gonic/gin v1.9.1\n`);\n\n // No go.sum written\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps).toHaveLength(1);\n expect(deps[0].name).toBe('github.com/gin-gonic/gin');\n expect(deps[0].resolvedVersion).toBe('v1.9.1');\n });\n\n it('sets ecosystem to go for all dependencies', async () => {\n const manifestPath = writeGoMod(`\nmodule github.com/example/myproject\n\ngo 1.21\n\nrequire (\n\tgithub.com/gin-gonic/gin v1.9.1\n\tgolang.org/x/text v0.14.0\n)\n`);\n\n const deps = await parseGoManifest(manifestPath, tmpDir);\n\n expect(deps.every(d => d.ecosystem === 'go')).toBe(true);\n });\n});\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
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 __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var gradle_exports = {};
|
|
30
|
+
__export(gradle_exports, {
|
|
31
|
+
parseGradleManifest: () => parseGradleManifest
|
|
32
|
+
});
|
|
33
|
+
module.exports = __toCommonJS(gradle_exports);
|
|
34
|
+
var fs = __toESM(require("fs"));
|
|
35
|
+
var path = __toESM(require("path"));
|
|
36
|
+
var import_errors = require("../../../errors");
|
|
37
|
+
const TEST_CONFIGURATIONS = /* @__PURE__ */ new Set([
|
|
38
|
+
"testimplementation",
|
|
39
|
+
"testapi",
|
|
40
|
+
"testcompile",
|
|
41
|
+
"testruntimeonly",
|
|
42
|
+
"androidtestimplementation",
|
|
43
|
+
"androidtestapi"
|
|
44
|
+
]);
|
|
45
|
+
const KNOWN_CONFIGURATIONS = [
|
|
46
|
+
"androidTestImplementation",
|
|
47
|
+
"androidTestApi",
|
|
48
|
+
"debugImplementation",
|
|
49
|
+
"releaseImplementation",
|
|
50
|
+
"testImplementation",
|
|
51
|
+
"testRuntimeOnly",
|
|
52
|
+
"testCompile",
|
|
53
|
+
"testApi",
|
|
54
|
+
"implementation",
|
|
55
|
+
"runtimeOnly",
|
|
56
|
+
"compileOnly",
|
|
57
|
+
"compile",
|
|
58
|
+
"api"
|
|
59
|
+
];
|
|
60
|
+
async function parseGradleManifest(manifestPath, projectRoot) {
|
|
61
|
+
const manifestDir = path.dirname(manifestPath);
|
|
62
|
+
const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\/g, "/");
|
|
63
|
+
let content;
|
|
64
|
+
try {
|
|
65
|
+
content = fs.readFileSync(manifestPath, "utf8");
|
|
66
|
+
} catch (err) {
|
|
67
|
+
(0, import_errors.logWarn)(`[sec:gradle] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);
|
|
68
|
+
return [];
|
|
69
|
+
}
|
|
70
|
+
const resolvedVersions = loadResolvedVersions(manifestDir);
|
|
71
|
+
const dependencies = [];
|
|
72
|
+
const configPattern = KNOWN_CONFIGURATIONS.map((c) => escapeRegex(c)).join("|");
|
|
73
|
+
const depRegex = new RegExp(
|
|
74
|
+
`^\\s*(${configPattern})\\s*\\(?\\s*["']([^"']+)["']\\s*\\)?`,
|
|
75
|
+
"gmi"
|
|
76
|
+
);
|
|
77
|
+
let match;
|
|
78
|
+
while ((match = depRegex.exec(content)) !== null) {
|
|
79
|
+
const configuration = match[1];
|
|
80
|
+
const notation = match[2].trim();
|
|
81
|
+
const dep = parseGradleNotation(notation, configuration, relativeManifest);
|
|
82
|
+
if (!dep) continue;
|
|
83
|
+
const lookupKey = `${dep.group}:${dep.artifact}`.toLowerCase();
|
|
84
|
+
const resolvedVersion = resolvedVersions.get(lookupKey);
|
|
85
|
+
dependencies.push({
|
|
86
|
+
name: `${dep.group}:${dep.artifact}`,
|
|
87
|
+
declaredConstraint: dep.version,
|
|
88
|
+
resolvedVersion,
|
|
89
|
+
scope: resolveScope(configuration),
|
|
90
|
+
ecosystem: "gradle",
|
|
91
|
+
sourceManifest: relativeManifest
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return dependencies;
|
|
95
|
+
}
|
|
96
|
+
function parseGradleNotation(notation, configuration, relativeManifest) {
|
|
97
|
+
if (notation.startsWith("libs.") || notation.startsWith("libs(")) {
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
const parts = notation.split(":");
|
|
101
|
+
if (parts.length < 2) {
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
const group = parts[0].trim();
|
|
105
|
+
const artifact = parts[1].trim();
|
|
106
|
+
const version = parts.length >= 3 ? parts[2].trim() : "";
|
|
107
|
+
if (!group || !artifact) {
|
|
108
|
+
(0, import_errors.logWarn)(`[sec:gradle] Empty group or artifact in notation "${notation}" (${configuration}) at ${relativeManifest} \u2014 skipping`);
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
const normalizedVersion = version === "" || version === "+" || version.toLowerCase() === "latest.release" ? "*" : version;
|
|
112
|
+
return { group, artifact, version: normalizedVersion };
|
|
113
|
+
}
|
|
114
|
+
function resolveScope(configuration) {
|
|
115
|
+
return TEST_CONFIGURATIONS.has(configuration.toLowerCase()) ? "development" : "production";
|
|
116
|
+
}
|
|
117
|
+
function loadResolvedVersions(manifestDir) {
|
|
118
|
+
const map = /* @__PURE__ */ new Map();
|
|
119
|
+
const lockPath = path.join(manifestDir, "gradle.lockfile");
|
|
120
|
+
if (!fs.existsSync(lockPath)) {
|
|
121
|
+
return map;
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
124
|
+
const content = fs.readFileSync(lockPath, "utf8");
|
|
125
|
+
extractFromGradleLockfile(content, map);
|
|
126
|
+
} catch (err) {
|
|
127
|
+
(0, import_errors.logWarn)(`[sec:gradle] Failed to parse gradle.lockfile: ${err instanceof Error ? err.message : String(err)}`);
|
|
128
|
+
}
|
|
129
|
+
return map;
|
|
130
|
+
}
|
|
131
|
+
function extractFromGradleLockfile(content, map) {
|
|
132
|
+
const lines = content.split("\n");
|
|
133
|
+
for (const line of lines) {
|
|
134
|
+
const trimmed = line.trim();
|
|
135
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
136
|
+
if (trimmed === "empty=") continue;
|
|
137
|
+
const eqIndex = trimmed.indexOf("=");
|
|
138
|
+
if (eqIndex === -1) continue;
|
|
139
|
+
const coordinate = trimmed.slice(0, eqIndex).trim();
|
|
140
|
+
const parts = coordinate.split(":");
|
|
141
|
+
if (parts.length < 3) continue;
|
|
142
|
+
const group = parts[0].trim();
|
|
143
|
+
const artifact = parts[1].trim();
|
|
144
|
+
const version = parts[2].trim();
|
|
145
|
+
if (!group || !artifact || !version) continue;
|
|
146
|
+
const key = `${group}:${artifact}`.toLowerCase();
|
|
147
|
+
if (!map.has(key)) {
|
|
148
|
+
map.set(key, version);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function escapeRegex(str) {
|
|
153
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
154
|
+
}
|
|
155
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
156
|
+
0 && (module.exports = {
|
|
157
|
+
parseGradleManifest
|
|
158
|
+
});
|
|
159
|
+
//# sourceMappingURL=gradle.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/security/manifest/plugins/gradle.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Gradle Version Extraction Plugin for KiroGraph-Sec\n *\n * Extends the existing architecture gradle parser to extract version constraints,\n * resolved versions (from gradle.lockfile), and dependency scopes for security analysis.\n *\n * Reuses `gradleParser` from `src/architecture/manifest/gradle.ts` for discovery and\n * basic parsing, then layers on version/scope extraction.\n *\n * Handles Groovy DSL (`build.gradle`) and Kotlin DSL (`build.gradle.kts`):\n * - Groovy: `implementation 'group:artifact:version'`\n * - Kotlin: `implementation(\"group:artifact:version\")`\n * - Configuration variants: `api`, `compile`, `testImplementation`, `testApi`,\n * `androidTestImplementation`, `debugImplementation`, `releaseImplementation`\n * - Version catalog references (`libs.someDep`) are skipped \u2014 no version available\n * - Lock file: `gradle.lockfile` for resolved versions\n */\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport type { ParsedDependency } from '../../types';\nimport { logWarn } from '../../../errors';\n\n/**\n * Gradle dependency configurations mapped to ParsedDependency scope.\n * Configurations not listed here are treated as 'production'.\n */\nconst TEST_CONFIGURATIONS = new Set([\n 'testimplementation',\n 'testapi',\n 'testcompile',\n 'testruntimeonly',\n 'androidtestimplementation',\n 'androidtestapi',\n]);\n\n/**\n * All known Gradle dependency configuration prefixes we parse.\n * Listed from longest to shortest so regex alternation matches greedily.\n */\nconst KNOWN_CONFIGURATIONS = [\n 'androidTestImplementation',\n 'androidTestApi',\n 'debugImplementation',\n 'releaseImplementation',\n 'testImplementation',\n 'testRuntimeOnly',\n 'testCompile',\n 'testApi',\n 'implementation',\n 'runtimeOnly',\n 'compileOnly',\n 'compile',\n 'api',\n];\n\n/**\n * Resolved version map: `group:artifact` (lower-cased) \u2192 resolved version string.\n * Built from gradle.lockfile.\n */\ntype ResolvedVersionMap = Map<string, string>;\n\n/**\n * Parse a Gradle build script (`build.gradle` or `build.gradle.kts`) and extract\n * dependency declarations with version constraints, scopes, and resolved versions\n * from `gradle.lockfile`.\n *\n * @param manifestPath - Absolute path to the build.gradle or build.gradle.kts file\n * @param projectRoot - Absolute path to the project root directory\n * @returns Array of parsed dependencies with version and scope information\n */\nexport async function parseGradleManifest(\n manifestPath: string,\n projectRoot: string,\n): Promise<ParsedDependency[]> {\n const manifestDir = path.dirname(manifestPath);\n const relativeManifest = path.relative(projectRoot, manifestPath).replace(/\\\\/g, '/');\n\n // Read the build script content\n let content: string;\n try {\n content = fs.readFileSync(manifestPath, 'utf8');\n } catch (err) {\n logWarn(`[sec:gradle] Failed to read ${relativeManifest}: ${err instanceof Error ? err.message : String(err)}`);\n return [];\n }\n\n // Attempt to load resolved versions from gradle.lockfile\n const resolvedVersions = loadResolvedVersions(manifestDir);\n\n const dependencies: ParsedDependency[] = [];\n\n // Build a regex that matches any known configuration followed by a dependency notation\n // Groovy DSL: implementation 'group:artifact:version'\n // implementation \"group:artifact:version\"\n // Kotlin DSL: implementation(\"group:artifact:version\")\n const configPattern = KNOWN_CONFIGURATIONS.map(c => escapeRegex(c)).join('|');\n // Match: <config> [optional (] ['\"] group:artifact:version ['\"] [optional )]\n const depRegex = new RegExp(\n `^\\\\s*(${configPattern})\\\\s*\\\\(?\\\\s*[\"']([^\"']+)[\"']\\\\s*\\\\)?`,\n 'gmi',\n );\n\n let match: RegExpExecArray | null;\n while ((match = depRegex.exec(content)) !== null) {\n const configuration = match[1];\n const notation = match[2].trim();\n\n const dep = parseGradleNotation(notation, configuration, relativeManifest);\n if (!dep) continue;\n\n const lookupKey = `${dep.group}:${dep.artifact}`.toLowerCase();\n const resolvedVersion = resolvedVersions.get(lookupKey);\n\n dependencies.push({\n name: `${dep.group}:${dep.artifact}`,\n declaredConstraint: dep.version,\n resolvedVersion,\n scope: resolveScope(configuration),\n ecosystem: 'gradle',\n sourceManifest: relativeManifest,\n });\n }\n\n return dependencies;\n}\n\n/**\n * A parsed Gradle dependency notation (group:artifact:version).\n */\ninterface GradleCoordinate {\n group: string;\n artifact: string;\n version: string;\n}\n\n/**\n * Parse a Gradle dependency notation string of the form `group:artifact:version`.\n *\n * Skips version catalog references (e.g. `libs.someDep`) and notations\n * that do not follow the three-part `group:artifact:version` format.\n */\nfunction parseGradleNotation(\n notation: string,\n configuration: string,\n relativeManifest: string,\n): GradleCoordinate | null {\n // Skip version catalog references \u2014 they don't carry version info\n if (notation.startsWith('libs.') || notation.startsWith('libs(')) {\n return null;\n }\n\n const parts = notation.split(':');\n if (parts.length < 2) {\n // Not a standard Maven/Gradle coordinate \u2014 skip silently\n return null;\n }\n\n const group = parts[0].trim();\n const artifact = parts[1].trim();\n const version = parts.length >= 3 ? parts[2].trim() : '';\n\n if (!group || !artifact) {\n logWarn(`[sec:gradle] Empty group or artifact in notation \"${notation}\" (${configuration}) at ${relativeManifest} \u2014 skipping`);\n return null;\n }\n\n // Dynamic/incomplete versions (e.g. \"+\", \"\", \"latest.release\") use \"*\" sentinel\n const normalizedVersion =\n version === '' || version === '+' || version.toLowerCase() === 'latest.release'\n ? '*'\n : version;\n\n return { group, artifact, version: normalizedVersion };\n}\n\n/**\n * Map a Gradle configuration name to a ParsedDependency scope.\n *\n * Test configurations (`testImplementation`, `testApi`, etc.) map to 'development'.\n * All others (including `implementation`, `api`, `compile`, etc.) map to 'production'.\n */\nfunction resolveScope(configuration: string): ParsedDependency['scope'] {\n return TEST_CONFIGURATIONS.has(configuration.toLowerCase()) ? 'development' : 'production';\n}\n\n/**\n * Attempt to load resolved versions from `gradle.lockfile` in the given directory.\n * Returns an empty map if the lock file is not available.\n *\n * gradle.lockfile format (one entry per line):\n * ```\n * # This is a comment\n * com.google.guava:guava:32.1.2-jre=compileClasspath,runtimeClasspath\n * junit:junit:4.13.2=testCompileClasspath,testRuntimeClasspath\n * empty=\n * ```\n */\nfunction loadResolvedVersions(manifestDir: string): ResolvedVersionMap {\n const map: ResolvedVersionMap = new Map();\n\n const lockPath = path.join(manifestDir, 'gradle.lockfile');\n if (!fs.existsSync(lockPath)) {\n return map;\n }\n\n try {\n const content = fs.readFileSync(lockPath, 'utf8');\n extractFromGradleLockfile(content, map);\n } catch (err) {\n logWarn(`[sec:gradle] Failed to parse gradle.lockfile: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n return map;\n}\n\n/**\n * Extract resolved versions from gradle.lockfile content.\n *\n * Each non-comment, non-empty line has the form:\n * `group:artifact:version=configurationList`\n *\n * The special line `empty=` indicates no locked dependencies and is ignored.\n */\nfunction extractFromGradleLockfile(content: string, map: ResolvedVersionMap): void {\n const lines = content.split('\\n');\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip comments and empty lines\n if (trimmed === '' || trimmed.startsWith('#')) continue;\n\n // Skip the sentinel \"empty=\" line\n if (trimmed === 'empty=') continue;\n\n // Format: group:artifact:version=configurationList\n const eqIndex = trimmed.indexOf('=');\n if (eqIndex === -1) continue;\n\n const coordinate = trimmed.slice(0, eqIndex).trim();\n const parts = coordinate.split(':');\n if (parts.length < 3) continue;\n\n const group = parts[0].trim();\n const artifact = parts[1].trim();\n const version = parts[2].trim();\n\n if (!group || !artifact || !version) continue;\n\n const key = `${group}:${artifact}`.toLowerCase();\n if (!map.has(key)) {\n map.set(key, version);\n }\n }\n}\n\n/**\n * Escape special regex characters in a string.\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|