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,272 @@
|
|
|
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_adapter = require("./adapter");
|
|
29
|
+
(0, import_vitest.describe)("SecurityManifestAdapter", () => {
|
|
30
|
+
let tmpDir;
|
|
31
|
+
(0, import_vitest.beforeEach)(() => {
|
|
32
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), "sec-adapter-test-"));
|
|
33
|
+
});
|
|
34
|
+
(0, import_vitest.afterEach)(() => {
|
|
35
|
+
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
36
|
+
});
|
|
37
|
+
(0, import_vitest.describe)("constructor", () => {
|
|
38
|
+
(0, import_vitest.it)("should initialize with architecture parsers", () => {
|
|
39
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
40
|
+
const parsers = adapter.getArchParsers();
|
|
41
|
+
(0, import_vitest.expect)(parsers.length).toBeGreaterThan(0);
|
|
42
|
+
const names = parsers.map((p) => p.name);
|
|
43
|
+
(0, import_vitest.expect)(names).toContain("npm");
|
|
44
|
+
(0, import_vitest.expect)(names).toContain("cargo");
|
|
45
|
+
(0, import_vitest.expect)(names).toContain("go");
|
|
46
|
+
(0, import_vitest.expect)(names).toContain("maven");
|
|
47
|
+
(0, import_vitest.expect)(names).toContain("python");
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
(0, import_vitest.describe)("registerPlugin", () => {
|
|
51
|
+
(0, import_vitest.it)("should register and retrieve a version extraction plugin", () => {
|
|
52
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
53
|
+
const plugin = {
|
|
54
|
+
ecosystem: "npm",
|
|
55
|
+
manifestFiles: ["package.json"],
|
|
56
|
+
canExtract: (p) => path.basename(p) === "package.json",
|
|
57
|
+
extract: async () => []
|
|
58
|
+
};
|
|
59
|
+
adapter.registerPlugin(plugin);
|
|
60
|
+
const plugins = adapter.getPlugins();
|
|
61
|
+
(0, import_vitest.expect)(plugins).toHaveLength(1);
|
|
62
|
+
(0, import_vitest.expect)(plugins[0].ecosystem).toBe("npm");
|
|
63
|
+
});
|
|
64
|
+
(0, import_vitest.it)("should overwrite plugin for same ecosystem", () => {
|
|
65
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
66
|
+
const plugin1 = {
|
|
67
|
+
ecosystem: "npm",
|
|
68
|
+
manifestFiles: ["package.json"],
|
|
69
|
+
canExtract: () => true,
|
|
70
|
+
extract: async () => [{ name: "a", declaredConstraint: "1.0", scope: "production", ecosystem: "npm", sourceManifest: "package.json" }]
|
|
71
|
+
};
|
|
72
|
+
const plugin2 = {
|
|
73
|
+
ecosystem: "npm",
|
|
74
|
+
manifestFiles: ["package.json"],
|
|
75
|
+
canExtract: () => true,
|
|
76
|
+
extract: async () => [{ name: "b", declaredConstraint: "2.0", scope: "development", ecosystem: "npm", sourceManifest: "package.json" }]
|
|
77
|
+
};
|
|
78
|
+
adapter.registerPlugin(plugin1);
|
|
79
|
+
adapter.registerPlugin(plugin2);
|
|
80
|
+
const plugins = adapter.getPlugins();
|
|
81
|
+
(0, import_vitest.expect)(plugins).toHaveLength(1);
|
|
82
|
+
(0, import_vitest.expect)(plugins[0]).toBe(plugin2);
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
(0, import_vitest.describe)("discoverManifests", () => {
|
|
86
|
+
(0, import_vitest.it)("should discover package.json files", () => {
|
|
87
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "test", dependencies: { express: "^4.0.0" } }));
|
|
88
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
89
|
+
const manifests = adapter.discoverManifests();
|
|
90
|
+
(0, import_vitest.expect)(manifests).toHaveLength(1);
|
|
91
|
+
(0, import_vitest.expect)(manifests[0]).toBe(path.join(tmpDir, "package.json"));
|
|
92
|
+
});
|
|
93
|
+
(0, import_vitest.it)("should discover nested manifest files", () => {
|
|
94
|
+
fs.mkdirSync(path.join(tmpDir, "sub"));
|
|
95
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "root" }));
|
|
96
|
+
fs.writeFileSync(path.join(tmpDir, "sub", "package.json"), JSON.stringify({ name: "sub" }));
|
|
97
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
98
|
+
const manifests = adapter.discoverManifests();
|
|
99
|
+
(0, import_vitest.expect)(manifests).toHaveLength(2);
|
|
100
|
+
});
|
|
101
|
+
(0, import_vitest.it)("should skip node_modules directory", () => {
|
|
102
|
+
fs.mkdirSync(path.join(tmpDir, "node_modules"));
|
|
103
|
+
fs.writeFileSync(path.join(tmpDir, "node_modules", "package.json"), JSON.stringify({ name: "dep" }));
|
|
104
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "root" }));
|
|
105
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
106
|
+
const manifests = adapter.discoverManifests();
|
|
107
|
+
(0, import_vitest.expect)(manifests).toHaveLength(1);
|
|
108
|
+
(0, import_vitest.expect)(manifests[0]).toBe(path.join(tmpDir, "package.json"));
|
|
109
|
+
});
|
|
110
|
+
(0, import_vitest.it)("should skip .git directory", () => {
|
|
111
|
+
fs.mkdirSync(path.join(tmpDir, ".git"));
|
|
112
|
+
fs.writeFileSync(path.join(tmpDir, ".git", "package.json"), JSON.stringify({ name: "git" }));
|
|
113
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "root" }));
|
|
114
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
115
|
+
const manifests = adapter.discoverManifests();
|
|
116
|
+
(0, import_vitest.expect)(manifests).toHaveLength(1);
|
|
117
|
+
});
|
|
118
|
+
(0, import_vitest.it)("should skip dist and build directories", () => {
|
|
119
|
+
fs.mkdirSync(path.join(tmpDir, "dist"));
|
|
120
|
+
fs.mkdirSync(path.join(tmpDir, "build"));
|
|
121
|
+
fs.writeFileSync(path.join(tmpDir, "dist", "package.json"), JSON.stringify({ name: "dist" }));
|
|
122
|
+
fs.writeFileSync(path.join(tmpDir, "build", "package.json"), JSON.stringify({ name: "build" }));
|
|
123
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "root" }));
|
|
124
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
125
|
+
const manifests = adapter.discoverManifests();
|
|
126
|
+
(0, import_vitest.expect)(manifests).toHaveLength(1);
|
|
127
|
+
});
|
|
128
|
+
(0, import_vitest.it)("should discover multiple ecosystem manifests", () => {
|
|
129
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({ name: "js-project" }));
|
|
130
|
+
fs.writeFileSync(path.join(tmpDir, "Cargo.toml"), '[package]\nname = "rust-project"\nversion = "0.1.0"');
|
|
131
|
+
fs.writeFileSync(path.join(tmpDir, "go.mod"), "module example.com/mymod\n\ngo 1.21");
|
|
132
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
133
|
+
const manifests = adapter.discoverManifests();
|
|
134
|
+
(0, import_vitest.expect)(manifests).toHaveLength(3);
|
|
135
|
+
});
|
|
136
|
+
(0, import_vitest.it)("should return empty array for empty directory", () => {
|
|
137
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
138
|
+
const manifests = adapter.discoverManifests();
|
|
139
|
+
(0, import_vitest.expect)(manifests).toHaveLength(0);
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
(0, import_vitest.describe)("getEcosystem", () => {
|
|
143
|
+
(0, import_vitest.it)("should return npm for package.json", () => {
|
|
144
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
145
|
+
(0, import_vitest.expect)(adapter.getEcosystem("/some/path/package.json")).toBe("npm");
|
|
146
|
+
});
|
|
147
|
+
(0, import_vitest.it)("should return cargo for Cargo.toml", () => {
|
|
148
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
149
|
+
(0, import_vitest.expect)(adapter.getEcosystem("/some/path/Cargo.toml")).toBe("cargo");
|
|
150
|
+
});
|
|
151
|
+
(0, import_vitest.it)("should return go for go.mod", () => {
|
|
152
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
153
|
+
(0, import_vitest.expect)(adapter.getEcosystem("/some/path/go.mod")).toBe("go");
|
|
154
|
+
});
|
|
155
|
+
(0, import_vitest.it)("should return maven for pom.xml", () => {
|
|
156
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
157
|
+
(0, import_vitest.expect)(adapter.getEcosystem("/some/path/pom.xml")).toBe("maven");
|
|
158
|
+
});
|
|
159
|
+
(0, import_vitest.it)("should return undefined for unknown files", () => {
|
|
160
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
161
|
+
(0, import_vitest.expect)(adapter.getEcosystem("/some/path/unknown.txt")).toBeUndefined();
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
(0, import_vitest.describe)("extractAll", () => {
|
|
165
|
+
(0, import_vitest.it)("should use registered plugin for extraction", async () => {
|
|
166
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({
|
|
167
|
+
name: "test-project",
|
|
168
|
+
dependencies: { express: "^4.18.0", lodash: "~4.17.21" },
|
|
169
|
+
devDependencies: { vitest: "^1.0.0" }
|
|
170
|
+
}));
|
|
171
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
172
|
+
const mockDeps = [
|
|
173
|
+
{ name: "express", declaredConstraint: "^4.18.0", scope: "production", ecosystem: "npm", sourceManifest: "package.json" },
|
|
174
|
+
{ name: "lodash", declaredConstraint: "~4.17.21", scope: "production", ecosystem: "npm", sourceManifest: "package.json" },
|
|
175
|
+
{ name: "vitest", declaredConstraint: "^1.0.0", scope: "development", ecosystem: "npm", sourceManifest: "package.json" }
|
|
176
|
+
];
|
|
177
|
+
const plugin = {
|
|
178
|
+
ecosystem: "npm",
|
|
179
|
+
manifestFiles: ["package.json"],
|
|
180
|
+
canExtract: (p) => path.basename(p) === "package.json",
|
|
181
|
+
extract: async () => mockDeps
|
|
182
|
+
};
|
|
183
|
+
adapter.registerPlugin(plugin);
|
|
184
|
+
const result = await adapter.extractAll();
|
|
185
|
+
(0, import_vitest.expect)(result.dependenciesCreated).toBe(3);
|
|
186
|
+
(0, import_vitest.expect)(result.manifestsParsed).toBe(1);
|
|
187
|
+
(0, import_vitest.expect)(result.warnings).toHaveLength(0);
|
|
188
|
+
(0, import_vitest.expect)(result.errors).toHaveLength(0);
|
|
189
|
+
});
|
|
190
|
+
(0, import_vitest.it)("should fall back to architecture parser when no plugin registered", async () => {
|
|
191
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({
|
|
192
|
+
name: "test-project",
|
|
193
|
+
dependencies: { express: "^4.18.0", lodash: "~4.17.21" }
|
|
194
|
+
}));
|
|
195
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
196
|
+
const result = await adapter.extractAll();
|
|
197
|
+
(0, import_vitest.expect)(result.dependenciesCreated).toBe(2);
|
|
198
|
+
(0, import_vitest.expect)(result.manifestsParsed).toBe(1);
|
|
199
|
+
(0, import_vitest.expect)(result.warnings.length).toBeGreaterThan(0);
|
|
200
|
+
(0, import_vitest.expect)(result.warnings[0].message).toContain("No version extraction plugin");
|
|
201
|
+
});
|
|
202
|
+
(0, import_vitest.it)("should handle plugin extraction errors gracefully", async () => {
|
|
203
|
+
fs.writeFileSync(path.join(tmpDir, "package.json"), JSON.stringify({
|
|
204
|
+
name: "test-project",
|
|
205
|
+
dependencies: { express: "^4.18.0" }
|
|
206
|
+
}));
|
|
207
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
208
|
+
const plugin = {
|
|
209
|
+
ecosystem: "npm",
|
|
210
|
+
manifestFiles: ["package.json"],
|
|
211
|
+
canExtract: () => true,
|
|
212
|
+
extract: async () => {
|
|
213
|
+
throw new Error("Parse failed");
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
adapter.registerPlugin(plugin);
|
|
217
|
+
const result = await adapter.extractAll();
|
|
218
|
+
(0, import_vitest.expect)(result.dependenciesCreated).toBe(0);
|
|
219
|
+
(0, import_vitest.expect)(result.errors).toHaveLength(1);
|
|
220
|
+
(0, import_vitest.expect)(result.errors[0].message).toBe("Parse failed");
|
|
221
|
+
});
|
|
222
|
+
(0, import_vitest.it)("should handle empty project with no manifests", async () => {
|
|
223
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
224
|
+
const result = await adapter.extractAll();
|
|
225
|
+
(0, import_vitest.expect)(result.dependenciesCreated).toBe(0);
|
|
226
|
+
(0, import_vitest.expect)(result.manifestsParsed).toBe(0);
|
|
227
|
+
(0, import_vitest.expect)(result.warnings).toHaveLength(0);
|
|
228
|
+
(0, import_vitest.expect)(result.errors).toHaveLength(0);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
(0, import_vitest.describe)("extractFromManifest", () => {
|
|
232
|
+
(0, import_vitest.it)("should use plugin when available", async () => {
|
|
233
|
+
const manifestPath = path.join(tmpDir, "package.json");
|
|
234
|
+
fs.writeFileSync(manifestPath, JSON.stringify({
|
|
235
|
+
name: "test",
|
|
236
|
+
dependencies: { express: "^4.0.0" }
|
|
237
|
+
}));
|
|
238
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
239
|
+
const expectedDeps = [
|
|
240
|
+
{ name: "express", declaredConstraint: "^4.0.0", scope: "production", ecosystem: "npm", sourceManifest: "package.json" }
|
|
241
|
+
];
|
|
242
|
+
adapter.registerPlugin({
|
|
243
|
+
ecosystem: "npm",
|
|
244
|
+
manifestFiles: ["package.json"],
|
|
245
|
+
canExtract: (p) => path.basename(p) === "package.json",
|
|
246
|
+
extract: async () => expectedDeps
|
|
247
|
+
});
|
|
248
|
+
const deps = await adapter.extractFromManifest(manifestPath);
|
|
249
|
+
(0, import_vitest.expect)(deps).toEqual(expectedDeps);
|
|
250
|
+
});
|
|
251
|
+
(0, import_vitest.it)("should fall back to architecture parser when no plugin", async () => {
|
|
252
|
+
const manifestPath = path.join(tmpDir, "package.json");
|
|
253
|
+
fs.writeFileSync(manifestPath, JSON.stringify({
|
|
254
|
+
name: "test",
|
|
255
|
+
dependencies: { express: "^4.0.0", lodash: "~4.17.0" }
|
|
256
|
+
}));
|
|
257
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
258
|
+
const deps = await adapter.extractFromManifest(manifestPath);
|
|
259
|
+
(0, import_vitest.expect)(deps).toHaveLength(2);
|
|
260
|
+
(0, import_vitest.expect)(deps[0].declaredConstraint).toBe("*");
|
|
261
|
+
(0, import_vitest.expect)(deps[0].scope).toBe("production");
|
|
262
|
+
});
|
|
263
|
+
(0, import_vitest.it)("should return empty array for unknown manifest type", async () => {
|
|
264
|
+
const manifestPath = path.join(tmpDir, "unknown.txt");
|
|
265
|
+
fs.writeFileSync(manifestPath, "some content");
|
|
266
|
+
const adapter = new import_adapter.SecurityManifestAdapter(tmpDir);
|
|
267
|
+
const deps = await adapter.extractFromManifest(manifestPath);
|
|
268
|
+
(0, import_vitest.expect)(deps).toHaveLength(0);
|
|
269
|
+
});
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
//# sourceMappingURL=adapter.test.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../src/security/manifest/adapter.test.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Unit tests for SecurityManifestAdapter\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 { SecurityManifestAdapter, type VersionExtractionPlugin } from './adapter';\nimport type { ParsedDependency } from '../types';\n\ndescribe('SecurityManifestAdapter', () => {\n let tmpDir: string;\n\n beforeEach(() => {\n tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'sec-adapter-test-'));\n });\n\n afterEach(() => {\n fs.rmSync(tmpDir, { recursive: true, force: true });\n });\n\n describe('constructor', () => {\n it('should initialize with architecture parsers', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n const parsers = adapter.getArchParsers();\n expect(parsers.length).toBeGreaterThan(0);\n // Should include the known parsers\n const names = parsers.map(p => p.name);\n expect(names).toContain('npm');\n expect(names).toContain('cargo');\n expect(names).toContain('go');\n expect(names).toContain('maven');\n expect(names).toContain('python');\n });\n });\n\n describe('registerPlugin', () => {\n it('should register and retrieve a version extraction plugin', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n const plugin: VersionExtractionPlugin = {\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: (p) => path.basename(p) === 'package.json',\n extract: async () => [],\n };\n adapter.registerPlugin(plugin);\n const plugins = adapter.getPlugins();\n expect(plugins).toHaveLength(1);\n expect(plugins[0].ecosystem).toBe('npm');\n });\n\n it('should overwrite plugin for same ecosystem', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n const plugin1: VersionExtractionPlugin = {\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: () => true,\n extract: async () => [{ name: 'a', declaredConstraint: '1.0', scope: 'production', ecosystem: 'npm', sourceManifest: 'package.json' }],\n };\n const plugin2: VersionExtractionPlugin = {\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: () => true,\n extract: async () => [{ name: 'b', declaredConstraint: '2.0', scope: 'development', ecosystem: 'npm', sourceManifest: 'package.json' }],\n };\n adapter.registerPlugin(plugin1);\n adapter.registerPlugin(plugin2);\n const plugins = adapter.getPlugins();\n expect(plugins).toHaveLength(1);\n expect(plugins[0]).toBe(plugin2);\n });\n });\n\n describe('discoverManifests', () => {\n it('should discover package.json files', () => {\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'test', dependencies: { express: '^4.0.0' } }));\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(1);\n expect(manifests[0]).toBe(path.join(tmpDir, 'package.json'));\n });\n\n it('should discover nested manifest files', () => {\n fs.mkdirSync(path.join(tmpDir, 'sub'));\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'root' }));\n fs.writeFileSync(path.join(tmpDir, 'sub', 'package.json'), JSON.stringify({ name: 'sub' }));\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(2);\n });\n\n it('should skip node_modules directory', () => {\n fs.mkdirSync(path.join(tmpDir, 'node_modules'));\n fs.writeFileSync(path.join(tmpDir, 'node_modules', 'package.json'), JSON.stringify({ name: 'dep' }));\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'root' }));\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(1);\n expect(manifests[0]).toBe(path.join(tmpDir, 'package.json'));\n });\n\n it('should skip .git directory', () => {\n fs.mkdirSync(path.join(tmpDir, '.git'));\n fs.writeFileSync(path.join(tmpDir, '.git', 'package.json'), JSON.stringify({ name: 'git' }));\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'root' }));\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(1);\n });\n\n it('should skip dist and build directories', () => {\n fs.mkdirSync(path.join(tmpDir, 'dist'));\n fs.mkdirSync(path.join(tmpDir, 'build'));\n fs.writeFileSync(path.join(tmpDir, 'dist', 'package.json'), JSON.stringify({ name: 'dist' }));\n fs.writeFileSync(path.join(tmpDir, 'build', 'package.json'), JSON.stringify({ name: 'build' }));\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'root' }));\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(1);\n });\n\n it('should discover multiple ecosystem manifests', () => {\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({ name: 'js-project' }));\n fs.writeFileSync(path.join(tmpDir, 'Cargo.toml'), '[package]\\nname = \"rust-project\"\\nversion = \"0.1.0\"');\n fs.writeFileSync(path.join(tmpDir, 'go.mod'), 'module example.com/mymod\\n\\ngo 1.21');\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(3);\n });\n\n it('should return empty array for empty directory', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n const manifests = adapter.discoverManifests();\n expect(manifests).toHaveLength(0);\n });\n });\n\n describe('getEcosystem', () => {\n it('should return npm for package.json', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n expect(adapter.getEcosystem('/some/path/package.json')).toBe('npm');\n });\n\n it('should return cargo for Cargo.toml', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n expect(adapter.getEcosystem('/some/path/Cargo.toml')).toBe('cargo');\n });\n\n it('should return go for go.mod', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n expect(adapter.getEcosystem('/some/path/go.mod')).toBe('go');\n });\n\n it('should return maven for pom.xml', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n expect(adapter.getEcosystem('/some/path/pom.xml')).toBe('maven');\n });\n\n it('should return undefined for unknown files', () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n expect(adapter.getEcosystem('/some/path/unknown.txt')).toBeUndefined();\n });\n });\n\n describe('extractAll', () => {\n it('should use registered plugin for extraction', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({\n name: 'test-project',\n dependencies: { express: '^4.18.0', lodash: '~4.17.21' },\n devDependencies: { vitest: '^1.0.0' },\n }));\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const mockDeps: ParsedDependency[] = [\n { name: 'express', declaredConstraint: '^4.18.0', scope: 'production', ecosystem: 'npm', sourceManifest: 'package.json' },\n { name: 'lodash', declaredConstraint: '~4.17.21', scope: 'production', ecosystem: 'npm', sourceManifest: 'package.json' },\n { name: 'vitest', declaredConstraint: '^1.0.0', scope: 'development', ecosystem: 'npm', sourceManifest: 'package.json' },\n ];\n\n const plugin: VersionExtractionPlugin = {\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: (p) => path.basename(p) === 'package.json',\n extract: async () => mockDeps,\n };\n adapter.registerPlugin(plugin);\n\n const result = await adapter.extractAll();\n expect(result.dependenciesCreated).toBe(3);\n expect(result.manifestsParsed).toBe(1);\n expect(result.warnings).toHaveLength(0);\n expect(result.errors).toHaveLength(0);\n });\n\n it('should fall back to architecture parser when no plugin registered', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({\n name: 'test-project',\n dependencies: { express: '^4.18.0', lodash: '~4.17.21' },\n }));\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const result = await adapter.extractAll();\n\n // Should extract deps from architecture parser (names only)\n expect(result.dependenciesCreated).toBe(2);\n expect(result.manifestsParsed).toBe(1);\n // Should warn about missing plugin\n expect(result.warnings.length).toBeGreaterThan(0);\n expect(result.warnings[0].message).toContain('No version extraction plugin');\n });\n\n it('should handle plugin extraction errors gracefully', async () => {\n fs.writeFileSync(path.join(tmpDir, 'package.json'), JSON.stringify({\n name: 'test-project',\n dependencies: { express: '^4.18.0' },\n }));\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const plugin: VersionExtractionPlugin = {\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: () => true,\n extract: async () => { throw new Error('Parse failed'); },\n };\n adapter.registerPlugin(plugin);\n\n const result = await adapter.extractAll();\n expect(result.dependenciesCreated).toBe(0);\n expect(result.errors).toHaveLength(1);\n expect(result.errors[0].message).toBe('Parse failed');\n });\n\n it('should handle empty project with no manifests', async () => {\n const adapter = new SecurityManifestAdapter(tmpDir);\n const result = await adapter.extractAll();\n expect(result.dependenciesCreated).toBe(0);\n expect(result.manifestsParsed).toBe(0);\n expect(result.warnings).toHaveLength(0);\n expect(result.errors).toHaveLength(0);\n });\n });\n\n describe('extractFromManifest', () => {\n it('should use plugin when available', async () => {\n const manifestPath = path.join(tmpDir, 'package.json');\n fs.writeFileSync(manifestPath, JSON.stringify({\n name: 'test',\n dependencies: { express: '^4.0.0' },\n }));\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const expectedDeps: ParsedDependency[] = [\n { name: 'express', declaredConstraint: '^4.0.0', scope: 'production', ecosystem: 'npm', sourceManifest: 'package.json' },\n ];\n\n adapter.registerPlugin({\n ecosystem: 'npm',\n manifestFiles: ['package.json'],\n canExtract: (p) => path.basename(p) === 'package.json',\n extract: async () => expectedDeps,\n });\n\n const deps = await adapter.extractFromManifest(manifestPath);\n expect(deps).toEqual(expectedDeps);\n });\n\n it('should fall back to architecture parser when no plugin', async () => {\n const manifestPath = path.join(tmpDir, 'package.json');\n fs.writeFileSync(manifestPath, JSON.stringify({\n name: 'test',\n dependencies: { express: '^4.0.0', lodash: '~4.17.0' },\n }));\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const deps = await adapter.extractFromManifest(manifestPath);\n expect(deps).toHaveLength(2);\n // Fallback uses '*' as constraint and 'production' as default scope\n expect(deps[0].declaredConstraint).toBe('*');\n expect(deps[0].scope).toBe('production');\n });\n\n it('should return empty array for unknown manifest type', async () => {\n const manifestPath = path.join(tmpDir, 'unknown.txt');\n fs.writeFileSync(manifestPath, 'some content');\n\n const adapter = new SecurityManifestAdapter(tmpDir);\n const deps = await adapter.extractFromManifest(manifestPath);\n expect(deps).toHaveLength(0);\n });\n });\n});\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAGA,oBAA4D;AAC5D,SAAoB;AACpB,WAAsB;AACtB,SAAoB;AACpB,qBAAsE;AAAA,IAGtE,wBAAS,2BAA2B,MAAM;AACxC,MAAI;AAEJ,gCAAW,MAAM;AACf,aAAS,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,mBAAmB,CAAC;AAAA,EACrE,CAAC;AAED,+BAAU,MAAM;AACd,OAAG,OAAO,QAAQ,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,EACpD,CAAC;AAED,8BAAS,eAAe,MAAM;AAC5B,0BAAG,+CAA+C,MAAM;AACtD,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,UAAU,QAAQ,eAAe;AACvC,gCAAO,QAAQ,MAAM,EAAE,gBAAgB,CAAC;AAExC,YAAM,QAAQ,QAAQ,IAAI,OAAK,EAAE,IAAI;AACrC,gCAAO,KAAK,EAAE,UAAU,KAAK;AAC7B,gCAAO,KAAK,EAAE,UAAU,OAAO;AAC/B,gCAAO,KAAK,EAAE,UAAU,IAAI;AAC5B,gCAAO,KAAK,EAAE,UAAU,OAAO;AAC/B,gCAAO,KAAK,EAAE,UAAU,QAAQ;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,kBAAkB,MAAM;AAC/B,0BAAG,4DAA4D,MAAM;AACnE,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,SAAkC;AAAA,QACtC,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;AAAA,QACxC,SAAS,YAAY,CAAC;AAAA,MACxB;AACA,cAAQ,eAAe,MAAM;AAC7B,YAAM,UAAU,QAAQ,WAAW;AACnC,gCAAO,OAAO,EAAE,aAAa,CAAC;AAC9B,gCAAO,QAAQ,CAAC,EAAE,SAAS,EAAE,KAAK,KAAK;AAAA,IACzC,CAAC;AAED,0BAAG,8CAA8C,MAAM;AACrD,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,UAAmC;AAAA,QACvC,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,MAAM;AAAA,QAClB,SAAS,YAAY,CAAC,EAAE,MAAM,KAAK,oBAAoB,OAAO,OAAO,cAAc,WAAW,OAAO,gBAAgB,eAAe,CAAC;AAAA,MACvI;AACA,YAAM,UAAmC;AAAA,QACvC,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,MAAM;AAAA,QAClB,SAAS,YAAY,CAAC,EAAE,MAAM,KAAK,oBAAoB,OAAO,OAAO,eAAe,WAAW,OAAO,gBAAgB,eAAe,CAAC;AAAA,MACxI;AACA,cAAQ,eAAe,OAAO;AAC9B,cAAQ,eAAe,OAAO;AAC9B,YAAM,UAAU,QAAQ,WAAW;AACnC,gCAAO,OAAO,EAAE,aAAa,CAAC;AAC9B,gCAAO,QAAQ,CAAC,CAAC,EAAE,KAAK,OAAO;AAAA,IACjC,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,qBAAqB,MAAM;AAClC,0BAAG,sCAAsC,MAAM;AAC7C,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,QAAQ,cAAc,EAAE,SAAS,SAAS,EAAE,CAAC,CAAC;AACzH,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAChC,gCAAO,UAAU,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,QAAQ,cAAc,CAAC;AAAA,IAC7D,CAAC;AAED,0BAAG,yCAAyC,MAAM;AAChD,SAAG,UAAU,KAAK,KAAK,QAAQ,KAAK,CAAC;AACrC,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AACpF,SAAG,cAAc,KAAK,KAAK,QAAQ,OAAO,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC,CAAC;AAC1F,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAAA,IAClC,CAAC;AAED,0BAAG,sCAAsC,MAAM;AAC7C,SAAG,UAAU,KAAK,KAAK,QAAQ,cAAc,CAAC;AAC9C,SAAG,cAAc,KAAK,KAAK,QAAQ,gBAAgB,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC,CAAC;AACnG,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AACpF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAChC,gCAAO,UAAU,CAAC,CAAC,EAAE,KAAK,KAAK,KAAK,QAAQ,cAAc,CAAC;AAAA,IAC7D,CAAC;AAED,0BAAG,8BAA8B,MAAM;AACrC,SAAG,UAAU,KAAK,KAAK,QAAQ,MAAM,CAAC;AACtC,SAAG,cAAc,KAAK,KAAK,QAAQ,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC,CAAC;AAC3F,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AACpF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAAA,IAClC,CAAC;AAED,0BAAG,0CAA0C,MAAM;AACjD,SAAG,UAAU,KAAK,KAAK,QAAQ,MAAM,CAAC;AACtC,SAAG,UAAU,KAAK,KAAK,QAAQ,OAAO,CAAC;AACvC,SAAG,cAAc,KAAK,KAAK,QAAQ,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AAC5F,SAAG,cAAc,KAAK,KAAK,QAAQ,SAAS,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAC,CAAC;AAC9F,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,OAAO,CAAC,CAAC;AACpF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAAA,IAClC,CAAC;AAED,0BAAG,gDAAgD,MAAM;AACvD,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC,CAAC;AAC1F,SAAG,cAAc,KAAK,KAAK,QAAQ,YAAY,GAAG,qDAAqD;AACvG,SAAG,cAAc,KAAK,KAAK,QAAQ,QAAQ,GAAG,qCAAqC;AACnF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAAA,IAClC,CAAC;AAED,0BAAG,iDAAiD,MAAM;AACxD,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,YAAY,QAAQ,kBAAkB;AAC5C,gCAAO,SAAS,EAAE,aAAa,CAAC;AAAA,IAClC,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,gBAAgB,MAAM;AAC7B,0BAAG,sCAAsC,MAAM;AAC7C,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,gCAAO,QAAQ,aAAa,yBAAyB,CAAC,EAAE,KAAK,KAAK;AAAA,IACpE,CAAC;AAED,0BAAG,sCAAsC,MAAM;AAC7C,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,gCAAO,QAAQ,aAAa,uBAAuB,CAAC,EAAE,KAAK,OAAO;AAAA,IACpE,CAAC;AAED,0BAAG,+BAA+B,MAAM;AACtC,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,gCAAO,QAAQ,aAAa,mBAAmB,CAAC,EAAE,KAAK,IAAI;AAAA,IAC7D,CAAC;AAED,0BAAG,mCAAmC,MAAM;AAC1C,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,gCAAO,QAAQ,aAAa,oBAAoB,CAAC,EAAE,KAAK,OAAO;AAAA,IACjE,CAAC;AAED,0BAAG,6CAA6C,MAAM;AACpD,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,gCAAO,QAAQ,aAAa,wBAAwB,CAAC,EAAE,cAAc;AAAA,IACvE,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,cAAc,MAAM;AAC3B,0BAAG,+CAA+C,YAAY;AAC5D,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU;AAAA,QACjE,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,WAAW,QAAQ,WAAW;AAAA,QACvD,iBAAiB,EAAE,QAAQ,SAAS;AAAA,MACtC,CAAC,CAAC;AAEF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,WAA+B;AAAA,QACnC,EAAE,MAAM,WAAW,oBAAoB,WAAW,OAAO,cAAc,WAAW,OAAO,gBAAgB,eAAe;AAAA,QACxH,EAAE,MAAM,UAAU,oBAAoB,YAAY,OAAO,cAAc,WAAW,OAAO,gBAAgB,eAAe;AAAA,QACxH,EAAE,MAAM,UAAU,oBAAoB,UAAU,OAAO,eAAe,WAAW,OAAO,gBAAgB,eAAe;AAAA,MACzH;AAEA,YAAM,SAAkC;AAAA,QACtC,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;AAAA,QACxC,SAAS,YAAY;AAAA,MACvB;AACA,cAAQ,eAAe,MAAM;AAE7B,YAAM,SAAS,MAAM,QAAQ,WAAW;AACxC,gCAAO,OAAO,mBAAmB,EAAE,KAAK,CAAC;AACzC,gCAAO,OAAO,eAAe,EAAE,KAAK,CAAC;AACrC,gCAAO,OAAO,QAAQ,EAAE,aAAa,CAAC;AACtC,gCAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AAAA,IACtC,CAAC;AAED,0BAAG,qEAAqE,YAAY;AAClF,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU;AAAA,QACjE,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,WAAW,QAAQ,WAAW;AAAA,MACzD,CAAC,CAAC;AAEF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,SAAS,MAAM,QAAQ,WAAW;AAGxC,gCAAO,OAAO,mBAAmB,EAAE,KAAK,CAAC;AACzC,gCAAO,OAAO,eAAe,EAAE,KAAK,CAAC;AAErC,gCAAO,OAAO,SAAS,MAAM,EAAE,gBAAgB,CAAC;AAChD,gCAAO,OAAO,SAAS,CAAC,EAAE,OAAO,EAAE,UAAU,8BAA8B;AAAA,IAC7E,CAAC;AAED,0BAAG,qDAAqD,YAAY;AAClE,SAAG,cAAc,KAAK,KAAK,QAAQ,cAAc,GAAG,KAAK,UAAU;AAAA,QACjE,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,UAAU;AAAA,MACrC,CAAC,CAAC;AAEF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,SAAkC;AAAA,QACtC,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,MAAM;AAAA,QAClB,SAAS,YAAY;AAAE,gBAAM,IAAI,MAAM,cAAc;AAAA,QAAG;AAAA,MAC1D;AACA,cAAQ,eAAe,MAAM;AAE7B,YAAM,SAAS,MAAM,QAAQ,WAAW;AACxC,gCAAO,OAAO,mBAAmB,EAAE,KAAK,CAAC;AACzC,gCAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AACpC,gCAAO,OAAO,OAAO,CAAC,EAAE,OAAO,EAAE,KAAK,cAAc;AAAA,IACtD,CAAC;AAED,0BAAG,iDAAiD,YAAY;AAC9D,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,SAAS,MAAM,QAAQ,WAAW;AACxC,gCAAO,OAAO,mBAAmB,EAAE,KAAK,CAAC;AACzC,gCAAO,OAAO,eAAe,EAAE,KAAK,CAAC;AACrC,gCAAO,OAAO,QAAQ,EAAE,aAAa,CAAC;AACtC,gCAAO,OAAO,MAAM,EAAE,aAAa,CAAC;AAAA,IACtC,CAAC;AAAA,EACH,CAAC;AAED,8BAAS,uBAAuB,MAAM;AACpC,0BAAG,oCAAoC,YAAY;AACjD,YAAM,eAAe,KAAK,KAAK,QAAQ,cAAc;AACrD,SAAG,cAAc,cAAc,KAAK,UAAU;AAAA,QAC5C,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,SAAS;AAAA,MACpC,CAAC,CAAC;AAEF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,eAAmC;AAAA,QACvC,EAAE,MAAM,WAAW,oBAAoB,UAAU,OAAO,cAAc,WAAW,OAAO,gBAAgB,eAAe;AAAA,MACzH;AAEA,cAAQ,eAAe;AAAA,QACrB,WAAW;AAAA,QACX,eAAe,CAAC,cAAc;AAAA,QAC9B,YAAY,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM;AAAA,QACxC,SAAS,YAAY;AAAA,MACvB,CAAC;AAED,YAAM,OAAO,MAAM,QAAQ,oBAAoB,YAAY;AAC3D,gCAAO,IAAI,EAAE,QAAQ,YAAY;AAAA,IACnC,CAAC;AAED,0BAAG,0DAA0D,YAAY;AACvE,YAAM,eAAe,KAAK,KAAK,QAAQ,cAAc;AACrD,SAAG,cAAc,cAAc,KAAK,UAAU;AAAA,QAC5C,MAAM;AAAA,QACN,cAAc,EAAE,SAAS,UAAU,QAAQ,UAAU;AAAA,MACvD,CAAC,CAAC;AAEF,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,OAAO,MAAM,QAAQ,oBAAoB,YAAY;AAC3D,gCAAO,IAAI,EAAE,aAAa,CAAC;AAE3B,gCAAO,KAAK,CAAC,EAAE,kBAAkB,EAAE,KAAK,GAAG;AAC3C,gCAAO,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,YAAY;AAAA,IACzC,CAAC;AAED,0BAAG,uDAAuD,YAAY;AACpE,YAAM,eAAe,KAAK,KAAK,QAAQ,aAAa;AACpD,SAAG,cAAc,cAAc,cAAc;AAE7C,YAAM,UAAU,IAAI,uCAAwB,MAAM;AAClD,YAAM,OAAO,MAAM,QAAQ,oBAAoB,YAAY;AAC3D,gCAAO,IAAI,EAAE,aAAa,CAAC;AAAA,IAC7B,CAAC;AAAA,EACH,CAAC;AACH,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|