@planu/cli 1.0.2 → 1.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/license-plans.json +4 -2
- package/dist/engine/actuals/progress-parser.js +1 -1
- package/dist/engine/actuals/progress-parser.js.map +1 -1
- package/dist/engine/ai-integration/agent-frameworks/crewai-exporter.d.ts.map +1 -1
- package/dist/engine/ai-integration/agent-frameworks/crewai-exporter.js.map +1 -1
- package/dist/engine/ai-integration/cline/clinerules-generator.d.ts.map +1 -1
- package/dist/engine/ai-integration/cline/clinerules-generator.js +1 -6
- package/dist/engine/ai-integration/cline/clinerules-generator.js.map +1 -1
- package/dist/engine/ai-integration/github-copilot/index.d.ts +1 -1
- package/dist/engine/ai-integration/github-copilot/index.d.ts.map +1 -1
- package/dist/engine/ai-integration/github-copilot/index.js +1 -1
- package/dist/engine/ai-integration/github-copilot/index.js.map +1 -1
- package/dist/engine/ai-integration/kiro/steering-generator.d.ts.map +1 -1
- package/dist/engine/ai-integration/kiro/steering-generator.js +1 -6
- package/dist/engine/ai-integration/kiro/steering-generator.js.map +1 -1
- package/dist/engine/ai-integration/mastra/index.d.ts +1 -1
- package/dist/engine/ai-integration/mastra/index.d.ts.map +1 -1
- package/dist/engine/ai-integration/mastra/index.js +1 -1
- package/dist/engine/ai-integration/mastra/index.js.map +1 -1
- package/dist/engine/api-spec-generator/ac-builder.d.ts.map +1 -1
- package/dist/engine/api-spec-generator/ac-builder.js.map +1 -1
- package/dist/engine/api-spec-generator/graphql-parser.d.ts.map +1 -1
- package/dist/engine/api-spec-generator/graphql-parser.js +5 -1
- package/dist/engine/api-spec-generator/graphql-parser.js.map +1 -1
- package/dist/engine/api-spec-generator/openapi-parser.d.ts.map +1 -1
- package/dist/engine/api-spec-generator/openapi-parser.js.map +1 -1
- package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -1
- package/dist/engine/ci-generator/yaml-builder.js +43 -0
- package/dist/engine/ci-generator/yaml-builder.js.map +1 -1
- package/dist/engine/compliance-checker.js +26 -3
- package/dist/engine/compliance-checker.js.map +1 -1
- package/dist/engine/dep-auditor/index.d.ts +2 -0
- package/dist/engine/dep-auditor/index.d.ts.map +1 -1
- package/dist/engine/dep-auditor/index.js +114 -42
- package/dist/engine/dep-auditor/index.js.map +1 -1
- package/dist/engine/dep-auditor/lockfile-parser.d.ts +26 -0
- package/dist/engine/dep-auditor/lockfile-parser.d.ts.map +1 -0
- package/dist/engine/dep-auditor/lockfile-parser.js +164 -0
- package/dist/engine/dep-auditor/lockfile-parser.js.map +1 -0
- package/dist/engine/dep-auditor/semver-utils.d.ts +19 -0
- package/dist/engine/dep-auditor/semver-utils.d.ts.map +1 -0
- package/dist/engine/dep-auditor/semver-utils.js +141 -0
- package/dist/engine/dep-auditor/semver-utils.js.map +1 -0
- package/dist/engine/dep-auditor/vuln-data.d.ts.map +1 -1
- package/dist/engine/dep-auditor/vuln-data.js +1 -20
- package/dist/engine/dep-auditor/vuln-data.js.map +1 -1
- package/dist/engine/detectors/idp-detector.js +1 -1
- package/dist/engine/detectors/idp-detector.js.map +1 -1
- package/dist/engine/github/quality-dimensions.js +1 -1
- package/dist/engine/github/quality-dimensions.js.map +1 -1
- package/dist/engine/hooks/event-bus.js +1 -1
- package/dist/engine/hooks/event-bus.js.map +1 -1
- package/dist/engine/hooks-reconciler.d.ts.map +1 -1
- package/dist/engine/hooks-reconciler.js.map +1 -1
- package/dist/engine/importers/csv-importer.d.ts.map +1 -1
- package/dist/engine/importers/csv-importer.js.map +1 -1
- package/dist/engine/importers/jira-importer.d.ts.map +1 -1
- package/dist/engine/importers/jira-importer.js.map +1 -1
- package/dist/engine/importers/linear-importer.d.ts.map +1 -1
- package/dist/engine/importers/linear-importer.js.map +1 -1
- package/dist/engine/importers/markdown-importer.d.ts.map +1 -1
- package/dist/engine/importers/markdown-importer.js.map +1 -1
- package/dist/engine/jira-exporter.d.ts.map +1 -1
- package/dist/engine/jira-exporter.js.map +1 -1
- package/dist/engine/property-test-generator.d.ts.map +1 -1
- package/dist/engine/property-test-generator.js +4 -1
- package/dist/engine/property-test-generator.js.map +1 -1
- package/dist/engine/registry/composio-publisher.d.ts.map +1 -1
- package/dist/engine/registry/composio-publisher.js +1 -3
- package/dist/engine/registry/composio-publisher.js.map +1 -1
- package/dist/engine/registry/mcp-official-publisher.d.ts.map +1 -1
- package/dist/engine/registry/mcp-official-publisher.js +3 -1
- package/dist/engine/registry/mcp-official-publisher.js.map +1 -1
- package/dist/engine/spec-differ.d.ts.map +1 -1
- package/dist/engine/spec-differ.js.map +1 -1
- package/dist/engine/spec-repair.js +1 -1
- package/dist/engine/spec-repair.js.map +1 -1
- package/dist/engine/spec-template-engine.d.ts.map +1 -1
- package/dist/engine/spec-template-engine.js +1 -3
- package/dist/engine/spec-template-engine.js.map +1 -1
- package/dist/engine/token-optimizer/response-cache.d.ts.map +1 -1
- package/dist/engine/token-optimizer/response-cache.js +1 -4
- package/dist/engine/token-optimizer/response-cache.js.map +1 -1
- package/dist/engine/validator/deep-code-checker.js +1 -1
- package/dist/engine/validator/deep-code-checker.js.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/comments-store.d.ts.map +1 -1
- package/dist/storage/comments-store.js.map +1 -1
- package/dist/storage/compliance-store.d.ts.map +1 -1
- package/dist/storage/compliance-store.js.map +1 -1
- package/dist/storage/jira-store.d.ts.map +1 -1
- package/dist/storage/jira-store.js.map +1 -1
- package/dist/storage/linear-store.d.ts.map +1 -1
- package/dist/storage/linear-store.js.map +1 -1
- package/dist/tools/ai-ecosystem-status.d.ts +1 -1
- package/dist/tools/ai-ecosystem-status.d.ts.map +1 -1
- package/dist/tools/ai-ecosystem-status.js +14 -3
- package/dist/tools/ai-ecosystem-status.js.map +1 -1
- package/dist/tools/api-spec-generator-handler.d.ts.map +1 -1
- package/dist/tools/api-spec-generator-handler.js.map +1 -1
- package/dist/tools/comments-handler.d.ts.map +1 -1
- package/dist/tools/comments-handler.js +2 -9
- package/dist/tools/comments-handler.js.map +1 -1
- package/dist/tools/compliance-handler.d.ts.map +1 -1
- package/dist/tools/compliance-handler.js +1 -1
- package/dist/tools/compliance-handler.js.map +1 -1
- package/dist/tools/generate-batch-script.d.ts.map +1 -1
- package/dist/tools/generate-batch-script.js +4 -14
- package/dist/tools/generate-batch-script.js.map +1 -1
- package/dist/tools/import-spec-handler.d.ts.map +1 -1
- package/dist/tools/import-spec-handler.js.map +1 -1
- package/dist/tools/init-project/helpers.js +1 -1
- package/dist/tools/init-project/helpers.js.map +1 -1
- package/dist/tools/init-project/planu-workflow-generator.js +2 -2
- package/dist/tools/init-project/planu-workflow-generator.js.map +1 -1
- package/dist/tools/orchestrate-agents-handler.d.ts.map +1 -1
- package/dist/tools/orchestrate-agents-handler.js +1 -10
- package/dist/tools/orchestrate-agents-handler.js.map +1 -1
- package/dist/tools/register-api-spec-generator.d.ts.map +1 -1
- package/dist/tools/register-api-spec-generator.js +1 -5
- package/dist/tools/register-api-spec-generator.js.map +1 -1
- package/dist/tools/register-backlog-tools.d.ts.map +1 -1
- package/dist/tools/register-backlog-tools.js +29 -4
- package/dist/tools/register-backlog-tools.js.map +1 -1
- package/dist/tools/register-comments-tools.d.ts.map +1 -1
- package/dist/tools/register-comments-tools.js +2 -6
- package/dist/tools/register-comments-tools.js.map +1 -1
- package/dist/tools/register-dep-audit-tools.d.ts +3 -0
- package/dist/tools/register-dep-audit-tools.d.ts.map +1 -0
- package/dist/tools/register-dep-audit-tools.js +157 -0
- package/dist/tools/register-dep-audit-tools.js.map +1 -0
- package/dist/tools/register-estimation-accuracy-tools.d.ts.map +1 -1
- package/dist/tools/register-estimation-accuracy-tools.js +22 -3
- package/dist/tools/register-estimation-accuracy-tools.js.map +1 -1
- package/dist/tools/register-import-tools.d.ts.map +1 -1
- package/dist/tools/register-import-tools.js +2 -8
- package/dist/tools/register-import-tools.js.map +1 -1
- package/dist/tools/register-platform-tools/design-stack-tools.d.ts.map +1 -1
- package/dist/tools/register-platform-tools/design-stack-tools.js +13 -2
- package/dist/tools/register-platform-tools/design-stack-tools.js.map +1 -1
- package/dist/tools/register-spec-314.d.ts.map +1 -1
- package/dist/tools/register-spec-314.js +1 -5
- package/dist/tools/register-spec-314.js.map +1 -1
- package/dist/tools/register-spec-316.d.ts.map +1 -1
- package/dist/tools/register-spec-316.js +7 -3
- package/dist/tools/register-spec-316.js.map +1 -1
- package/dist/tools/register-spec-317.d.ts.map +1 -1
- package/dist/tools/register-spec-317.js.map +1 -1
- package/dist/tools/register-spec-319.d.ts.map +1 -1
- package/dist/tools/register-spec-319.js +4 -16
- package/dist/tools/register-spec-319.js.map +1 -1
- package/dist/tools/register-spec-tools/analysis-tools.d.ts.map +1 -1
- package/dist/tools/register-spec-tools/analysis-tools.js +131 -20
- package/dist/tools/register-spec-tools/analysis-tools.js.map +1 -1
- package/dist/tools/register-velocity-tools.d.ts.map +1 -1
- package/dist/tools/register-velocity-tools.js +2 -10
- package/dist/tools/register-velocity-tools.js.map +1 -1
- package/dist/tools/scan-project.d.ts +5 -1
- package/dist/tools/scan-project.d.ts.map +1 -1
- package/dist/tools/scan-project.js +6 -1
- package/dist/tools/scan-project.js.map +1 -1
- package/dist/tools/spec-diff-handler.d.ts.map +1 -1
- package/dist/tools/spec-diff-handler.js.map +1 -1
- package/dist/tools/spec-marketplace-handler.d.ts.map +1 -1
- package/dist/tools/spec-marketplace-handler.js.map +1 -1
- package/dist/tools/spec-quality-score-handler.d.ts.map +1 -1
- package/dist/tools/spec-quality-score-handler.js +22 -8
- package/dist/tools/spec-quality-score-handler.js.map +1 -1
- package/dist/tools/sync-ai-configs.d.ts +1 -1
- package/dist/tools/sync-ai-configs.d.ts.map +1 -1
- package/dist/tools/sync-ai-configs.js +14 -3
- package/dist/tools/sync-ai-configs.js.map +1 -1
- package/dist/tools/update-status/dod-gates.d.ts +14 -0
- package/dist/tools/update-status/dod-gates.d.ts.map +1 -1
- package/dist/tools/update-status/dod-gates.js +54 -0
- package/dist/tools/update-status/dod-gates.js.map +1 -1
- package/dist/tools/update-status/index.d.ts.map +1 -1
- package/dist/tools/update-status/index.js +6 -6
- package/dist/tools/update-status/index.js.map +1 -1
- package/dist/tools/velocity-handler.d.ts.map +1 -1
- package/dist/tools/velocity-handler.js.map +1 -1
- package/dist/types/tooling/audit.d.ts +20 -0
- package/dist/types/tooling/audit.d.ts.map +1 -1
- package/dist/types/tooling/audit.js +1 -1
- package/dist/types/tooling/audit.js.map +1 -1
- package/dist/types/tooling/index.d.ts +1 -1
- package/dist/types/tooling/index.d.ts.map +1 -1
- package/dist/types/tooling.d.ts +1 -1
- package/dist/types/tooling.d.ts.map +1 -1
- package/package.json +11 -9
- package/src/config/license-plans.json +4 -2
|
@@ -1,63 +1,103 @@
|
|
|
1
|
-
// dep-auditor/index.ts — Main dependency audit orchestrator (SPEC-025)
|
|
1
|
+
// dep-auditor/index.ts — Main dependency audit orchestrator (SPEC-025, SPEC-335)
|
|
2
2
|
// Combines license checking, vuln detection, abandonment heuristics, and duplicate detection.
|
|
3
3
|
import { readFile } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { readManifest } from '../stack-auditor/manifest-reader.js';
|
|
6
6
|
import { checkLicense, isCommercialProject } from './license-checker.js';
|
|
7
7
|
import { detectDuplicates } from './dep-duplicates-detector.js';
|
|
8
|
-
import { getVulns } from './vuln-data.js';
|
|
8
|
+
import { getVulns, KNOWN_VULNS } from './vuln-data.js';
|
|
9
9
|
import { getAbandonedInfo, classifyEntry } from './abandonment-data.js';
|
|
10
|
+
import { fetchNpmCve } from './cve-fetcher.js';
|
|
11
|
+
import { parseTransitiveDeps } from './lockfile-parser.js';
|
|
10
12
|
export { formatDepAuditMarkdown, formatDepAuditAcceptanceCriteria } from './formatters.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// 1h in-memory CVE cache
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
const cveCache = new Map();
|
|
17
|
+
const CVE_CACHE_TTL_MS = 60 * 60 * 1000; // 1 hour
|
|
18
|
+
/** Clear the CVE cache — intended for use in tests only. */
|
|
19
|
+
export function clearCveCache() {
|
|
20
|
+
cveCache.clear();
|
|
21
|
+
}
|
|
22
|
+
async function fetchNpmCveCached(pkg, version) {
|
|
23
|
+
const cacheKey = `${pkg}@${version}`;
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
const cached = cveCache.get(cacheKey);
|
|
26
|
+
if (cached && cached.expiresAt > now) {
|
|
27
|
+
return cached.data;
|
|
28
|
+
}
|
|
29
|
+
const data = await fetchNpmCve(pkg, version);
|
|
30
|
+
cveCache.set(cacheKey, { data, expiresAt: now + CVE_CACHE_TTL_MS });
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
/** Build DepVuln entries from live CveFinding results, marking as transitive if needed. */
|
|
34
|
+
function cveToDepVulns(findings, transitive) {
|
|
35
|
+
return findings.map((f) => ({
|
|
36
|
+
cveId: f.cveId,
|
|
37
|
+
severity: f.severity,
|
|
38
|
+
description: f.title,
|
|
39
|
+
fixedIn: f.fixedIn ?? undefined,
|
|
40
|
+
...(transitive ? { transitive: true } : {}),
|
|
41
|
+
}));
|
|
42
|
+
}
|
|
11
43
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* Cargo.toml (rust), pom.xml (java).
|
|
44
|
+
* Merge hardcoded vulns with live API vulns. Live results take precedence:
|
|
45
|
+
* if a CVE ID appears in both, keep the live version.
|
|
15
46
|
*/
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
47
|
+
function mergeVulns(hardcoded, live) {
|
|
48
|
+
const liveCveIds = new Set(live.map((v) => v.cveId));
|
|
49
|
+
const filteredHardcoded = hardcoded.filter((v) => !liveCveIds.has(v.cveId));
|
|
50
|
+
return [...filteredHardcoded, ...live];
|
|
51
|
+
}
|
|
52
|
+
/** Build a DepAuditEntry for a single direct dependency. */
|
|
53
|
+
async function buildDirectEntry(name, version, ecosystem, licenseMap) {
|
|
54
|
+
const hardcodedVulns = getVulns(name, version);
|
|
55
|
+
let liveVulns = [];
|
|
56
|
+
if (ecosystem === 'nodejs' && name in KNOWN_VULNS) {
|
|
21
57
|
try {
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
isCommercialProject(pkgJson);
|
|
58
|
+
const findings = await fetchNpmCveCached(name, version);
|
|
59
|
+
liveVulns = cveToDepVulns(findings, false);
|
|
25
60
|
}
|
|
26
61
|
catch {
|
|
27
|
-
//
|
|
62
|
+
// silently fall back to hardcoded list
|
|
28
63
|
}
|
|
29
64
|
}
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
65
|
+
const vulns = mergeVulns(hardcodedVulns, liveVulns);
|
|
66
|
+
const licenseRaw = licenseMap[name] ?? '';
|
|
67
|
+
const license = checkLicense(licenseRaw);
|
|
68
|
+
const abandoned = getAbandonedInfo(name);
|
|
69
|
+
return { name, currentVersion: version, ecosystem, vulns, license, abandoned };
|
|
70
|
+
}
|
|
71
|
+
/** Build transitive-only vuln entries (packages not in direct deps). */
|
|
72
|
+
async function buildTransitiveEntries(transitiveOnlyEntries, ecosystem) {
|
|
73
|
+
const results = await Promise.all(transitiveOnlyEntries.map(async ([name, version]) => {
|
|
74
|
+
const hardcoded = getVulns(name, version).map((v) => ({ ...v, transitive: true }));
|
|
75
|
+
let liveVulns = [];
|
|
76
|
+
if (name in KNOWN_VULNS) {
|
|
77
|
+
try {
|
|
78
|
+
liveVulns = cveToDepVulns(await fetchNpmCveCached(name, version), true);
|
|
79
|
+
}
|
|
80
|
+
catch {
|
|
81
|
+
/* fall back to hardcoded */
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
const vulns = mergeVulns(hardcoded, liveVulns);
|
|
85
|
+
if (vulns.length === 0) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
39
88
|
return {
|
|
40
89
|
name,
|
|
41
90
|
currentVersion: version,
|
|
42
91
|
ecosystem,
|
|
43
92
|
vulns,
|
|
44
|
-
license,
|
|
45
|
-
abandoned,
|
|
93
|
+
license: checkLicense(''),
|
|
94
|
+
abandoned: getAbandonedInfo(name),
|
|
46
95
|
};
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
for (const pkg of dup.packages) {
|
|
53
|
-
duplicateCategories.set(pkg, dup.category);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
// Tag duplicate groups on entries
|
|
57
|
-
const taggedEntries = entries.map((e) => {
|
|
58
|
-
const grp = duplicateCategories.get(e.name);
|
|
59
|
-
return grp ? { ...e, duplicateGroup: grp } : e;
|
|
60
|
-
});
|
|
96
|
+
}));
|
|
97
|
+
return results.filter((e) => e !== null);
|
|
98
|
+
}
|
|
99
|
+
/** Classify tagged entries into critical / warnings / clean buckets. */
|
|
100
|
+
function classifyEntries(taggedEntries) {
|
|
61
101
|
const critical = [];
|
|
62
102
|
const warnings = [];
|
|
63
103
|
const clean = [];
|
|
@@ -73,9 +113,41 @@ export async function auditDeps(projectPath) {
|
|
|
73
113
|
clean.push(entry);
|
|
74
114
|
}
|
|
75
115
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
116
|
+
return { critical, warnings, clean };
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Audit all dependencies of a project at projectPath.
|
|
120
|
+
* Scans package.json (npm), requirements.txt (python), go.mod (go),
|
|
121
|
+
* Cargo.toml (rust), pom.xml (java).
|
|
122
|
+
*/
|
|
123
|
+
export async function auditDeps(projectPath) {
|
|
124
|
+
const manifest = await readManifest(projectPath);
|
|
125
|
+
const ecosystem = manifest.ecosystem;
|
|
126
|
+
if (ecosystem === 'nodejs') {
|
|
127
|
+
try {
|
|
128
|
+
isCommercialProject(await readFile(join(projectPath, 'package.json'), 'utf-8'));
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
/* default: assume commercial */
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const deps = manifest.directDependencies;
|
|
135
|
+
const depNames = Object.keys(deps);
|
|
136
|
+
const licenseMap = await buildLicenseMap(projectPath, ecosystem);
|
|
137
|
+
const entries = await Promise.all(depNames.map((name) => buildDirectEntry(name, deps[name] ?? 'unknown', ecosystem, licenseMap)));
|
|
138
|
+
const transitiveOnlyEntries = ecosystem === 'nodejs'
|
|
139
|
+
? [...(await parseTransitiveDeps(projectPath)).entries()].filter(([n]) => !new Set(depNames).has(n))
|
|
140
|
+
: [];
|
|
141
|
+
const transitiveVulnEntries = await buildTransitiveEntries(transitiveOnlyEntries, ecosystem);
|
|
142
|
+
const duplicates = detectDuplicates(depNames);
|
|
143
|
+
const dupCategories = new Map(duplicates.flatMap((d) => d.packages.map((p) => [p, d.category])));
|
|
144
|
+
const tagged = [...entries, ...transitiveVulnEntries].map((e) => {
|
|
145
|
+
const grp = dupCategories.get(e.name);
|
|
146
|
+
return grp ? { ...e, duplicateGroup: grp } : e;
|
|
147
|
+
});
|
|
148
|
+
const { critical, warnings, clean } = classifyEntries(tagged);
|
|
149
|
+
const summary = buildSummary(depNames.length, critical.length, warnings.length, duplicates.length);
|
|
150
|
+
return { ecosystem, totalDeps: depNames.length, critical, warnings, clean, duplicates, summary };
|
|
79
151
|
}
|
|
80
152
|
async function buildLicenseMap(projectPath, ecosystem) {
|
|
81
153
|
if (ecosystem !== 'nodejs') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/dep-auditor/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/dep-auditor/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse transitive deps from the project lockfile.
|
|
3
|
+
* Returns Map<packageName, installedVersion> for ALL deps (direct + transitive).
|
|
4
|
+
* Falls back to direct deps from package.json if no lockfile found.
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseTransitiveDeps(projectPath: string): Promise<Map<string, string>>;
|
|
7
|
+
/**
|
|
8
|
+
* Parse pnpm-lock.yaml v9 format.
|
|
9
|
+
* v9 format has a `snapshots:` section with entries like:
|
|
10
|
+
* pkg@version:
|
|
11
|
+
* ...
|
|
12
|
+
* and a `packages:` section with entries like:
|
|
13
|
+
* /pkg/version:
|
|
14
|
+
* ...
|
|
15
|
+
* We parse both sections to extract all package names and versions.
|
|
16
|
+
*/
|
|
17
|
+
export declare function parsePnpmLockYaml(raw: string): Map<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Parse package-lock.json v2/v3 format.
|
|
20
|
+
* v3: top-level `packages` object with keys like "node_modules/pkg" or
|
|
21
|
+
* "node_modules/pkg/node_modules/nested-pkg".
|
|
22
|
+
* v2: both `packages` and `dependencies` present.
|
|
23
|
+
* v1: only `dependencies` present (older format).
|
|
24
|
+
*/
|
|
25
|
+
export declare function parsePackageLockJson(raw: string): Map<string, string>;
|
|
26
|
+
//# sourceMappingURL=lockfile-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile-parser.d.ts","sourceRoot":"","sources":["../../../src/engine/dep-auditor/lockfile-parser.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAe3F;AAaD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BlE;AAkBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAgCrE"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
// dep-auditor/lockfile-parser.ts — Transitive dependency walker (SPEC-335)
|
|
2
|
+
// Reads pnpm-lock.yaml (v9) or package-lock.json (v2/v3) to build a full
|
|
3
|
+
// flat map of all installed packages including transitive dependencies.
|
|
4
|
+
import { readFile } from 'node:fs/promises';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Parse transitive deps from the project lockfile.
|
|
8
|
+
* Returns Map<packageName, installedVersion> for ALL deps (direct + transitive).
|
|
9
|
+
* Falls back to direct deps from package.json if no lockfile found.
|
|
10
|
+
*/
|
|
11
|
+
export async function parseTransitiveDeps(projectPath) {
|
|
12
|
+
// Try pnpm-lock.yaml first
|
|
13
|
+
const pnpmResult = await tryParsePnpmLock(projectPath);
|
|
14
|
+
if (pnpmResult !== null) {
|
|
15
|
+
return pnpmResult;
|
|
16
|
+
}
|
|
17
|
+
// Try package-lock.json (npm v2/v3)
|
|
18
|
+
const npmResult = await tryParsePackageLock(projectPath);
|
|
19
|
+
if (npmResult !== null) {
|
|
20
|
+
return npmResult;
|
|
21
|
+
}
|
|
22
|
+
// Fallback: read direct deps from package.json
|
|
23
|
+
return readDirectDepsFromPackageJson(projectPath);
|
|
24
|
+
}
|
|
25
|
+
async function tryParsePnpmLock(projectPath) {
|
|
26
|
+
const lockPath = join(projectPath, 'pnpm-lock.yaml');
|
|
27
|
+
let raw;
|
|
28
|
+
try {
|
|
29
|
+
raw = await readFile(lockPath, 'utf-8');
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
return parsePnpmLockYaml(raw);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Parse pnpm-lock.yaml v9 format.
|
|
38
|
+
* v9 format has a `snapshots:` section with entries like:
|
|
39
|
+
* pkg@version:
|
|
40
|
+
* ...
|
|
41
|
+
* and a `packages:` section with entries like:
|
|
42
|
+
* /pkg/version:
|
|
43
|
+
* ...
|
|
44
|
+
* We parse both sections to extract all package names and versions.
|
|
45
|
+
*/
|
|
46
|
+
export function parsePnpmLockYaml(raw) {
|
|
47
|
+
const result = new Map();
|
|
48
|
+
// pnpm-lock.yaml v9: snapshots section
|
|
49
|
+
// Pattern: " pkg@version:" or " '@scope/pkg@version':" at start of line
|
|
50
|
+
// Also handle: " pkg@version(peer@ver):"
|
|
51
|
+
// Scoped packages start with @scope/name, unscoped are plain names.
|
|
52
|
+
const snapshotPattern = /^ {2}'?(@[^/@\s']+\/[^/@\s'(]+|[^/@\s'(]+)@([^:()\s']+)/gm;
|
|
53
|
+
let match;
|
|
54
|
+
while ((match = snapshotPattern.exec(raw)) !== null) {
|
|
55
|
+
const name = match[1];
|
|
56
|
+
const version = match[2];
|
|
57
|
+
if (name && version && !result.has(name)) {
|
|
58
|
+
result.set(name, version);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// pnpm-lock.yaml v6/v8: packages section with /pkg/version: format
|
|
62
|
+
// Pattern: " /pkg/version:" — older pnpm format
|
|
63
|
+
const packagePattern = /^ {2}\/(@?[^/\s]+(?:\/[^/\s]+)?)\/([^:()\s]+):/gm;
|
|
64
|
+
while ((match = packagePattern.exec(raw)) !== null) {
|
|
65
|
+
const name = match[1];
|
|
66
|
+
const version = match[2];
|
|
67
|
+
if (name && version && !result.has(name)) {
|
|
68
|
+
result.set(name, version);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
async function tryParsePackageLock(projectPath) {
|
|
74
|
+
const lockPath = join(projectPath, 'package-lock.json');
|
|
75
|
+
let raw;
|
|
76
|
+
try {
|
|
77
|
+
raw = await readFile(lockPath, 'utf-8');
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
try {
|
|
83
|
+
return parsePackageLockJson(raw);
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse package-lock.json v2/v3 format.
|
|
91
|
+
* v3: top-level `packages` object with keys like "node_modules/pkg" or
|
|
92
|
+
* "node_modules/pkg/node_modules/nested-pkg".
|
|
93
|
+
* v2: both `packages` and `dependencies` present.
|
|
94
|
+
* v1: only `dependencies` present (older format).
|
|
95
|
+
*/
|
|
96
|
+
export function parsePackageLockJson(raw) {
|
|
97
|
+
const result = new Map();
|
|
98
|
+
const parsed = JSON.parse(raw);
|
|
99
|
+
// v2/v3: use packages section
|
|
100
|
+
if (parsed.packages && typeof parsed.packages === 'object') {
|
|
101
|
+
const pkgs = parsed.packages;
|
|
102
|
+
for (const [key, entry] of Object.entries(pkgs)) {
|
|
103
|
+
if (!key || key === '') {
|
|
104
|
+
continue; // skip root package entry
|
|
105
|
+
}
|
|
106
|
+
const version = entry.version;
|
|
107
|
+
if (!version) {
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Extract package name from key: "node_modules/foo" -> "foo"
|
|
111
|
+
// Scoped: "node_modules/@scope/foo" -> "@scope/foo"
|
|
112
|
+
// Nested: "node_modules/foo/node_modules/bar" -> "bar" (use the deepest)
|
|
113
|
+
const name = extractNameFromPackagesKey(key);
|
|
114
|
+
if (name && !result.has(name)) {
|
|
115
|
+
result.set(name, version);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
// v1 fallback: use dependencies section (flat list)
|
|
121
|
+
if (parsed.dependencies && typeof parsed.dependencies === 'object') {
|
|
122
|
+
flattenDependencies(parsed.dependencies, result);
|
|
123
|
+
}
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
function extractNameFromPackagesKey(key) {
|
|
127
|
+
// Remove leading "node_modules/" segments, keep the last package name
|
|
128
|
+
const parts = key.split('node_modules/');
|
|
129
|
+
const lastPart = parts[parts.length - 1];
|
|
130
|
+
if (!lastPart) {
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
// Handle scoped packages like "@scope/name"
|
|
134
|
+
return lastPart || null;
|
|
135
|
+
}
|
|
136
|
+
function flattenDependencies(deps, result) {
|
|
137
|
+
for (const [name, entry] of Object.entries(deps)) {
|
|
138
|
+
if (entry.version && !result.has(name)) {
|
|
139
|
+
result.set(name, entry.version);
|
|
140
|
+
}
|
|
141
|
+
if (entry.dependencies && typeof entry.dependencies === 'object') {
|
|
142
|
+
flattenDependencies(entry.dependencies, result);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
async function readDirectDepsFromPackageJson(projectPath) {
|
|
147
|
+
const result = new Map();
|
|
148
|
+
try {
|
|
149
|
+
const raw = await readFile(join(projectPath, 'package.json'), 'utf-8');
|
|
150
|
+
const parsed = JSON.parse(raw);
|
|
151
|
+
const allDeps = {
|
|
152
|
+
...(parsed.dependencies ?? {}),
|
|
153
|
+
...(parsed.devDependencies ?? {}),
|
|
154
|
+
};
|
|
155
|
+
for (const [name, version] of Object.entries(allDeps)) {
|
|
156
|
+
result.set(name, version.replace(/^[\^~>=<]/, ''));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// no package.json or parse error — return empty map
|
|
161
|
+
}
|
|
162
|
+
return result;
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=lockfile-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lockfile-parser.js","sourceRoot":"","sources":["../../../src/engine/dep-auditor/lockfile-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true if installedVersion falls within vulnerableRange.
|
|
3
|
+
* vulnerableRange supports:
|
|
4
|
+
* - exact: "1.2.3"
|
|
5
|
+
* - caret: "^1.2.3"
|
|
6
|
+
* - tilde: "~1.2.3"
|
|
7
|
+
* - comparators: ">=1.0.0", "<=2.0.0", ">1.0.0", "<2.0.0"
|
|
8
|
+
* - AND ranges (space-separated): ">=1.0.0 <2.0.0"
|
|
9
|
+
* - OR ranges (|| separated): ">=1.0.0 <1.5.0 || >=2.0.0 <2.5.0"
|
|
10
|
+
* - pre-release suffixes: "1.2.3-rc.1", ">=1.0.0-alpha"
|
|
11
|
+
*/
|
|
12
|
+
export declare function isVersionVulnerable(installedVersion: string, vulnerableRange: string): boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Returns true if installedVersion is strictly below threshold.
|
|
15
|
+
* Equivalent to isVersionVulnerable(installed, '<threshold').
|
|
16
|
+
* Used as backward-compatible replacement for the old isVersionBelow().
|
|
17
|
+
*/
|
|
18
|
+
export declare function isVersionBelow(installedVersion: string, threshold: string): boolean;
|
|
19
|
+
//# sourceMappingURL=semver-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver-utils.d.ts","sourceRoot":"","sources":["../../../src/engine/dep-auditor/semver-utils.ts"],"names":[],"mappings":"AA2GA;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,gBAAgB,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,OAAO,CAmB9F;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,gBAAgB,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAOnF"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a version string like "1.2.3", "1.2.3-rc.1", "^1.2.3" into parts.
|
|
3
|
+
* Strips leading range operators (^, ~, >=, <=, >, <) before parsing.
|
|
4
|
+
*/
|
|
5
|
+
function parseSemver(raw) {
|
|
6
|
+
const stripped = raw.trim().replace(/^[^0-9]*/, '');
|
|
7
|
+
const match = /^(\d+)\.(\d+)\.(\d+)(?:-([a-zA-Z0-9._-]+))?/.exec(stripped);
|
|
8
|
+
if (!match) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
return {
|
|
12
|
+
major: parseInt(match[1] ?? '0', 10),
|
|
13
|
+
minor: parseInt(match[2] ?? '0', 10),
|
|
14
|
+
patch: parseInt(match[3] ?? '0', 10),
|
|
15
|
+
preRelease: match[4] ?? '',
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/** Compare two parsed versions. Returns negative if a < b, 0 if equal, positive if a > b. */
|
|
19
|
+
function compareTuples(a, b) {
|
|
20
|
+
if (a.major !== b.major) {
|
|
21
|
+
return a.major - b.major;
|
|
22
|
+
}
|
|
23
|
+
if (a.minor !== b.minor) {
|
|
24
|
+
return a.minor - b.minor;
|
|
25
|
+
}
|
|
26
|
+
if (a.patch !== b.patch) {
|
|
27
|
+
return a.patch - b.patch;
|
|
28
|
+
}
|
|
29
|
+
// Pre-release handling: a version without pre-release is greater than one with
|
|
30
|
+
if (a.preRelease === '' && b.preRelease !== '') {
|
|
31
|
+
return 1;
|
|
32
|
+
}
|
|
33
|
+
if (a.preRelease !== '' && b.preRelease === '') {
|
|
34
|
+
return -1;
|
|
35
|
+
}
|
|
36
|
+
// Both have pre-release: compare lexicographically
|
|
37
|
+
return a.preRelease < b.preRelease ? -1 : a.preRelease > b.preRelease ? 1 : 0;
|
|
38
|
+
}
|
|
39
|
+
/** Evaluate a single comparator like ">=1.0.0", "<2.0.0", "1.2.3" against installed. */
|
|
40
|
+
function evaluateComparator(installed, comparator) {
|
|
41
|
+
const c = comparator.trim();
|
|
42
|
+
if (c === '' || c === '*') {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
if (c.startsWith('>=')) {
|
|
46
|
+
const bound = parseSemver(c.slice(2));
|
|
47
|
+
return bound !== null && compareTuples(installed, bound) >= 0;
|
|
48
|
+
}
|
|
49
|
+
if (c.startsWith('<=')) {
|
|
50
|
+
const bound = parseSemver(c.slice(2));
|
|
51
|
+
return bound !== null && compareTuples(installed, bound) <= 0;
|
|
52
|
+
}
|
|
53
|
+
if (c.startsWith('>')) {
|
|
54
|
+
const bound = parseSemver(c.slice(1));
|
|
55
|
+
return bound !== null && compareTuples(installed, bound) > 0;
|
|
56
|
+
}
|
|
57
|
+
if (c.startsWith('<')) {
|
|
58
|
+
const bound = parseSemver(c.slice(1));
|
|
59
|
+
return bound !== null && compareTuples(installed, bound) < 0;
|
|
60
|
+
}
|
|
61
|
+
if (c.startsWith('~')) {
|
|
62
|
+
// ~1.2.3 := >=1.2.3 <1.3.0
|
|
63
|
+
const base = parseSemver(c.slice(1));
|
|
64
|
+
if (!base) {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
const upper = {
|
|
68
|
+
major: base.major,
|
|
69
|
+
minor: base.minor + 1,
|
|
70
|
+
patch: 0,
|
|
71
|
+
preRelease: '',
|
|
72
|
+
};
|
|
73
|
+
return compareTuples(installed, base) >= 0 && compareTuples(installed, upper) < 0;
|
|
74
|
+
}
|
|
75
|
+
if (c.startsWith('^')) {
|
|
76
|
+
// ^1.2.3 := >=1.2.3 <2.0.0, ^0.2.3 := >=0.2.3 <0.3.0, ^0.0.3 := >=0.0.3 <0.0.4
|
|
77
|
+
const base = parseSemver(c.slice(1));
|
|
78
|
+
if (!base) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
let upper;
|
|
82
|
+
if (base.major > 0) {
|
|
83
|
+
upper = { major: base.major + 1, minor: 0, patch: 0, preRelease: '' };
|
|
84
|
+
}
|
|
85
|
+
else if (base.minor > 0) {
|
|
86
|
+
upper = { major: 0, minor: base.minor + 1, patch: 0, preRelease: '' };
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
upper = { major: 0, minor: 0, patch: base.patch + 1, preRelease: '' };
|
|
90
|
+
}
|
|
91
|
+
return compareTuples(installed, base) >= 0 && compareTuples(installed, upper) < 0;
|
|
92
|
+
}
|
|
93
|
+
// Exact version match
|
|
94
|
+
const exact = parseSemver(c);
|
|
95
|
+
if (!exact) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
return compareTuples(installed, exact) === 0;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Returns true if installedVersion falls within vulnerableRange.
|
|
102
|
+
* vulnerableRange supports:
|
|
103
|
+
* - exact: "1.2.3"
|
|
104
|
+
* - caret: "^1.2.3"
|
|
105
|
+
* - tilde: "~1.2.3"
|
|
106
|
+
* - comparators: ">=1.0.0", "<=2.0.0", ">1.0.0", "<2.0.0"
|
|
107
|
+
* - AND ranges (space-separated): ">=1.0.0 <2.0.0"
|
|
108
|
+
* - OR ranges (|| separated): ">=1.0.0 <1.5.0 || >=2.0.0 <2.5.0"
|
|
109
|
+
* - pre-release suffixes: "1.2.3-rc.1", ">=1.0.0-alpha"
|
|
110
|
+
*/
|
|
111
|
+
export function isVersionVulnerable(installedVersion, vulnerableRange) {
|
|
112
|
+
const installed = parseSemver(installedVersion);
|
|
113
|
+
if (!installed) {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
// Split by || for OR groups
|
|
117
|
+
const orGroups = vulnerableRange.split('||').map((g) => g.trim());
|
|
118
|
+
for (const group of orGroups) {
|
|
119
|
+
// Each group is an AND of space-separated comparators
|
|
120
|
+
const comparators = group.split(/\s+/).filter((c) => c !== '');
|
|
121
|
+
const allMatch = comparators.every((c) => evaluateComparator(installed, c));
|
|
122
|
+
if (allMatch) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return false;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Returns true if installedVersion is strictly below threshold.
|
|
130
|
+
* Equivalent to isVersionVulnerable(installed, '<threshold').
|
|
131
|
+
* Used as backward-compatible replacement for the old isVersionBelow().
|
|
132
|
+
*/
|
|
133
|
+
export function isVersionBelow(installedVersion, threshold) {
|
|
134
|
+
const installed = parseSemver(installedVersion);
|
|
135
|
+
const bound = parseSemver(threshold);
|
|
136
|
+
if (!installed || !bound) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
return compareTuples(installed, bound) < 0;
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=semver-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"semver-utils.js","sourceRoot":"","sources":["../../../src/engine/dep-auditor/semver-utils.ts"],"names":[],"mappings":"AAKA;;;GAGG;AACH,SAAS,WAAW,CAAC,GAAW;IAC9B,MAAM,QAAQ,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACpD,MAAM,KAAK,GAAG,6CAA6C,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC3E,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACpC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,EAAE,CAAC;QACpC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE;KAC3B,CAAC;AACJ,CAAC;AAED,6FAA6F;AAC7F,SAAS,aAAa,CAAC,CAAc,EAAE,CAAc;IACnD,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAC3B,CAAC;IACD,+EAA+E;IAC/E,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,IAAI,CAAC,CAAC,UAAU,KAAK,EAAE,EAAE,CAAC;QAC/C,OAAO,CAAC,CAAC,CAAC;IACZ,CAAC;IACD,mDAAmD;IACnD,OAAO,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,wFAAwF;AACxF,SAAS,kBAAkB,CAAC,SAAsB,EAAE,UAAkB;IACpE,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC;IAC5B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,IAAI,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,IAAI,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,IAAI,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,OAAO,KAAK,KAAK,IAAI,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,2BAA2B;QAC3B,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,KAAK,GAAgB;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC;YACrB,KAAK,EAAE,CAAC;YACR,UAAU,EAAE,EAAE;SACf,CAAC;QACF,OAAO,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACpF,CAAC;IACD,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,+EAA+E;QAC/E,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,KAAkB,CAAC;QACvB,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YACnB,KAAK,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACxE,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;QACxE,CAAC;QACD,OAAO,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACpF,CAAC;IAED,sBAAsB;IACtB,MAAM,KAAK,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,mBAAmB,CAAC,gBAAwB,EAAE,eAAuB;IACnF,MAAM,SAAS,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,KAAK,CAAC;IACf,CAAC;IAED,4BAA4B;IAC5B,MAAM,QAAQ,GAAG,eAAe,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IAElE,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,sDAAsD;QACtD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC/D,MAAM,QAAQ,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC;QAC5E,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,gBAAwB,EAAE,SAAiB;IACxE,MAAM,SAAS,GAAG,WAAW,CAAC,gBAAgB,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;IACrC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,aAAa,CAAC,SAAS,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vuln-data.d.ts","sourceRoot":"","sources":["../../../src/engine/dep-auditor/vuln-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"vuln-data.d.ts","sourceRoot":"","sources":["../../../src/engine/dep-auditor/vuln-data.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAGpE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,EAAE,CAgHxD,CAAC;AAEF,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAoBjE"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isVersionBelow } from './semver-utils.js';
|
|
1
2
|
export const KNOWN_VULNS = {
|
|
2
3
|
lodash: [
|
|
3
4
|
{
|
|
@@ -111,26 +112,6 @@ export const KNOWN_VULNS = {
|
|
|
111
112
|
},
|
|
112
113
|
],
|
|
113
114
|
};
|
|
114
|
-
function isVersionBelow(current, threshold) {
|
|
115
|
-
const parseParts = (v) => {
|
|
116
|
-
const cleaned = v.replace(/^[^0-9]*/, '');
|
|
117
|
-
return cleaned.split('.').map((p) => parseInt(p, 10) || 0);
|
|
118
|
-
};
|
|
119
|
-
const cur = parseParts(current);
|
|
120
|
-
const thr = parseParts(threshold);
|
|
121
|
-
const len = Math.max(cur.length, thr.length);
|
|
122
|
-
for (let i = 0; i < len; i++) {
|
|
123
|
-
const c = cur[i] ?? 0;
|
|
124
|
-
const t = thr[i] ?? 0;
|
|
125
|
-
if (c < t) {
|
|
126
|
-
return true;
|
|
127
|
-
}
|
|
128
|
-
if (c > t) {
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
return false;
|
|
133
|
-
}
|
|
134
115
|
export function getVulns(name, version) {
|
|
135
116
|
const entries = KNOWN_VULNS[name];
|
|
136
117
|
if (!entries) {
|