@lockhawk/core 0.2.1 → 0.2.3
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/index.d.ts +9 -7
- package/dist/index.js +43 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -543,16 +543,18 @@ declare function toSarif(result: ScanResult): SarifLog;
|
|
|
543
543
|
/** Stringified SARIF log. */
|
|
544
544
|
declare function toSarifString(result: ScanResult): string;
|
|
545
545
|
|
|
546
|
-
/** Placeholder the report UI shell embeds so we can inject scan data at scan time. */
|
|
547
|
-
declare const DATA_MARKER = "<!--LOCKHAWK_DATA-->";
|
|
548
546
|
/**
|
|
549
|
-
* Produce a self-contained HTML report
|
|
550
|
-
*
|
|
551
|
-
*
|
|
547
|
+
* Produce a self-contained HTML report for a scan result.
|
|
548
|
+
*
|
|
549
|
+
* The page is fully server-rendered: no client-side JavaScript, no embedded
|
|
550
|
+
* data blob, no external resources. Every dynamic value is HTML-escaped, the
|
|
551
|
+
* layout flows normally within a width-constrained container, and long advisory
|
|
552
|
+
* text lives in a collapsed, contained block — so the report cannot overflow the
|
|
553
|
+
* viewport or render attacker-controlled advisory text as live markup.
|
|
552
554
|
*/
|
|
553
|
-
declare function toHtml(result: ScanResult
|
|
555
|
+
declare function toHtml(result: ScanResult): string;
|
|
554
556
|
|
|
555
557
|
/** Render a scan result as JUnit XML (one failed test per finding). */
|
|
556
558
|
declare function toJunit(result: ScanResult): string;
|
|
557
559
|
|
|
558
|
-
export { AutoSource, type CvssResult,
|
|
560
|
+
export { AutoSource, type CvssResult, type DatabaseInfo, type DepNode, type DepScope, type DependencyGraph, type DetectedLockfile, type Finding, type FindingsOptions, LockfileError, OfflineDbMissingError, type OfflineMeta, OfflineSource, type OnlineClientOptions, OnlineSource, type OsvAffected, OsvClient, OsvDatabase, type OsvEvent, type OsvRange, type OsvReference, type OsvSeverity, type OsvVulnerability, type PackageManager, type PackageRef, type PkgKey, type RawGraph, type RawNode, type ResolvedSource, type RootManifest, SEVERITY_RANK, SHARD_BUCKETS, type SarifLog, type ScanOptions, type ScanResult, type ScanStats, type ScanSummary, type Severity, type SeverityInfo, type SourceMode, type SourceOptions, TOOL, type UnscannablePackage, type UpdateResult, type VulnMatch, type VulnSource, buildDependencyGraph, buildFindings, canonicalId, createSource, dedupeVulnerabilities, detectLockfile, isVersionAffected, levelFromLabel, levelFromScore, loadAdvisoriesForPackages, loadDependencyGraph, nearestFix, offlineDbDir, offlineMetaPath, parseLockfile, pkgKey, readOfflineMeta, readRootManifest, resolveCacheDir, resolveSeverity, rootLabel, scan, scoreFromVector, severityAtLeast, shardBucket, shortestPath, shouldFail, toHtml, toJson, toJunit, toSarif, toSarifString, uniqueScannablePackages, updateOfflineDatabase, vulnerabilityAffects };
|
package/dist/index.js
CHANGED
|
@@ -2143,18 +2143,8 @@ function toSarifString(result) {
|
|
|
2143
2143
|
}
|
|
2144
2144
|
|
|
2145
2145
|
// src/report/html.ts
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
const json = JSON.stringify(result).replace(/</g, "\\u003c").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
2149
|
-
return `<script>window.__SCAN_RESULT__ = ${json};</script>`;
|
|
2150
|
-
}
|
|
2151
|
-
function toHtml(result, shell) {
|
|
2152
|
-
const dataScript = embed(result);
|
|
2153
|
-
if (shell) {
|
|
2154
|
-
if (shell.includes(DATA_MARKER)) return shell.replace(DATA_MARKER, dataScript);
|
|
2155
|
-
return shell.replace("</head>", `${dataScript}</head>`);
|
|
2156
|
-
}
|
|
2157
|
-
return fallbackTemplate(result, dataScript);
|
|
2146
|
+
function toHtml(result) {
|
|
2147
|
+
return renderHtml(result);
|
|
2158
2148
|
}
|
|
2159
2149
|
var SEVERITY_COLORS = {
|
|
2160
2150
|
critical: "#b4232c",
|
|
@@ -2178,7 +2168,7 @@ function httpHref(url) {
|
|
|
2178
2168
|
return void 0;
|
|
2179
2169
|
}
|
|
2180
2170
|
}
|
|
2181
|
-
function
|
|
2171
|
+
function renderHtml(result) {
|
|
2182
2172
|
const { summary } = result;
|
|
2183
2173
|
const cards = ["critical", "high", "medium", "low", "unknown"].map(
|
|
2184
2174
|
(sev) => `
|
|
@@ -2189,14 +2179,27 @@ function fallbackTemplate(result, dataScript) {
|
|
|
2189
2179
|
const rows = result.findings.map((f) => {
|
|
2190
2180
|
const path = f.dependencyPaths[0]?.join(" \u203A ") ?? f.packageName;
|
|
2191
2181
|
const refs = f.references.slice(0, 3).map((u) => httpHref(u)).filter((u) => u !== void 0).map((u) => `<a href="${esc(u)}" target="_blank" rel="noopener">link</a>`).join(" ");
|
|
2182
|
+
const rec = f.recommendation ? `<p class="rec"><strong>Recommendation:</strong> ${esc(f.recommendation)}</p>` : "";
|
|
2192
2183
|
return `
|
|
2193
2184
|
<tr>
|
|
2194
|
-
<td><span class="pill" style="background:${SEVERITY_COLORS[f.severity.level]}">${
|
|
2195
|
-
|
|
2196
|
-
|
|
2185
|
+
<td><span class="pill" style="background:${SEVERITY_COLORS[f.severity.level]}">${esc(
|
|
2186
|
+
f.severity.level
|
|
2187
|
+
)}${f.severity.score ? ` ${f.severity.score}` : ""}</span></td>
|
|
2188
|
+
<td><code>${esc(f.packageName)}@${esc(f.version)}</code><div class="scope">${esc(f.scope)}${f.direct ? " \xB7 direct" : ""}</div></td>
|
|
2189
|
+
<td><a href="https://osv.dev/${encodeURIComponent(f.id)}" target="_blank" rel="noopener">${esc(
|
|
2190
|
+
f.id
|
|
2191
|
+
)}</a></td>
|
|
2197
2192
|
<td>${esc(f.summary)}<div class="path">${esc(path)}</div></td>
|
|
2198
2193
|
<td>${f.fixedVersions[0] ? esc(f.fixedVersions[0]) : "\u2014"}</td>
|
|
2199
|
-
<td>${refs}</td>
|
|
2194
|
+
<td class="refs">${refs}</td>
|
|
2195
|
+
</tr>
|
|
2196
|
+
<tr class="detail-row">
|
|
2197
|
+
<td colspan="6">
|
|
2198
|
+
<details>
|
|
2199
|
+
<summary>Advisory details</summary>
|
|
2200
|
+
${rec}<pre class="advisory">${esc(f.details ?? f.summary)}</pre>
|
|
2201
|
+
</details>
|
|
2202
|
+
</td>
|
|
2200
2203
|
</tr>`;
|
|
2201
2204
|
}).join("");
|
|
2202
2205
|
const dbWarnings = result.database.warnings.map((w) => `<div class="warn">\u26A0 ${esc(w)}</div>`).join("");
|
|
@@ -2206,43 +2209,52 @@ function fallbackTemplate(result, dataScript) {
|
|
|
2206
2209
|
<meta charset="utf-8">
|
|
2207
2210
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
2208
2211
|
<title>lockhawk report \u2014 ${esc(result.target.root.name)}</title>
|
|
2209
|
-
${dataScript}
|
|
2210
2212
|
<style>
|
|
2211
2213
|
:root { color-scheme: light dark; }
|
|
2212
2214
|
* { box-sizing: border-box; }
|
|
2215
|
+
html, body { max-width: 100%; overflow-x: hidden; }
|
|
2213
2216
|
body { font: 15px/1.5 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; margin: 0; background: #f6f7f9; color: #1c1e21; }
|
|
2214
2217
|
header { background: #11161d; color: #fff; padding: 24px 32px; }
|
|
2215
2218
|
header h1 { margin: 0 0 4px; font-size: 20px; }
|
|
2216
|
-
header .meta { color: #9aa4b2; font-size: 13px; }
|
|
2217
|
-
main { max-width: 1100px; margin: 0 auto; padding: 24px 32px; }
|
|
2218
|
-
.cards { display: grid; grid-template-columns: repeat(
|
|
2219
|
+
header .meta { color: #9aa4b2; font-size: 13px; overflow-wrap: anywhere; }
|
|
2220
|
+
main { max-width: 1100px; margin: 0 auto; padding: 24px clamp(16px, 4vw, 32px) 40px; }
|
|
2221
|
+
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 12px; margin-bottom: 8px; }
|
|
2219
2222
|
.card { background: #fff; border-radius: 8px; padding: 14px 16px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
|
|
2220
2223
|
.card .count { font-size: 28px; font-weight: 700; }
|
|
2221
2224
|
.card .label { text-transform: capitalize; color: #6b7280; font-size: 13px; }
|
|
2222
|
-
.warn { background: #fff7e6; border: 1px solid #ffd591; color: #874d00; padding: 8px 12px; border-radius: 6px; margin: 12px 0; font-size: 13px; }
|
|
2223
|
-
table {
|
|
2224
|
-
|
|
2225
|
-
th {
|
|
2225
|
+
.warn { background: #fff7e6; border: 1px solid #ffd591; color: #874d00; padding: 8px 12px; border-radius: 6px; margin: 12px 0; font-size: 13px; overflow-wrap: anywhere; }
|
|
2226
|
+
.table-wrap { margin-top: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }
|
|
2227
|
+
table { width: 100%; border-collapse: collapse; background: #fff; }
|
|
2228
|
+
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eef0f3; vertical-align: top; font-size: 13px; overflow-wrap: anywhere; word-break: break-word; }
|
|
2229
|
+
th { background: #f0f2f5; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; color: #6b7280; white-space: nowrap; }
|
|
2226
2230
|
.pill { color: #fff; padding: 2px 8px; border-radius: 999px; font-size: 12px; text-transform: capitalize; white-space: nowrap; }
|
|
2227
2231
|
.scope, .path { color: #6b7280; font-size: 12px; }
|
|
2228
2232
|
.path { margin-top: 4px; }
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2233
|
+
.refs { white-space: nowrap; }
|
|
2234
|
+
code { background: #eef0f3; padding: 1px 5px; border-radius: 4px; max-width: 100%; }
|
|
2235
|
+
.detail-row td { border-bottom: 2px solid #eef0f3; padding-top: 0; }
|
|
2236
|
+
details { font-size: 13px; }
|
|
2237
|
+
summary { cursor: pointer; color: #3a7bd5; font-size: 12px; padding: 4px 0; width: max-content; }
|
|
2238
|
+
.rec { margin: 8px 0; font-size: 13px; }
|
|
2239
|
+
pre.advisory { white-space: pre-wrap; word-break: break-word; overflow-x: auto; max-width: 100%; background: #f6f7f9; border: 1px solid #eef0f3; border-radius: 6px; padding: 10px 12px; margin: 6px 0 4px; font-size: 12.5px; }
|
|
2240
|
+
.empty { background: #fff; border-radius: 8px; padding: 40px; text-align: center; color: #3a9e54; font-size: 18px; box-shadow: 0 1px 3px rgba(0,0,0,.08); margin-top: 16px; }
|
|
2241
|
+
footer { max-width: 1100px; margin: 0 auto; padding: 16px clamp(16px, 4vw, 32px) 40px; color: #9aa4b2; font-size: 12px; }
|
|
2232
2242
|
</style>
|
|
2233
2243
|
</head>
|
|
2234
2244
|
<body>
|
|
2235
2245
|
<header>
|
|
2236
2246
|
<h1>lockhawk report</h1>
|
|
2237
|
-
<div class="meta">${esc(result.target.root.name)}${result.target.root.version ? `@${esc(result.target.root.version)}` : ""} \xB7 ${esc(result.target.manager)} \xB7 ${result.stats.totalPackages} packages \xB7 scanned ${esc(
|
|
2247
|
+
<div class="meta">${esc(result.target.root.name)}${result.target.root.version ? `@${esc(result.target.root.version)}` : ""} \xB7 ${esc(result.target.manager)} \xB7 ${result.stats.totalPackages} packages \xB7 scanned ${esc(
|
|
2248
|
+
result.scannedAt
|
|
2249
|
+
)}</div>
|
|
2238
2250
|
</header>
|
|
2239
2251
|
<main>
|
|
2240
2252
|
<div class="cards">${cards}</div>
|
|
2241
2253
|
${dbWarnings}
|
|
2242
|
-
${result.findings.length === 0 ? '<div class="empty">\u2713 No known vulnerabilities found.</div>' : `<table>
|
|
2254
|
+
${result.findings.length === 0 ? '<div class="empty">\u2713 No known vulnerabilities found.</div>' : `<div class="table-wrap"><table>
|
|
2243
2255
|
<thead><tr><th>Severity</th><th>Package</th><th>Advisory</th><th>Summary & path</th><th>Fixed in</th><th>Refs</th></tr></thead>
|
|
2244
2256
|
<tbody>${rows}</tbody>
|
|
2245
|
-
</table>`}
|
|
2257
|
+
</table></div>`}
|
|
2246
2258
|
</main>
|
|
2247
2259
|
<footer>Generated by lockhawk v${esc(result.tool.version)} \xB7 data from OSV.dev \xB7 database: ${esc(
|
|
2248
2260
|
result.database.source
|
|
@@ -2297,7 +2309,6 @@ function toJunit(result) {
|
|
|
2297
2309
|
}
|
|
2298
2310
|
export {
|
|
2299
2311
|
AutoSource,
|
|
2300
|
-
DATA_MARKER,
|
|
2301
2312
|
LockfileError,
|
|
2302
2313
|
OfflineDbMissingError,
|
|
2303
2314
|
OfflineSource,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types.ts","../src/lockfiles/normalize.ts","../src/lockfiles/detect.ts","../src/lockfiles/raw.ts","../src/lockfiles/npm.ts","../src/lockfiles/yarn.ts","../src/lockfiles/pnpm.ts","../src/graph/paths.ts","../src/match/ranges.ts","../src/match/dedupe.ts","../src/match/findings.ts","../src/score/cvss4-data.ts","../src/score/cvss4.ts","../src/score/cvss.ts","../src/osv/database.ts","../src/engine.ts","../src/cache/paths.ts","../src/osv/client.ts","../src/osv/offline-db.ts","../src/osv/source.ts","../src/report/json.ts","../src/report/sarif.ts","../src/report/html.ts","../src/report/junit.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Shared data model for lockhawk.\n//\n// Every package (CLI, report UI, GitHub Action) depends on these types — this\n// is the contract that keeps the pipeline stages and the reporters in sync.\n// ---------------------------------------------------------------------------\n\n/** Qualitative severity bands (CVSS-aligned, plus `unknown` for un-scored advisories). */\nexport type Severity = 'critical' | 'high' | 'medium' | 'low' | 'none' | 'unknown';\n\n/** Ordering used for `--severity-threshold` and `--fail-on` comparisons. */\nexport const SEVERITY_RANK: Record<Severity, number> = {\n none: 0,\n unknown: 1,\n low: 2,\n medium: 3,\n high: 4,\n critical: 5,\n};\n\n/** `true` when `level` is at least as severe as `threshold`. */\nexport function severityAtLeast(level: Severity, threshold: Severity): boolean {\n return SEVERITY_RANK[level] >= SEVERITY_RANK[threshold];\n}\n\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm';\n\n/** How a dependency is reachable from the project root. */\nexport type DepScope = 'prod' | 'dev' | 'optional' | 'peer';\n\n/** Unique identity of an installed package: `name@version`. */\nexport type PkgKey = string;\n\n/** Build a {@link PkgKey} from a name and version. */\nexport function pkgKey(name: string, version: string): PkgKey {\n return `${name}@${version}`;\n}\n\n/** A single installed package in the dependency graph. */\nexport interface DepNode {\n /** `name@version` — the node's key in {@link DependencyGraph.nodes}. */\n key: PkgKey;\n name: string;\n version: string;\n /** Strongest scope by which this node is reachable (prod beats dev/optional). */\n scope: DepScope;\n /** Whether this is a direct dependency of the project root. */\n direct: boolean;\n /** Keys of packages this node depends on (edges out). */\n dependencies: PkgKey[];\n /** Set when the package has no queryable registry version (file:/link:/git:). */\n unscannable?: { reason: string };\n}\n\n/** The normalized dependency tree, independent of which package manager produced it. */\nexport interface DependencyGraph {\n manager: PackageManager;\n lockfilePath: string;\n lockfileVersion?: string | number;\n root: { name: string; version?: string };\n /** All installed packages, keyed by {@link PkgKey}. */\n nodes: Record<PkgKey, DepNode>;\n /** Keys of the project's direct dependencies. */\n directKeys: PkgKey[];\n}\n\n// --- OSV schema (the subset we consume) -----------------------------------\n// https://ossf.github.io/osv-schema/\n\nexport interface OsvEvent {\n introduced?: string;\n fixed?: string;\n last_affected?: string;\n limit?: string;\n}\n\nexport interface OsvRange {\n type: 'SEMVER' | 'ECOSYSTEM' | 'GIT';\n events: OsvEvent[];\n repo?: string;\n}\n\nexport interface OsvSeverity {\n /** e.g. `CVSS_V3`, `CVSS_V4`. */\n type: string;\n /** CVSS vector string. */\n score: string;\n}\n\nexport interface OsvAffected {\n package?: { ecosystem?: string; name?: string; purl?: string };\n ranges?: OsvRange[];\n versions?: string[];\n severity?: OsvSeverity[];\n ecosystem_specific?: Record<string, unknown>;\n database_specific?: Record<string, unknown>;\n}\n\nexport interface OsvReference {\n type?: string;\n url: string;\n}\n\nexport interface OsvVulnerability {\n id: string;\n modified?: string;\n published?: string;\n /** RFC3339 timestamp; when present the advisory has been retracted and must be ignored. */\n withdrawn?: string;\n aliases?: string[];\n related?: string[];\n summary?: string;\n details?: string;\n severity?: OsvSeverity[];\n affected?: OsvAffected[];\n references?: OsvReference[];\n database_specific?: Record<string, unknown>;\n}\n\n// --- Scan results ----------------------------------------------------------\n\n/** Resolved severity for a finding, with provenance so the UI never shows a bare number. */\nexport interface SeverityInfo {\n level: Severity;\n /** Numeric CVSS base score (0–10) when computable. */\n score?: number;\n /** CVSS vector string the score was derived from. */\n vector?: string;\n /** e.g. `CVSS:3.1`, `CVSS:4.0`. */\n cvssVersion?: string;\n source: 'cvss' | 'database' | 'unknown';\n}\n\n/** One vulnerability affecting one installed package version. */\nexport interface Finding {\n /** Canonical id (prefers CVE, then GHSA, then the OSV id). */\n id: string;\n /** All known identifiers for this advisory, including the canonical one. */\n aliases: string[];\n packageName: string;\n version: string;\n scope: DepScope;\n direct: boolean;\n severity: SeverityInfo;\n summary: string;\n details?: string;\n references: string[];\n /** Versions that resolve this advisory (derived from OSV `fixed` events). */\n fixedVersions: string[];\n /** Human-readable mitigation guidance. */\n recommendation?: string;\n /** Each path runs root → … → `name@version`, explaining why the package is present. */\n dependencyPaths: PkgKey[][];\n source: string;\n}\n\nexport interface DatabaseInfo {\n source: 'offline' | 'online' | 'mixed';\n recordCount?: number;\n /** ISO timestamp of when the offline DB was last refreshed. */\n lastUpdated?: string;\n ageHours?: number;\n stale: boolean;\n warnings: string[];\n}\n\nexport interface ScanSummary {\n total: number;\n critical: number;\n high: number;\n medium: number;\n low: number;\n unknown: number;\n none: number;\n /** Number of distinct vulnerable packages (not advisories). */\n vulnerablePackages: number;\n /** Number of findings that have at least one known fixed version. */\n fixable: number;\n}\n\nexport interface ScanStats {\n totalPackages: number;\n uniquePackages: number;\n directDependencies: number;\n unscannable: number;\n durationMs?: number;\n}\n\nexport interface UnscannablePackage {\n name: string;\n version: string;\n reason: string;\n}\n\n/** The complete output of a scan — what reporters serialize and the dashboard renders. */\nexport interface ScanResult {\n schemaVersion: 1;\n tool: { name: string; version: string };\n /** ISO timestamp. */\n scannedAt: string;\n target: {\n path: string;\n manager: PackageManager;\n lockfile: string;\n root: { name: string; version?: string };\n };\n database: DatabaseInfo;\n summary: ScanSummary;\n stats: ScanStats;\n findings: Finding[];\n unscannable: UnscannablePackage[];\n}\n\n// --- Engine options --------------------------------------------------------\n\nexport type SourceMode = 'auto' | 'offline' | 'online';\n\nexport interface ScanOptions {\n /** Project directory to scan (defaults to cwd). */\n path?: string;\n /** Vulnerability-source strategy. */\n mode?: SourceMode;\n cacheDir?: string;\n cacheTtlHours?: number;\n noCache?: boolean;\n concurrency?: number;\n /** Ignore dev dependencies. */\n prodOnly?: boolean;\n /** Advisory ids (CVE/GHSA/OSV) to suppress. */\n ignore?: string[];\n /** Fail hard on network errors instead of degrading to cache (fail-open). */\n strictNetwork?: boolean;\n /** Limit the scan to a single workspace by name. */\n workspace?: string;\n /** Drop findings below this severity from the report. */\n severityThreshold?: Severity;\n /** Progress callback (used by the CLI spinner). */\n onProgress?: (message: string) => void;\n}\n","import { resolve } from 'node:path';\nimport type { DependencyGraph } from '../types.js';\nimport { detectLockfile } from './detect.js';\nimport type { DetectedLockfile } from './detect.js';\nimport { buildDependencyGraph } from './raw.js';\nimport type { RawGraph } from './raw.js';\nimport { parseNpm } from './npm.js';\nimport { parseYarn } from './yarn.js';\nimport { parsePnpm } from './pnpm.js';\n\nexport class LockfileError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LockfileError';\n }\n}\n\n/** Parse a detected lockfile into the manager-agnostic {@link RawGraph}. */\nexport function parseLockfile(detected: DetectedLockfile): RawGraph {\n try {\n switch (detected.manager) {\n case 'npm':\n return parseNpm(detected.path);\n case 'yarn':\n return parseYarn(detected.path);\n case 'pnpm':\n return parsePnpm(detected.path);\n }\n } catch (err) {\n throw new LockfileError(\n `Failed to parse ${detected.filename}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Detect, parse and normalize the lockfile in `dir` into a {@link DependencyGraph}.\n * Throws {@link LockfileError} when no lockfile is present or parsing fails.\n */\nexport function loadDependencyGraph(dir: string): DependencyGraph {\n const detected = detectLockfile(resolve(dir));\n if (!detected) {\n throw new LockfileError(\n `No lockfile found in ${dir}. Expected one of: package-lock.json, yarn.lock, pnpm-lock.yaml.`,\n );\n }\n return buildDependencyGraph(parseLockfile(detected));\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { PackageManager } from '../types.js';\n\nexport interface DetectedLockfile {\n manager: PackageManager;\n /** Absolute or relative path to the lockfile. */\n path: string;\n filename: string;\n}\n\nconst LOCKFILES: { filename: string; manager: PackageManager }[] = [\n { filename: 'pnpm-lock.yaml', manager: 'pnpm' },\n { filename: 'yarn.lock', manager: 'yarn' },\n { filename: 'package-lock.json', manager: 'npm' },\n { filename: 'npm-shrinkwrap.json', manager: 'npm' },\n];\n\n/**\n * Find the lockfile to scan in `dir`. If several are present we prefer pnpm,\n * then yarn, then npm — mirroring how a project that committed multiple\n * lockfiles is most likely actually installed.\n */\nexport function detectLockfile(dir: string): DetectedLockfile | undefined {\n for (const { filename, manager } of LOCKFILES) {\n const path = join(dir, filename);\n if (existsSync(path) && statSync(path).isFile()) {\n return { manager, path, filename };\n }\n }\n return undefined;\n}\n\nexport interface RootManifest {\n name: string;\n version?: string;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n optionalDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n}\n\n/** Read and normalize the project's `package.json` (used to determine direct deps). */\nexport function readRootManifest(dir: string): RootManifest {\n const path = join(dir, 'package.json');\n let raw: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n raw = JSON.parse(readFileSync(path, 'utf8')) as Record<string, unknown>;\n } catch {\n raw = {};\n }\n }\n const asMap = (v: unknown): Record<string, string> =>\n v && typeof v === 'object' ? (v as Record<string, string>) : {};\n return {\n name: typeof raw.name === 'string' ? raw.name : 'project',\n version: typeof raw.version === 'string' ? raw.version : undefined,\n dependencies: asMap(raw.dependencies),\n devDependencies: asMap(raw.devDependencies),\n optionalDependencies: asMap(raw.optionalDependencies),\n peerDependencies: asMap(raw.peerDependencies),\n };\n}\n","import type {\n DependencyGraph,\n DepNode,\n DepScope,\n PackageManager,\n PkgKey,\n UnscannablePackage,\n} from '../types.js';\n\n/**\n * Manager-agnostic parser output. Each lockfile parser produces one of these;\n * a single {@link buildDependencyGraph} step then classifies scopes by\n * reachability and assembles the final {@link DependencyGraph}.\n *\n * Computing scope from reachability (rather than per-package `dev` flags) is\n * what lets us treat npm, yarn and pnpm uniformly — pnpm v9 lockfiles, for\n * instance, no longer carry a per-package `dev` field.\n */\nexport interface RawNode {\n key: PkgKey;\n name: string;\n version: string;\n /** Keys of packages this node depends on (edges out). May contain duplicates. */\n dependencies: PkgKey[];\n /** Set when there is no queryable registry version (file:/link:/git:/workspace). */\n unscannable?: { reason: string };\n}\n\nexport interface RawGraph {\n manager: PackageManager;\n lockfilePath: string;\n lockfileVersion?: string | number;\n root: { name: string; version?: string };\n nodes: Record<PkgKey, RawNode>;\n /** Direct production dependencies of the project root. */\n directProd: PkgKey[];\n /** Direct dev dependencies of the project root. */\n directDev: PkgKey[];\n /** Direct optional dependencies of the project root. */\n directOptional: PkgKey[];\n unscannable: UnscannablePackage[];\n}\n\n/** Breadth-first set of all keys reachable from the given starting keys. */\nfunction reachable(start: Iterable<PkgKey>, nodes: Record<PkgKey, RawNode>): Set<PkgKey> {\n const seen = new Set<PkgKey>();\n const queue: PkgKey[] = [];\n for (const k of start) {\n if (!seen.has(k)) {\n seen.add(k);\n queue.push(k);\n }\n }\n for (let i = 0; i < queue.length; i++) {\n const node = nodes[queue[i]!];\n if (!node) continue;\n for (const dep of node.dependencies) {\n if (!seen.has(dep)) {\n seen.add(dep);\n queue.push(dep);\n }\n }\n }\n return seen;\n}\n\n/**\n * Classify every node's scope by reachability and assemble the normalized graph.\n * Priority when a node is reachable multiple ways: prod > optional > dev.\n */\nexport function buildDependencyGraph(raw: RawGraph): DependencyGraph {\n const prodReach = reachable(raw.directProd, raw.nodes);\n const optionalReach = reachable(raw.directOptional, raw.nodes);\n const devReach = reachable(raw.directDev, raw.nodes);\n const direct = new Set<PkgKey>([...raw.directProd, ...raw.directOptional, ...raw.directDev]);\n\n const nodes: Record<PkgKey, DepNode> = {};\n for (const [key, rn] of Object.entries(raw.nodes)) {\n let scope: DepScope;\n if (prodReach.has(key)) scope = 'prod';\n else if (optionalReach.has(key)) scope = 'optional';\n else if (devReach.has(key)) scope = 'dev';\n else scope = 'prod'; // explicitly-listed-but-unreferenced: treat as prod\n\n nodes[key] = {\n key,\n name: rn.name,\n version: rn.version,\n scope,\n direct: direct.has(key),\n dependencies: dedupe(rn.dependencies),\n ...(rn.unscannable ? { unscannable: rn.unscannable } : {}),\n };\n }\n\n return {\n manager: raw.manager,\n lockfilePath: raw.lockfilePath,\n lockfileVersion: raw.lockfileVersion,\n root: raw.root,\n nodes,\n directKeys: [...direct].filter((k) => nodes[k] !== undefined),\n };\n}\n\nfunction dedupe(keys: PkgKey[]): PkgKey[] {\n return keys.length > 1 ? [...new Set(keys)] : keys;\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { pkgKey } from '../types.js';\nimport type { UnscannablePackage } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\n\ninterface PkgEntry {\n name?: string;\n version?: string;\n resolved?: string;\n link?: boolean;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface V1Entry {\n version?: string;\n dev?: boolean;\n optional?: boolean;\n requires?: Record<string, string>;\n dependencies?: Record<string, V1Entry>;\n}\n\n/** Parse a `package-lock.json` / `npm-shrinkwrap.json` (lockfile v1, v2 or v3). */\nexport function parseNpm(lockfilePath: string): RawGraph {\n const data = JSON.parse(readFileSync(lockfilePath, 'utf8')) as {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n packages?: Record<string, PkgEntry>;\n dependencies?: Record<string, V1Entry>;\n };\n\n if (data.packages) {\n return parsePackages(data, lockfilePath);\n }\n return parseLegacy(data, lockfilePath);\n}\n\n/** Last `node_modules/<name>` segment of an install path, scope-aware. */\nfunction nameFromPath(p: string): string {\n const marker = 'node_modules/';\n const idx = p.lastIndexOf(marker);\n return idx === -1 ? p : p.slice(idx + marker.length);\n}\n\n/** Lockfile v2/v3: a flat `packages` map keyed by install path. */\nfunction parsePackages(\n data: {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n packages?: Record<string, PkgEntry>;\n },\n lockfilePath: string,\n): RawGraph {\n const packages = data.packages ?? {};\n const rootEntry = packages[''] ?? {};\n const root = {\n name: rootEntry.name ?? data.name ?? 'project',\n version: rootEntry.version ?? data.version,\n };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n const unscannable: UnscannablePackage[] = [];\n const pathToKey: Record<string, string> = Object.create(null);\n\n // First pass: create a node per installed package and map its path → key.\n for (const [p, entry] of Object.entries(packages)) {\n if (p === '' || entry.link) continue;\n const name = entry.name ?? nameFromPath(p);\n const version = entry.version;\n if (!version) continue;\n const key = pkgKey(name, version);\n pathToKey[p] = key;\n if (!nodes[key]) {\n const node: RawNode = { key, name, version, dependencies: [] };\n // A package living outside node_modules is a local workspace package —\n // it is your own code, not something to look up in OSV.\n if (!p.includes('node_modules')) {\n node.unscannable = { reason: 'local workspace package' };\n unscannable.push({ name, version, reason: 'local workspace package' });\n }\n nodes[key] = node;\n }\n }\n\n // Resolve a dependency name from a package path using node_modules hoisting:\n // check the nearest node_modules first, then walk up toward the root.\n const resolveDep = (fromPath: string, depName: string): string | undefined => {\n let prefix = fromPath;\n for (;;) {\n const candidate = `${prefix ? `${prefix}/` : ''}node_modules/${depName}`;\n const entry = packages[candidate];\n if (entry) {\n if (entry.link && typeof entry.resolved === 'string') return entry.resolved;\n return candidate;\n }\n if (!prefix) return undefined;\n const i = prefix.lastIndexOf('/node_modules/');\n prefix = i === -1 ? '' : prefix.slice(0, i);\n }\n };\n\n const directProd = new Set<string>();\n const directDev = new Set<string>();\n const directOptional = new Set<string>();\n\n // Second pass: build edges. Only the root/workspace packages contribute\n // direct deps and dev edges; transitive packages contribute prod/optional only.\n for (const [p, entry] of Object.entries(packages)) {\n if (entry.link) continue;\n const fromKey = p === '' ? undefined : pathToKey[p];\n const isLocalRoot = p === '' || !p.includes('node_modules');\n\n const addEdges = (names: string[], bucket?: Set<string>): void => {\n for (const depName of names) {\n const targetPath = resolveDep(p, depName);\n if (!targetPath) continue; // unmet optional / not installed on this platform\n const targetKey = pathToKey[targetPath];\n if (!targetKey) continue;\n if (fromKey && fromKey !== targetKey) nodes[fromKey]!.dependencies.push(targetKey);\n if (bucket) bucket.add(targetKey);\n }\n };\n\n addEdges(Object.keys(entry.dependencies ?? {}), isLocalRoot ? directProd : undefined);\n addEdges(\n Object.keys(entry.optionalDependencies ?? {}),\n isLocalRoot ? directOptional : undefined,\n );\n if (isLocalRoot) {\n addEdges(Object.keys(entry.devDependencies ?? {}), directDev);\n }\n }\n\n return {\n manager: 'npm',\n lockfilePath,\n lockfileVersion: data.lockfileVersion,\n root,\n nodes,\n directProd: [...directProd],\n directDev: [...directDev],\n directOptional: [...directOptional],\n unscannable,\n };\n}\n\n/** Lockfile v1: a nested `dependencies` tree. Direct deps come from package.json. */\nfunction parseLegacy(\n data: {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n dependencies?: Record<string, V1Entry>;\n },\n lockfilePath: string,\n): RawGraph {\n const manifest = readRootManifest(dirname(lockfilePath));\n const root = { name: data.name ?? manifest.name, version: data.version ?? manifest.version };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n\n const buildLevel = (deps?: Record<string, V1Entry>): Map<string, string> => {\n const m = new Map<string, string>();\n for (const [name, info] of Object.entries(deps ?? {})) {\n if (info?.version) m.set(name, info.version);\n }\n return m;\n };\n\n // Resolve a required name against the visibility chain, nearest level first.\n const resolveFromChain = (name: string, chain: Map<string, string>[]): string | undefined => {\n for (let i = chain.length - 1; i >= 0; i--) {\n const v = chain[i]!.get(name);\n if (v) return v;\n }\n return undefined;\n };\n\n const visit = (\n deps: Record<string, V1Entry> | undefined,\n ancestors: Map<string, string>[],\n ): void => {\n const level = buildLevel(deps);\n const chain = [...ancestors, level];\n for (const [name, info] of Object.entries(deps ?? {})) {\n const version = info?.version;\n if (!version) continue;\n const key = pkgKey(name, version);\n if (!nodes[key]) nodes[key] = { key, name, version, dependencies: [] };\n\n const ownChain = [...chain, buildLevel(info.dependencies)];\n for (const reqName of Object.keys(info.requires ?? {})) {\n const v = resolveFromChain(reqName, ownChain);\n if (v) {\n const targetKey = pkgKey(reqName, v);\n if (targetKey !== key) nodes[key]!.dependencies.push(targetKey);\n }\n }\n if (info.dependencies) visit(info.dependencies, chain);\n }\n };\n visit(data.dependencies, []);\n\n // Direct deps: declared in package.json, resolved to top-level installed versions.\n const topLevel = buildLevel(data.dependencies);\n const directProd: string[] = [];\n const directDev: string[] = [];\n const directOptional: string[] = [];\n const classify = (names: string[], out: string[]): void => {\n for (const name of names) {\n const v = topLevel.get(name);\n if (v) out.push(pkgKey(name, v));\n }\n };\n classify(Object.keys(manifest.dependencies), directProd);\n classify(Object.keys(manifest.optionalDependencies), directOptional);\n classify(Object.keys(manifest.devDependencies), directDev);\n\n return {\n manager: 'npm',\n lockfilePath,\n lockfileVersion: data.lockfileVersion,\n root,\n nodes,\n directProd,\n directDev,\n directOptional,\n unscannable: [],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { createRequire } from 'node:module';\nimport yaml from 'js-yaml';\nimport { pkgKey } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\nimport type { RootManifest } from './detect.js';\n\n// @yarnpkg/lockfile is CommonJS with no ESM default; load it via require so the\n// interop is identical under vitest (vite) and the built Node ESM bundle.\nconst require = createRequire(import.meta.url);\nconst yarnLockfile = require('@yarnpkg/lockfile') as {\n parse(content: string): { type: string; object: Record<string, YarnEntry> };\n};\n\ninterface YarnEntry {\n version?: string;\n resolution?: string;\n dependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n}\n\n/** Parse a `yarn.lock` (classic v1 or berry v2+). */\nexport function parseYarn(lockfilePath: string): RawGraph {\n const content = readFileSync(lockfilePath, 'utf8');\n const manifest = readRootManifest(dirname(lockfilePath));\n const isBerry = content.includes('__metadata');\n const { descriptorToVersion, entryByVersion, lockfileVersion } = isBerry\n ? parseBerry(content)\n : parseClassic(content);\n return assemble(\n lockfilePath,\n manifest,\n descriptorToVersion,\n entryByVersion,\n lockfileVersion,\n isBerry,\n );\n}\n\n/** Split a \"name@range\" descriptor, scope-aware. */\nfunction splitDescriptor(descriptor: string): { name: string; range: string } | undefined {\n const at = descriptor.lastIndexOf('@');\n if (at <= 0) return undefined;\n return { name: descriptor.slice(0, at), range: descriptor.slice(at + 1) };\n}\n\ninterface ParsedLock {\n /** \"name@range\" → resolved version. */\n descriptorToVersion: Map<string, string>;\n /** \"name@version\" → its dependency ranges. */\n entryByVersion: Map<string, YarnEntry>;\n lockfileVersion: string | number;\n}\n\nfunction parseClassic(content: string): ParsedLock {\n const parsed = yarnLockfile.parse(content) as { object: Record<string, YarnEntry> };\n const descriptorToVersion = new Map<string, string>();\n const entryByVersion = new Map<string, YarnEntry>();\n for (const [rawKey, entry] of Object.entries(parsed.object)) {\n if (!entry.version) continue;\n // A key may list several descriptors joined by \", \".\n for (const descriptor of rawKey.split(/,\\s*/)) {\n const split = splitDescriptor(descriptor);\n if (split) descriptorToVersion.set(`${split.name}@${split.range}`, entry.version);\n if (split) entryByVersion.set(pkgKey(split.name, entry.version), entry);\n }\n }\n return { descriptorToVersion, entryByVersion, lockfileVersion: 1 };\n}\n\nfunction parseBerry(content: string): ParsedLock {\n const doc = (yaml.load(content) as Record<string, YarnEntry & { version?: string }>) ?? {};\n const descriptorToVersion = new Map<string, string>();\n const entryByVersion = new Map<string, YarnEntry>();\n let lockfileVersion: string | number = 'berry';\n for (const [rawKey, entry] of Object.entries(doc)) {\n if (rawKey === '__metadata') {\n const v = (entry as { version?: string | number }).version;\n if (v !== undefined) lockfileVersion = v;\n continue;\n }\n if (!entry.version) continue;\n for (const descriptor of rawKey.split(/,\\s*/)) {\n const split = splitDescriptor(descriptor);\n if (!split) continue;\n descriptorToVersion.set(`${split.name}@${split.range}`, entry.version);\n entryByVersion.set(pkgKey(split.name, entry.version), entry);\n }\n }\n return { descriptorToVersion, entryByVersion, lockfileVersion };\n}\n\nfunction assemble(\n lockfilePath: string,\n manifest: RootManifest,\n descriptorToVersion: Map<string, string>,\n entryByVersion: Map<string, YarnEntry>,\n lockfileVersion: string | number,\n isBerry: boolean,\n): RawGraph {\n // Resolve a (name, range) request to an installed version, tolerating berry's\n // protocol prefixes (e.g. \"npm:^1.0.0\") that the manifest omits.\n const resolve = (name: string, range: string): string | undefined => {\n const candidates = isBerry\n ? [`${name}@${range}`, `${name}@npm:${range}`]\n : [`${name}@${range}`];\n for (const c of candidates) {\n const v = descriptorToVersion.get(c);\n if (v) return v;\n }\n return undefined;\n };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n for (const [key, entry] of entryByVersion) {\n // `key` is already a `name@version` PkgKey; recover both halves.\n const at = key.lastIndexOf('@');\n const name = key.slice(0, at);\n const version = key.slice(at + 1);\n if (!nodes[key]) nodes[key] = { key, name, version, dependencies: [] };\n const addEdges = (deps?: Record<string, string>): void => {\n for (const [depName, depRange] of Object.entries(deps ?? {})) {\n const v = resolve(depName, depRange);\n if (!v) continue;\n const targetKey = pkgKey(depName, v);\n if (targetKey !== key) nodes[key]!.dependencies.push(targetKey);\n }\n };\n addEdges(entry.dependencies);\n addEdges(entry.optionalDependencies);\n }\n\n const toDirect = (deps: Record<string, string>): string[] => {\n const out: string[] = [];\n for (const [name, range] of Object.entries(deps)) {\n const v = resolve(name, range);\n if (v) out.push(pkgKey(name, v));\n }\n return out;\n };\n\n return {\n manager: 'yarn',\n lockfilePath,\n lockfileVersion,\n root: { name: manifest.name, version: manifest.version },\n nodes,\n directProd: toDirect(manifest.dependencies),\n directDev: toDirect(manifest.devDependencies),\n directOptional: toDirect(manifest.optionalDependencies),\n unscannable: [],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport yaml from 'js-yaml';\nimport { pkgKey } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\n\ninterface PnpmEntry {\n dependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n}\n\ninterface ImporterDeps {\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n}\n\ninterface PnpmLock {\n lockfileVersion?: string | number;\n importers?: Record<string, ImporterDeps>;\n packages?: Record<string, PnpmEntry>;\n snapshots?: Record<string, PnpmEntry>;\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n}\n\n/** Parse a `pnpm-lock.yaml` (lockfile v5, v6 or v9). */\nexport function parsePnpm(lockfilePath: string): RawGraph {\n const doc = (yaml.load(readFileSync(lockfilePath, 'utf8')) as PnpmLock) ?? {};\n const manifest = readRootManifest(dirname(lockfilePath));\n const major = majorVersion(doc.lockfileVersion);\n\n const nodes: Record<string, RawNode> = Object.create(null);\n\n // Nodes come from the `packages` map (one entry per installed package).\n for (const key of Object.keys(doc.packages ?? {})) {\n const parsed = parseKey(key, major);\n if (!parsed) continue;\n const nodeKey = pkgKey(parsed.name, parsed.version);\n if (!nodes[nodeKey]) {\n nodes[nodeKey] = {\n key: nodeKey,\n name: parsed.name,\n version: parsed.version,\n dependencies: [],\n };\n }\n }\n\n // Edges: from `snapshots` in v9, else from `packages` directly.\n const edgeSource = major >= 9 ? (doc.snapshots ?? {}) : (doc.packages ?? {});\n for (const [key, entry] of Object.entries(edgeSource)) {\n const parsed = parseKey(key, major);\n if (!parsed) continue;\n const fromKey = pkgKey(parsed.name, parsed.version);\n if (!nodes[fromKey]) {\n nodes[fromKey] = {\n key: fromKey,\n name: parsed.name,\n version: parsed.version,\n dependencies: [],\n };\n }\n const addEdges = (deps?: Record<string, string>): void => {\n for (const [depName, depValue] of Object.entries(deps ?? {})) {\n const targetKey = pkgKey(depName, stripVersion(depValue, major));\n if (targetKey !== fromKey && nodes[targetKey]) nodes[fromKey]!.dependencies.push(targetKey);\n }\n };\n addEdges(entry.dependencies);\n addEdges(entry.optionalDependencies);\n }\n\n // Roots: from `importers` (workspaces + modern single project) or the\n // top-level dependency maps (older single-project lockfiles).\n const importers: Record<string, ImporterDeps> = doc.importers ?? {\n '.': {\n dependencies: doc.dependencies,\n devDependencies: doc.devDependencies,\n optionalDependencies: doc.optionalDependencies,\n },\n };\n\n const directProd = new Set<string>();\n const directDev = new Set<string>();\n const directOptional = new Set<string>();\n const collect = (deps: Record<string, unknown> | undefined, into: Set<string>): void => {\n for (const [name, val] of Object.entries(deps ?? {})) {\n const version = importerVersion(val, major);\n if (!version) continue;\n const key = pkgKey(name, version);\n if (nodes[key]) into.add(key);\n }\n };\n for (const imp of Object.values(importers)) {\n collect(imp.dependencies, directProd);\n collect(imp.optionalDependencies, directOptional);\n collect(imp.devDependencies, directDev);\n }\n\n return {\n manager: 'pnpm',\n lockfilePath,\n lockfileVersion: doc.lockfileVersion,\n root: { name: manifest.name, version: manifest.version },\n nodes,\n directProd: [...directProd],\n directDev: [...directDev],\n directOptional: [...directOptional],\n unscannable: [],\n };\n}\n\nfunction majorVersion(v: string | number | undefined): number {\n const n = parseFloat(String(v ?? '9'));\n return Number.isNaN(n) ? 9 : Math.floor(n);\n}\n\n/** Parse a pnpm package key into `{ name, version }`, format-aware. */\nfunction parseKey(key: string, major: number): { name: string; version: string } | undefined {\n const k = key.startsWith('/') ? key.slice(1) : key;\n if (major < 6) {\n // `name/version[_peers]`\n const lastSlash = k.lastIndexOf('/');\n if (lastSlash <= 0) return undefined;\n const name = k.slice(0, lastSlash);\n const version = stripVersion(k.slice(lastSlash + 1), major);\n return version ? { name, version } : undefined;\n }\n // `name@version[(peers)]`\n const at = k.lastIndexOf('@');\n if (at <= 0) return undefined;\n const name = k.slice(0, at);\n const version = stripVersion(k.slice(at + 1), major);\n return version ? { name, version } : undefined;\n}\n\n/** Strip pnpm's peer-dependency suffix from a version ref. */\nfunction stripVersion(value: string, major: number): string {\n let v = value;\n if (major < 6) {\n const us = v.indexOf('_');\n if (us !== -1) v = v.slice(0, us);\n }\n const paren = v.indexOf('(');\n if (paren !== -1) v = v.slice(0, paren);\n return v;\n}\n\n/** Extract the installed version from an importer dependency entry. */\nfunction importerVersion(val: unknown, major: number): string | undefined {\n let ref: string | undefined;\n if (typeof val === 'string') ref = val;\n else if (\n val &&\n typeof val === 'object' &&\n typeof (val as { version?: unknown }).version === 'string'\n ) {\n ref = (val as { version: string }).version;\n }\n if (!ref) return undefined;\n if (ref.startsWith('link:') || ref.startsWith('file:') || ref.startsWith('workspace:'))\n return undefined;\n return stripVersion(ref, major);\n}\n","import type { DependencyGraph, PkgKey } from '../types.js';\n\n/** Label for the project root used as the first element of a dependency path. */\nexport function rootLabel(graph: DependencyGraph): string {\n return graph.root.version ? `${graph.root.name}@${graph.root.version}` : graph.root.name;\n}\n\n/**\n * Shortest dependency path from the project root to `targetKey`, answering\n * \"why is this package in my tree?\". Returns `[root, …, target]` or `null` if\n * the target is not reachable. Uses BFS from a virtual root connected to the\n * project's direct dependencies.\n */\nexport function shortestPath(graph: DependencyGraph, targetKey: PkgKey): PkgKey[] | null {\n if (!graph.nodes[targetKey]) return null;\n\n const VIRTUAL_ROOT = '\u0000root';\n const prev = new Map<PkgKey, PkgKey>();\n const visited = new Set<PkgKey>([VIRTUAL_ROOT]);\n const queue: PkgKey[] = [VIRTUAL_ROOT];\n\n for (let i = 0; i < queue.length; i++) {\n const current = queue[i]!;\n const neighbors =\n current === VIRTUAL_ROOT ? graph.directKeys : (graph.nodes[current]?.dependencies ?? []);\n for (const next of neighbors) {\n if (visited.has(next)) continue;\n visited.add(next);\n prev.set(next, current);\n if (next === targetKey) return reconstruct(graph, prev, targetKey, VIRTUAL_ROOT);\n queue.push(next);\n }\n }\n // Listed-but-unreferenced (e.g. a direct dep with no edges recorded).\n return [rootLabel(graph), targetKey];\n}\n\nfunction reconstruct(\n graph: DependencyGraph,\n prev: Map<PkgKey, PkgKey>,\n target: PkgKey,\n virtualRoot: string,\n): PkgKey[] {\n const path: PkgKey[] = [];\n let cursor: PkgKey | undefined = target;\n while (cursor !== undefined && cursor !== virtualRoot) {\n path.unshift(cursor);\n cursor = prev.get(cursor);\n }\n path.unshift(rootLabel(graph));\n return path;\n}\n","import semver from 'semver';\nimport type { OsvAffected, OsvEvent, OsvVulnerability } from '../types.js';\n\n/**\n * Whether `version` is affected by a single OSV `affected` entry — the heart of\n * accuracy. We honor enumerated `versions[]` exactly and walk `ranges[].events`\n * with the canonical OSV sweep. We never coerce a non-semver installed version\n * into a range match (that would manufacture false positives); such versions\n * only match via the explicit `versions[]` list.\n */\nexport function isVersionAffected(version: string, affected: OsvAffected): boolean {\n if (affected.versions?.includes(version)) return true;\n\n const installed = semver.parse(version, { loose: true });\n if (!installed) return false; // non-semver: only the enumerated list (checked above) can match\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') continue; // not applicable to npm\n if (rangeAffects(installed, range.events)) return true;\n }\n return false;\n}\n\ntype Boundary = { kind: 'introduced' | 'fixed' | 'last_affected'; version: semver.SemVer | null };\n\n/**\n * OSV event sweep: sort the introduced/fixed/last_affected boundaries ascending\n * and replay them. `introduced` opens the affected interval (`\"0\"` = from the\n * beginning), `fixed` closes it exclusively, `last_affected` closes it inclusively.\n */\nfunction rangeAffects(installed: semver.SemVer, events: OsvEvent[]): boolean {\n const boundaries: Boundary[] = [];\n for (const event of events) {\n if (event.introduced !== undefined) {\n boundaries.push({\n kind: 'introduced',\n version: event.introduced === '0' ? null : parse(event.introduced),\n });\n } else if (event.fixed !== undefined) {\n boundaries.push({ kind: 'fixed', version: parse(event.fixed) });\n } else if (event.last_affected !== undefined) {\n boundaries.push({ kind: 'last_affected', version: parse(event.last_affected) });\n }\n // `limit` events are not affected-state boundaries; ignore.\n }\n\n boundaries.sort((a, b) => {\n if (a.version === null) return b.version === null ? 0 : -1; // introduced:0 sorts first (-inf)\n if (b.version === null) return 1;\n return a.version.compare(b.version);\n });\n\n let affected = false;\n for (const boundary of boundaries) {\n if (boundary.version === null) {\n affected = true; // introduced from the beginning\n continue;\n }\n const cmp = installed.compare(boundary.version);\n switch (boundary.kind) {\n case 'introduced':\n if (cmp >= 0) affected = true;\n break;\n case 'fixed':\n if (cmp >= 0) affected = false; // fixed is exclusive\n break;\n case 'last_affected':\n if (cmp > 0) affected = false; // last_affected is inclusive\n break;\n }\n }\n return affected;\n}\n\nfunction parse(version: string): semver.SemVer | null {\n return semver.parse(version, { loose: true }) ?? semver.coerce(version);\n}\n\nexport interface VulnMatch {\n affected: boolean;\n /** Distinct `fixed` versions across the matching affected entries. */\n fixedVersions: string[];\n}\n\n/**\n * Whether a whole OSV record affects `name@version` for the npm ecosystem, and\n * which fixed versions it advertises. Withdrawn advisories never match.\n */\nexport function vulnerabilityAffects(\n name: string,\n version: string,\n vuln: OsvVulnerability,\n): VulnMatch {\n if (vuln.withdrawn) return { affected: false, fixedVersions: [] };\n\n let affected = false;\n const fixed = new Set<string>();\n for (const entry of vuln.affected ?? []) {\n const ecosystem = entry.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (entry.package?.name && entry.package.name !== name) continue;\n if (!isVersionAffected(version, entry)) continue;\n affected = true;\n for (const range of entry.ranges ?? []) {\n for (const event of range.events) {\n if (event.fixed) fixed.add(event.fixed);\n }\n }\n }\n return { affected, fixedVersions: [...fixed] };\n}\n\n/**\n * The lowest advertised fixed version strictly greater than `installed`\n * (the nearest safe upgrade), or `undefined` if none is known.\n */\nexport function nearestFix(installed: string, fixedVersions: string[]): string | undefined {\n const current = semver.parse(installed, { loose: true });\n const candidates = fixedVersions\n .map((v) => semver.parse(v, { loose: true }) ?? semver.coerce(v))\n .filter((v): v is semver.SemVer => v !== null)\n .filter((v) => (current ? v.compare(current) > 0 : true))\n .sort((a, b) => a.compare(b));\n return candidates[0]?.version;\n}\n","import type { OsvAffected, OsvReference, OsvSeverity, OsvVulnerability } from '../types.js';\n\n/** All identifiers a record is known by (its id plus aliases). */\nfunction tokensOf(vuln: OsvVulnerability): string[] {\n return [vuln.id, ...(vuln.aliases ?? [])];\n}\n\n/** Pick the human-facing id: prefer CVE, then GHSA, then the raw OSV id. */\nexport function canonicalId(ids: Iterable<string>): string {\n const list = [...ids];\n return (\n list.find((id) => id.startsWith('CVE-')) ??\n list.find((id) => id.startsWith('GHSA-')) ??\n list[0]!\n );\n}\n\n/**\n * Collapse advisories that describe the same vulnerability. Records are grouped\n * by the connected components of their shared ids/aliases (a CVE surfaced under\n * both a GHSA and an OSV id becomes one finding), then each group is merged into\n * a single representative carrying the union of aliases, references and severity.\n */\nexport function dedupeVulnerabilities(vulns: OsvVulnerability[]): OsvVulnerability[] {\n if (vulns.length <= 1) return vulns;\n\n const parent = new Map<string, string>();\n const find = (x: string): string => {\n let root = x;\n while (parent.get(root) !== undefined && parent.get(root) !== root) root = parent.get(root)!;\n parent.set(x, root);\n return root;\n };\n const union = (a: string, b: string): void => {\n parent.set(find(a), find(b));\n };\n\n for (const vuln of vulns) {\n const tokens = tokensOf(vuln);\n if (!parent.has(tokens[0]!)) parent.set(tokens[0]!, tokens[0]!);\n for (const token of tokens.slice(1)) {\n if (!parent.has(token)) parent.set(token, token);\n union(tokens[0]!, token);\n }\n }\n\n const groups = new Map<string, OsvVulnerability[]>();\n for (const vuln of vulns) {\n const root = find(vuln.id);\n const group = groups.get(root);\n if (group) group.push(vuln);\n else groups.set(root, [vuln]);\n }\n\n return [...groups.values()].map(mergeGroup);\n}\n\nfunction mergeGroup(group: OsvVulnerability[]): OsvVulnerability {\n if (group.length === 1) return group[0]!;\n\n const allIds = new Set<string>();\n const references = new Map<string, OsvReference>();\n const severity: OsvSeverity[] = [];\n const affected: OsvAffected[] = [];\n let summary: string | undefined;\n let details: string | undefined;\n let database_specific: Record<string, unknown> | undefined;\n\n for (const vuln of group) {\n for (const token of tokensOf(vuln)) allIds.add(token);\n for (const ref of vuln.references ?? []) references.set(ref.url, ref);\n for (const sev of vuln.severity ?? []) severity.push(sev);\n for (const aff of vuln.affected ?? []) affected.push(aff);\n summary ??= vuln.summary;\n details ??= vuln.details;\n database_specific ??= vuln.database_specific;\n }\n\n const id = canonicalId(allIds);\n return {\n id,\n aliases: [...allIds].filter((token) => token !== id),\n summary,\n details,\n references: [...references.values()],\n severity,\n affected,\n database_specific,\n };\n}\n","import semver from 'semver';\nimport type { DependencyGraph, Finding, OsvVulnerability, PackageManager } from '../types.js';\nimport { shortestPath } from '../graph/paths.js';\nimport { dedupeVulnerabilities } from './dedupe.js';\nimport { nearestFix, vulnerabilityAffects } from './ranges.js';\nimport { resolveSeverity } from '../score/cvss.js';\n\nexport interface FindingsOptions {\n /** Skip dev-only dependencies. */\n prodOnly?: boolean;\n /** Advisory ids/aliases to suppress. */\n ignore?: Set<string>;\n}\n\n/**\n * Turn a dependency graph plus a per-package advisory lookup into findings.\n *\n * `candidatesFor(name)` returns advisories that *name* the package; this\n * function performs the authoritative version match, de-duplicates aliased\n * advisories, scores severity and traces the dependency path. Keeping the\n * version match here (rather than trusting the source) means offline and online\n * sources share one accuracy-critical code path.\n */\nexport function buildFindings(\n graph: DependencyGraph,\n candidatesFor: (name: string) => OsvVulnerability[],\n options: FindingsOptions = {},\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable) continue;\n if (options.prodOnly && node.scope === 'dev') continue;\n\n const candidates = candidatesFor(node.name);\n if (candidates.length === 0) continue;\n\n const matched = candidates.filter(\n (vuln) => vulnerabilityAffects(node.name, node.version, vuln).affected,\n );\n if (matched.length === 0) continue;\n\n const path = shortestPath(graph, node.key);\n for (const vuln of dedupeVulnerabilities(matched)) {\n if (isIgnored(vuln, options.ignore)) continue;\n\n const { fixedVersions } = vulnerabilityAffects(node.name, node.version, vuln);\n const sortedFixes = sortVersions(fixedVersions);\n const nearest = nearestFix(node.version, fixedVersions);\n\n findings.push({\n id: vuln.id,\n aliases: vuln.aliases ?? [],\n packageName: node.name,\n version: node.version,\n scope: node.scope,\n direct: node.direct,\n severity: resolveSeverity(vuln),\n summary: vuln.summary ?? vuln.id,\n details: vuln.details,\n references: (vuln.references ?? []).map((ref) => ref.url),\n fixedVersions: sortedFixes,\n recommendation: buildRecommendation(node.name, node.direct, nearest, graph.manager),\n dependencyPaths: path ? [path] : [],\n source: 'osv',\n });\n }\n }\n\n return findings;\n}\n\nfunction isIgnored(vuln: OsvVulnerability, ignore?: Set<string>): boolean {\n if (!ignore || ignore.size === 0) return false;\n if (ignore.has(vuln.id)) return true;\n return (vuln.aliases ?? []).some((alias) => ignore.has(alias));\n}\n\nfunction sortVersions(versions: string[]): string[] {\n return [...new Set(versions)].sort((a, b) => {\n const pa = semver.parse(a, { loose: true });\n const pb = semver.parse(b, { loose: true });\n if (pa && pb) return pa.compare(pb);\n return a.localeCompare(b);\n });\n}\n\nconst INSTALL_COMMAND: Record<PackageManager, string> = {\n npm: 'npm install',\n yarn: 'yarn add',\n pnpm: 'pnpm add',\n};\n\nfunction buildRecommendation(\n name: string,\n direct: boolean,\n nearest: string | undefined,\n manager: PackageManager,\n): string {\n if (!nearest) {\n return direct\n ? 'No fixed version is available yet. Watch the advisory, or evaluate an alternative package.'\n : 'No fixed version is available yet. Pressure the parent dependency to update, or override the version.';\n }\n if (direct) {\n return `Upgrade to ${name}@${nearest} or later (e.g. \\`${INSTALL_COMMAND[manager]} ${name}@${nearest}\\`).`;\n }\n return `Update the dependency that pulls in ${name} so it resolves to ${name}@${nearest} or later. If it cannot, force the resolution via an override.`;\n}\n","// Auto-generated from FIRST.org cvss-v4-calculator (BSD-2-Clause licensed).\n// Source: https://github.com/FIRSTdotorg/cvss-v4-calculator\n// Do not edit by hand. 270 macrovector entries.\n\nexport const CVSS4_LOOKUP: Record<string, number> = {\n '100000': 9.8,\n '100001': 9.5,\n '100010': 9.4,\n '100011': 8.7,\n '100020': 9.1,\n '100021': 8.1,\n '100100': 9.4,\n '100101': 8.9,\n '100110': 8.6,\n '100111': 7.4,\n '100120': 7.7,\n '100121': 6.4,\n '100200': 8.7,\n '100201': 7.5,\n '100210': 7.4,\n '100211': 6.3,\n '100220': 6.3,\n '100221': 4.9,\n '101000': 9.4,\n '101001': 8.9,\n '101010': 8.8,\n '101011': 7.7,\n '101020': 7.6,\n '101021': 6.7,\n '101100': 8.6,\n '101101': 7.6,\n '101110': 7.4,\n '101111': 5.8,\n '101120': 5.9,\n '101121': 5,\n '101200': 7.2,\n '101201': 5.7,\n '101210': 5.7,\n '101211': 5.2,\n '101220': 5.2,\n '101221': 2.5,\n '102001': 8.3,\n '102011': 7,\n '102021': 5.4,\n '102101': 6.5,\n '102111': 5.8,\n '102121': 2.6,\n '102201': 5.3,\n '102211': 2.1,\n '102221': 1.3,\n '110000': 9.5,\n '110001': 9,\n '110010': 8.8,\n '110011': 7.6,\n '110020': 7.6,\n '110021': 7,\n '110100': 9,\n '110101': 7.7,\n '110110': 7.5,\n '110111': 6.2,\n '110120': 6.1,\n '110121': 5.3,\n '110200': 7.7,\n '110201': 6.6,\n '110210': 6.8,\n '110211': 5.9,\n '110220': 5.2,\n '110221': 3,\n '111000': 8.9,\n '111001': 7.8,\n '111010': 7.6,\n '111011': 6.7,\n '111020': 6.2,\n '111021': 5.8,\n '111100': 7.4,\n '111101': 5.9,\n '111110': 5.7,\n '111111': 5.7,\n '111120': 4.7,\n '111121': 2.3,\n '111200': 6.1,\n '111201': 5.2,\n '111210': 5.7,\n '111211': 2.9,\n '111220': 2.4,\n '111221': 1.6,\n '112001': 7.1,\n '112011': 5.9,\n '112021': 3,\n '112101': 5.8,\n '112111': 2.6,\n '112121': 1.5,\n '112201': 2.3,\n '112211': 1.3,\n '112221': 0.6,\n '200000': 9.3,\n '200001': 8.7,\n '200010': 8.6,\n '200011': 7.2,\n '200020': 7.5,\n '200021': 5.8,\n '200100': 8.6,\n '200101': 7.4,\n '200110': 7.4,\n '200111': 6.1,\n '200120': 5.6,\n '200121': 3.4,\n '200200': 7,\n '200201': 5.4,\n '200210': 5.2,\n '200211': 4,\n '200220': 4,\n '200221': 2.2,\n '201000': 8.5,\n '201001': 7.5,\n '201010': 7.4,\n '201011': 5.5,\n '201020': 6.2,\n '201021': 5.1,\n '201100': 7.2,\n '201101': 5.7,\n '201110': 5.5,\n '201111': 4.1,\n '201120': 4.6,\n '201121': 1.9,\n '201200': 5.3,\n '201201': 3.6,\n '201210': 3.4,\n '201211': 1.9,\n '201220': 1.9,\n '201221': 0.8,\n '202001': 6.4,\n '202011': 5.1,\n '202021': 2,\n '202101': 4.7,\n '202111': 2.1,\n '202121': 1.1,\n '202201': 2.4,\n '202211': 0.9,\n '202221': 0.4,\n '210000': 8.8,\n '210001': 7.5,\n '210010': 7.3,\n '210011': 5.3,\n '210020': 6,\n '210021': 5,\n '210100': 7.3,\n '210101': 5.5,\n '210110': 5.9,\n '210111': 4,\n '210120': 4.1,\n '210121': 2,\n '210200': 5.4,\n '210201': 4.3,\n '210210': 4.5,\n '210211': 2.2,\n '210220': 2,\n '210221': 1.1,\n '211000': 7.5,\n '211001': 5.5,\n '211010': 5.8,\n '211011': 4.5,\n '211020': 4,\n '211021': 2.1,\n '211100': 6.1,\n '211101': 5.1,\n '211110': 4.8,\n '211111': 1.8,\n '211120': 2,\n '211121': 0.9,\n '211200': 4.6,\n '211201': 1.8,\n '211210': 1.7,\n '211211': 0.7,\n '211220': 0.8,\n '211221': 0.2,\n '212001': 5.3,\n '212011': 2.4,\n '212021': 1.4,\n '212101': 2.4,\n '212111': 1.2,\n '212121': 0.5,\n '212201': 1,\n '212211': 0.3,\n '212221': 0.1,\n '000000': 10,\n '000001': 9.9,\n '000010': 9.8,\n '000011': 9.5,\n '000020': 9.5,\n '000021': 9.2,\n '000100': 10,\n '000101': 9.6,\n '000110': 9.3,\n '000111': 8.7,\n '000120': 9.1,\n '000121': 8.1,\n '000200': 9.3,\n '000201': 9,\n '000210': 8.9,\n '000211': 8,\n '000220': 8.1,\n '000221': 6.8,\n '001000': 9.8,\n '001001': 9.5,\n '001010': 9.5,\n '001011': 9.2,\n '001020': 9,\n '001021': 8.4,\n '001100': 9.3,\n '001101': 9.2,\n '001110': 8.9,\n '001111': 8.1,\n '001120': 8.1,\n '001121': 6.5,\n '001200': 8.8,\n '001201': 8,\n '001210': 7.8,\n '001211': 7,\n '001220': 6.9,\n '001221': 4.8,\n '002001': 9.2,\n '002011': 8.2,\n '002021': 7.2,\n '002101': 7.9,\n '002111': 6.9,\n '002121': 5,\n '002201': 6.9,\n '002211': 5.5,\n '002221': 2.7,\n '010000': 9.9,\n '010001': 9.7,\n '010010': 9.5,\n '010011': 9.2,\n '010020': 9.2,\n '010021': 8.5,\n '010100': 9.5,\n '010101': 9.1,\n '010110': 9,\n '010111': 8.3,\n '010120': 8.4,\n '010121': 7.1,\n '010200': 9.2,\n '010201': 8.1,\n '010210': 8.2,\n '010211': 7.1,\n '010220': 7.2,\n '010221': 5.3,\n '011000': 9.5,\n '011001': 9.3,\n '011010': 9.2,\n '011011': 8.5,\n '011020': 8.5,\n '011021': 7.3,\n '011100': 9.2,\n '011101': 8.2,\n '011110': 8,\n '011111': 7.2,\n '011120': 7,\n '011121': 5.9,\n '011200': 8.4,\n '011201': 7,\n '011210': 7.1,\n '011211': 5.2,\n '011220': 5,\n '011221': 3,\n '012001': 8.6,\n '012011': 7.5,\n '012021': 5.2,\n '012101': 7.1,\n '012111': 5.2,\n '012121': 2.9,\n '012201': 6.3,\n '012211': 2.9,\n '012221': 1.7,\n};\n\nexport const CVSS4_MAX_COMPOSED: Record<string, Record<string, unknown>> = {\n eq1: {\n '0': ['AV:N/PR:N/UI:N/'],\n '1': ['AV:A/PR:N/UI:N/', 'AV:N/PR:L/UI:N/', 'AV:N/PR:N/UI:P/'],\n '2': ['AV:P/PR:N/UI:N/', 'AV:A/PR:L/UI:P/'],\n },\n eq2: {\n '0': ['AC:L/AT:N/'],\n '1': ['AC:H/AT:N/', 'AC:L/AT:P/'],\n },\n eq3: {\n '0': {\n '0': ['VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/'],\n '1': ['VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/', 'VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/'],\n },\n '1': {\n '0': ['VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/', 'VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/'],\n '1': [\n 'VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/',\n 'VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/',\n 'VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/',\n 'VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/',\n 'VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/',\n ],\n },\n '2': {\n '1': ['VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/'],\n },\n },\n eq4: {\n '0': ['SC:H/SI:S/SA:S/'],\n '1': ['SC:H/SI:H/SA:H/'],\n '2': ['SC:L/SI:L/SA:L/'],\n },\n eq5: {\n '0': ['E:A/'],\n '1': ['E:P/'],\n '2': ['E:U/'],\n },\n};\n\nexport const CVSS4_MAX_SEVERITY: Record<string, Record<string, number | Record<string, number>>> = {\n eq1: {\n '0': 1,\n '1': 4,\n '2': 5,\n },\n eq2: {\n '0': 1,\n '1': 2,\n },\n eq3eq6: {\n '0': {\n '0': 7,\n '1': 6,\n },\n '1': {\n '0': 8,\n '1': 8,\n },\n '2': {\n '1': 10,\n },\n },\n eq4: {\n '0': 6,\n '1': 5,\n '2': 4,\n },\n eq5: {\n '0': 1,\n '1': 1,\n '2': 1,\n },\n};\n","// CVSS v4.0 base-score computation, ported faithfully from the FIRST.org\n// reference calculator (BSD-2-Clause). We compute the base score (CVSS-B):\n// threat/environmental metrics are absent and therefore default to their\n// worst case (E:A, CR/IR/AR:H), exactly as the reference does.\nimport { CVSS4_LOOKUP, CVSS4_MAX_COMPOSED, CVSS4_MAX_SEVERITY } from './cvss4-data.js';\n\nconst BASE_METRICS = ['AV', 'AC', 'AT', 'PR', 'UI', 'VC', 'VI', 'VA', 'SC', 'SI', 'SA'] as const;\n\ntype Sel = Record<string, string>;\n\nconst AV_levels: Record<string, number> = { N: 0.0, A: 0.1, L: 0.2, P: 0.3 };\nconst PR_levels: Record<string, number> = { N: 0.0, L: 0.1, H: 0.2 };\nconst UI_levels: Record<string, number> = { N: 0.0, P: 0.1, A: 0.2 };\nconst AC_levels: Record<string, number> = { L: 0.0, H: 0.1 };\nconst AT_levels: Record<string, number> = { N: 0.0, P: 0.1 };\nconst VC_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst VI_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst VA_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst SC_levels: Record<string, number> = { H: 0.1, L: 0.2, N: 0.3 };\nconst SI_levels: Record<string, number> = { S: 0.0, H: 0.1, L: 0.2, N: 0.3 };\nconst SA_levels: Record<string, number> = { S: 0.0, H: 0.1, L: 0.2, N: 0.3 };\nconst CR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\nconst IR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\nconst AR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\n\n/** Compute the CVSS v4.0 base score from a vector string, or null if invalid. */\nexport function scoreV4(vector: string): number | null {\n const sel = parseV4(vector);\n if (!sel) return null;\n const macro = macroVector(sel);\n if (CVSS4_LOOKUP[macro] === undefined) return null;\n return cvssScore(sel, macro);\n}\n\nfunction parseV4(vector: string): Sel | null {\n const parts = vector.split('/');\n if (parts[0] !== 'CVSS:4.0') return null;\n const sel: Sel = {};\n for (const part of parts.slice(1)) {\n const [k, v] = part.split(':');\n if (k && v) sel[k] = v;\n }\n for (const metric of BASE_METRICS) if (!(metric in sel)) return null;\n for (const metric of ['E', 'CR', 'IR', 'AR']) if (!(metric in sel)) sel[metric] = 'X';\n return sel;\n}\n\n/** Effective metric value, applying modified-metric and worst-case-default rules. */\nfunction m(sel: Sel, metric: string): string {\n const selected = sel[metric];\n if (metric === 'E' && selected === 'X') return 'A';\n if ((metric === 'CR' || metric === 'IR' || metric === 'AR') && selected === 'X') return 'H';\n const modified = sel[`M${metric}`];\n if (modified !== undefined && modified !== 'X') return modified;\n return selected ?? '';\n}\n\nfunction macroVector(sel: Sel): string {\n const av = m(sel, 'AV');\n const pr = m(sel, 'PR');\n const ui = m(sel, 'UI');\n let eq1 = '2';\n if (av === 'N' && pr === 'N' && ui === 'N') eq1 = '0';\n else if ((av === 'N' || pr === 'N' || ui === 'N') && av !== 'P') eq1 = '1';\n\n const eq2 = m(sel, 'AC') === 'L' && m(sel, 'AT') === 'N' ? '0' : '1';\n\n const vc = m(sel, 'VC');\n const vi = m(sel, 'VI');\n const va = m(sel, 'VA');\n let eq3 = '2';\n if (vc === 'H' && vi === 'H') eq3 = '0';\n else if (vc === 'H' || vi === 'H' || va === 'H') eq3 = '1';\n\n const msi = m(sel, 'MSI');\n const msa = m(sel, 'MSA');\n let eq4 = '2';\n if (msi === 'S' || msa === 'S') eq4 = '0';\n else if (m(sel, 'SC') === 'H' || m(sel, 'SI') === 'H' || m(sel, 'SA') === 'H') eq4 = '1';\n\n const e = m(sel, 'E');\n const eq5 = e === 'A' ? '0' : e === 'P' ? '1' : '2';\n\n const cr = m(sel, 'CR');\n const ir = m(sel, 'IR');\n const ar = m(sel, 'AR');\n const eq6 =\n (cr === 'H' && vc === 'H') || (ir === 'H' && vi === 'H') || (ar === 'H' && va === 'H')\n ? '0'\n : '1';\n\n return `${eq1}${eq2}${eq3}${eq4}${eq5}${eq6}`;\n}\n\nfunction lvl(map: Record<string, number>, key: string): number {\n return map[key] ?? 0;\n}\n\nfunction eqMaxes(macro: string, eq: number): string[] {\n const group = CVSS4_MAX_COMPOSED[`eq${eq}`] as Record<string, string[]>;\n return group[macro[eq - 1]!] ?? [];\n}\n\nfunction extractValueMetric(metric: string, str: string): string {\n const start = str.indexOf(metric) + metric.length + 1;\n const rest = str.slice(start);\n const slash = rest.indexOf('/');\n return slash > 0 ? rest.substring(0, slash) : rest;\n}\n\nfunction cvssScore(sel: Sel, macro: string): number {\n if (BASE_METRICS.slice(5).every((metric) => m(sel, metric) === 'N')) return 0; // VC..SA all None\n\n let value = CVSS4_LOOKUP[macro]!;\n\n const eq1 = Number(macro[0]);\n const eq3 = Number(macro[2]);\n const eq6 = Number(macro[5]);\n\n const lower = (parts: [number, number, number, number, number, number]): number =>\n CVSS4_LOOKUP[parts.join('')] ?? NaN;\n\n const d = macro.split('').map(Number) as [number, number, number, number, number, number];\n const scoreEq1Lower = lower([d[0] + 1, d[1], d[2], d[3], d[4], d[5]]);\n const scoreEq2Lower = lower([d[0], d[1] + 1, d[2], d[3], d[4], d[5]]);\n\n let scoreEq3Eq6Lower: number;\n if (eq3 === 1 && eq6 === 1) scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n else if (eq3 === 0 && eq6 === 1)\n scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n else if (eq3 === 1 && eq6 === 0)\n scoreEq3Eq6Lower = lower([d[0], d[1], d[2], d[3], d[4], d[5] + 1]);\n else if (eq3 === 0 && eq6 === 0) {\n const left = lower([d[0], d[1], d[2], d[3], d[4], d[5] + 1]);\n const right = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n scoreEq3Eq6Lower = left > right ? left : right;\n } else scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5] + 1]);\n\n const scoreEq4Lower = lower([d[0], d[1], d[2], d[3] + 1, d[4], d[5]]);\n const scoreEq5Lower = lower([d[0], d[1], d[2], d[3], d[4] + 1, d[5]]);\n\n const eq1Maxes = eqMaxes(macro, 1);\n const eq2Maxes = eqMaxes(macro, 2);\n const eq3Eq6Maxes = (CVSS4_MAX_COMPOSED.eq3 as Record<string, Record<string, string[]>>)[\n macro[2]!\n ]![macro[5]!]!;\n const eq4Maxes = eqMaxes(macro, 4);\n const eq5Maxes = eqMaxes(macro, 5);\n\n const maxVectors: string[] = [];\n for (const a of eq1Maxes)\n for (const b of eq2Maxes)\n for (const c of eq3Eq6Maxes)\n for (const e of eq4Maxes) for (const f of eq5Maxes) maxVectors.push(a + b + c + e + f);\n\n let sdAV = 0,\n sdPR = 0,\n sdUI = 0,\n sdAC = 0,\n sdAT = 0,\n sdVC = 0,\n sdVI = 0,\n sdVA = 0,\n sdSC = 0,\n sdSI = 0,\n sdSA = 0,\n sdCR = 0,\n sdIR = 0,\n sdAR = 0;\n\n for (const maxVector of maxVectors) {\n sdAV = lvl(AV_levels, m(sel, 'AV')) - lvl(AV_levels, extractValueMetric('AV', maxVector));\n sdPR = lvl(PR_levels, m(sel, 'PR')) - lvl(PR_levels, extractValueMetric('PR', maxVector));\n sdUI = lvl(UI_levels, m(sel, 'UI')) - lvl(UI_levels, extractValueMetric('UI', maxVector));\n sdAC = lvl(AC_levels, m(sel, 'AC')) - lvl(AC_levels, extractValueMetric('AC', maxVector));\n sdAT = lvl(AT_levels, m(sel, 'AT')) - lvl(AT_levels, extractValueMetric('AT', maxVector));\n sdVC = lvl(VC_levels, m(sel, 'VC')) - lvl(VC_levels, extractValueMetric('VC', maxVector));\n sdVI = lvl(VI_levels, m(sel, 'VI')) - lvl(VI_levels, extractValueMetric('VI', maxVector));\n sdVA = lvl(VA_levels, m(sel, 'VA')) - lvl(VA_levels, extractValueMetric('VA', maxVector));\n sdSC = lvl(SC_levels, m(sel, 'SC')) - lvl(SC_levels, extractValueMetric('SC', maxVector));\n sdSI = lvl(SI_levels, m(sel, 'SI')) - lvl(SI_levels, extractValueMetric('SI', maxVector));\n sdSA = lvl(SA_levels, m(sel, 'SA')) - lvl(SA_levels, extractValueMetric('SA', maxVector));\n sdCR = lvl(CR_levels, m(sel, 'CR')) - lvl(CR_levels, extractValueMetric('CR', maxVector));\n sdIR = lvl(IR_levels, m(sel, 'IR')) - lvl(IR_levels, extractValueMetric('IR', maxVector));\n sdAR = lvl(AR_levels, m(sel, 'AR')) - lvl(AR_levels, extractValueMetric('AR', maxVector));\n\n const distances = [\n sdAV,\n sdPR,\n sdUI,\n sdAC,\n sdAT,\n sdVC,\n sdVI,\n sdVA,\n sdSC,\n sdSI,\n sdSA,\n sdCR,\n sdIR,\n sdAR,\n ];\n if (distances.some((x) => x < 0)) continue;\n break;\n }\n\n const csdEq1 = sdAV + sdPR + sdUI;\n const csdEq2 = sdAC + sdAT;\n const csdEq3Eq6 = sdVC + sdVI + sdVA + sdCR + sdIR + sdAR;\n const csdEq4 = sdSC + sdSI + sdSA;\n\n const step = 0.1;\n const availEq1 = value - scoreEq1Lower;\n const availEq2 = value - scoreEq2Lower;\n const availEq3Eq6 = value - scoreEq3Eq6Lower;\n const availEq4 = value - scoreEq4Lower;\n const availEq5 = value - scoreEq5Lower;\n\n const maxSev = CVSS4_MAX_SEVERITY;\n const maxSevEq1 = (maxSev.eq1 as Record<string, number>)[String(eq1)]! * step;\n const maxSevEq2 = (maxSev.eq2 as Record<string, number>)[macro[1]!]! * step;\n const maxSevEq3Eq6 =\n (maxSev.eq3eq6 as Record<string, Record<string, number>>)[String(eq3)]![String(eq6)]! * step;\n const maxSevEq4 = (maxSev.eq4 as Record<string, number>)[macro[3]!]! * step;\n\n let n = 0;\n let nsEq1 = 0,\n nsEq2 = 0,\n nsEq3Eq6 = 0,\n nsEq4 = 0;\n if (!Number.isNaN(availEq1)) {\n n++;\n nsEq1 = availEq1 * (csdEq1 / maxSevEq1);\n }\n if (!Number.isNaN(availEq2)) {\n n++;\n nsEq2 = availEq2 * (csdEq2 / maxSevEq2);\n }\n if (!Number.isNaN(availEq3Eq6)) {\n n++;\n nsEq3Eq6 = availEq3Eq6 * (csdEq3Eq6 / maxSevEq3Eq6);\n }\n if (!Number.isNaN(availEq4)) {\n n++;\n nsEq4 = availEq4 * (csdEq4 / maxSevEq4);\n }\n if (!Number.isNaN(availEq5)) {\n n++; // eq5 proportion is always 0\n }\n\n const meanDistance = n === 0 ? 0 : (nsEq1 + nsEq2 + nsEq3Eq6 + nsEq4) / n;\n value -= meanDistance;\n if (value < 0) value = 0;\n if (value > 10) value = 10;\n return Math.round(value * 10) / 10;\n}\n","import type { OsvVulnerability, Severity, SeverityInfo } from '../types.js';\nimport { scoreV4 } from './cvss4.js';\n\n// CVSS base-score computation from a vector string. v3.0/v3.1 are computed from\n// the public formula; v4.0 is computed via the FIRST.org reference algorithm\n// (see cvss4.ts). Both feed the same severity-band mapping.\n\nconst AV: Record<string, number> = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 };\nconst AC: Record<string, number> = { L: 0.77, H: 0.44 };\nconst UI: Record<string, number> = { N: 0.85, R: 0.62 };\nconst PR_UNCHANGED: Record<string, number> = { N: 0.85, L: 0.62, H: 0.27 };\nconst PR_CHANGED: Record<string, number> = { N: 0.85, L: 0.68, H: 0.5 };\nconst CIA: Record<string, number> = { H: 0.56, L: 0.22, N: 0 };\n\nexport interface CvssResult {\n score: number;\n level: Severity;\n /** e.g. `CVSS:3.1`. */\n version: string;\n}\n\n/** Map a numeric CVSS base score to its qualitative band. */\nexport function levelFromScore(score: number): Severity {\n if (score <= 0) return 'none';\n if (score < 4) return 'low';\n if (score < 7) return 'medium';\n if (score < 9) return 'high';\n return 'critical';\n}\n\n/** Map a qualitative label (GHSA-style) to a {@link Severity}. */\nexport function levelFromLabel(label: string): Severity {\n switch (label.trim().toUpperCase()) {\n case 'CRITICAL':\n return 'critical';\n case 'HIGH':\n return 'high';\n case 'MODERATE':\n case 'MEDIUM':\n return 'medium';\n case 'LOW':\n return 'low';\n case 'NONE':\n return 'none';\n default:\n return 'unknown';\n }\n}\n\n/** CVSS 3.1 Roundup: smallest one-decimal number ≥ input (integer-math, float-safe). */\nfunction roundUp(input: number): number {\n const scaled = Math.round(input * 100000);\n if (scaled % 10000 === 0) return scaled / 100000;\n return (Math.floor(scaled / 10000) + 1) / 10;\n}\n\n/** Compute a base score from a CVSS v3.0/v3.1/v4.0 vector string, or null if unparseable. */\nexport function scoreFromVector(vector: string): CvssResult | null {\n const parts = vector.split('/');\n const header = parts[0] ?? '';\n if (header === 'CVSS:4.0') {\n const score = scoreV4(vector);\n return score === null ? null : { score, level: levelFromScore(score), version: header };\n }\n if (!/^CVSS:3\\.[01]$/.test(header)) return null;\n\n const m: Record<string, string> = {};\n for (const part of parts.slice(1)) {\n const [k, v] = part.split(':');\n if (k && v) m[k] = v;\n }\n const av = AV[m.AV ?? ''];\n const ac = AC[m.AC ?? ''];\n const ui = UI[m.UI ?? ''];\n const scopeChanged = m.S === 'C';\n const pr = (scopeChanged ? PR_CHANGED : PR_UNCHANGED)[m.PR ?? ''];\n const c = CIA[m.C ?? ''];\n const i = CIA[m.I ?? ''];\n const a = CIA[m.A ?? ''];\n if ([av, ac, ui, pr, c, i, a].some((x) => x === undefined)) return null;\n\n const iss = 1 - (1 - c!) * (1 - i!) * (1 - a!);\n const impact = scopeChanged ? 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15) : 6.42 * iss;\n const exploitability = 8.22 * av! * ac! * pr! * ui!;\n\n let score: number;\n if (impact <= 0) score = 0;\n else if (scopeChanged) score = roundUp(Math.min(1.08 * (impact + exploitability), 10));\n else score = roundUp(Math.min(impact + exploitability, 10));\n\n return { score, level: levelFromScore(score), version: header };\n}\n\n/**\n * Resolve the severity of a whole advisory, with provenance. Prefers a computed\n * CVSS v3 score (highest across all vectors), then the advisory's qualitative\n * `database_specific.severity`, then `unknown`.\n */\nexport function resolveSeverity(vuln: OsvVulnerability): SeverityInfo {\n const vectors: string[] = [];\n for (const s of vuln.severity ?? []) if (s.score) vectors.push(s.score);\n for (const affected of vuln.affected ?? []) {\n for (const s of affected.severity ?? []) if (s.score) vectors.push(s.score);\n }\n\n let best: CvssResult | null = null;\n for (const vector of vectors) {\n const result = scoreFromVector(vector);\n if (result && (!best || result.score > best.score)) best = result;\n }\n if (best) {\n return {\n level: best.level,\n score: best.score,\n vector: vectorFor(best, vectors),\n cvssVersion: best.version,\n source: 'cvss',\n };\n }\n\n const label = qualitativeLabel(vuln);\n if (label) return { level: levelFromLabel(label), source: 'database' };\n\n return { level: 'unknown', source: 'unknown' };\n}\n\nfunction vectorFor(best: CvssResult, vectors: string[]): string | undefined {\n return vectors.find((v) => v.startsWith(best.version));\n}\n\nfunction qualitativeLabel(vuln: OsvVulnerability): string | undefined {\n const fromRecord = (db: Record<string, unknown> | undefined): string | undefined => {\n const sev = db?.severity;\n return typeof sev === 'string' ? sev : undefined;\n };\n const top = fromRecord(vuln.database_specific);\n if (top) return top;\n for (const affected of vuln.affected ?? []) {\n const label = fromRecord(affected.database_specific);\n if (label) return label;\n }\n return undefined;\n}\n","import type { OsvVulnerability } from '../types.js';\n\n/**\n * In-memory index of OSV advisories for the npm ecosystem, keyed by package\n * name. Populated either from the downloaded offline DB zip (M3) or from online\n * API responses, then queried per installed package during a scan.\n *\n * Withdrawn advisories are dropped on insert so they can never produce a finding.\n */\nexport class OsvDatabase {\n private readonly byName = new Map<string, OsvVulnerability[]>();\n private readonly ids = new Set<string>();\n\n add(vuln: OsvVulnerability): void {\n if (vuln.withdrawn) return;\n if (this.ids.has(vuln.id)) return;\n this.ids.add(vuln.id);\n\n const names = new Set<string>();\n for (const affected of vuln.affected ?? []) {\n const ecosystem = affected.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (affected.package?.name) names.add(affected.package.name);\n }\n for (const name of names) {\n const list = this.byName.get(name);\n if (list) list.push(vuln);\n else this.byName.set(name, [vuln]);\n }\n }\n\n addAll(vulns: Iterable<OsvVulnerability>): void {\n for (const vuln of vulns) this.add(vuln);\n }\n\n /** Candidate advisories that name `packageName` (still need a version check). */\n vulnerabilitiesFor(packageName: string): OsvVulnerability[] {\n return this.byName.get(packageName) ?? [];\n }\n\n /** Number of distinct advisories indexed. */\n get size(): number {\n return this.ids.size;\n }\n}\n","import { resolve } from 'node:path';\nimport type {\n DependencyGraph,\n Finding,\n ScanOptions,\n ScanResult,\n ScanSummary,\n Severity,\n UnscannablePackage,\n} from './types.js';\nimport { SEVERITY_RANK, severityAtLeast } from './types.js';\nimport { loadDependencyGraph } from './lockfiles/normalize.js';\nimport { detectLockfile } from './lockfiles/detect.js';\nimport { buildFindings } from './match/findings.js';\nimport { resolveCacheDir } from './cache/paths.js';\nimport { createSource } from './osv/source.js';\nimport type { VulnSource } from './osv/source.js';\nimport type { PackageRef } from './osv/client.js';\n\nexport const TOOL = { name: 'lockhawk', version: '0.1.0' } as const;\n\n/**\n * Run a full scan: load and normalize the lockfile, query OSV for the unique\n * scannable packages, build findings, and assemble a {@link ScanResult}.\n *\n * A `source` can be injected (used by tests and by the CLI once it has resolved\n * options); otherwise one is created from `options.mode`.\n */\nexport async function scan(options: ScanOptions = {}, source?: VulnSource): Promise<ScanResult> {\n const start = Date.now();\n const dir = resolve(options.path ?? '.');\n const graph = loadDependencyGraph(dir);\n const detected = detectLockfile(dir);\n\n const scannable = uniqueScannablePackages(graph, options.prodOnly);\n const cacheDir = resolveCacheDir(options.cacheDir);\n const src =\n source ??\n createSource(options.mode ?? 'auto', {\n cacheDir,\n concurrency: options.concurrency,\n noCache: options.noCache,\n cacheTtlHours: options.cacheTtlHours,\n strictNetwork: options.strictNetwork,\n });\n\n options.onProgress?.('Checking dependencies against OSV.dev…');\n const resolved = await src.prepare(scannable);\n\n let findings = buildFindings(graph, resolved.candidatesFor, {\n prodOnly: options.prodOnly,\n ignore: options.ignore && options.ignore.length ? new Set(options.ignore) : undefined,\n });\n if (options.severityThreshold && options.severityThreshold !== 'none') {\n findings = findings.filter((f) =>\n severityAtLeast(f.severity.level, options.severityThreshold!),\n );\n }\n findings.sort(bySeverityThenName);\n\n const unscannable = unscannablePackages(graph);\n\n return {\n schemaVersion: 1,\n tool: { ...TOOL },\n scannedAt: new Date(start).toISOString(),\n target: {\n path: dir,\n manager: graph.manager,\n lockfile: detected?.filename ?? '',\n root: graph.root,\n },\n database: resolved.database,\n summary: summarize(findings),\n stats: {\n totalPackages: Object.keys(graph.nodes).length,\n uniquePackages: scannable.length,\n directDependencies: graph.directKeys.length,\n unscannable: unscannable.length,\n durationMs: Date.now() - start,\n },\n findings,\n unscannable,\n };\n}\n\n/** Unique `name@version` packages worth querying (skips local/unscannable, optionally dev). */\nexport function uniqueScannablePackages(graph: DependencyGraph, prodOnly?: boolean): PackageRef[] {\n const seen = new Set<string>();\n const out: PackageRef[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable) continue;\n if (prodOnly && node.scope === 'dev') continue;\n if (seen.has(node.key)) continue;\n seen.add(node.key);\n out.push({ name: node.name, version: node.version });\n }\n return out;\n}\n\nfunction unscannablePackages(graph: DependencyGraph): UnscannablePackage[] {\n const out: UnscannablePackage[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable)\n out.push({ name: node.name, version: node.version, reason: node.unscannable.reason });\n }\n return out;\n}\n\nfunction summarize(findings: Finding[]): ScanSummary {\n const summary: ScanSummary = {\n total: findings.length,\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n unknown: 0,\n none: 0,\n vulnerablePackages: 0,\n fixable: 0,\n };\n const vulnerable = new Set<string>();\n for (const f of findings) {\n summary[f.severity.level] += 1;\n vulnerable.add(`${f.packageName}@${f.version}`);\n if (f.fixedVersions.length > 0) summary.fixable += 1;\n }\n summary.vulnerablePackages = vulnerable.size;\n return summary;\n}\n\nfunction bySeverityThenName(a: Finding, b: Finding): number {\n const rank = SEVERITY_RANK[b.severity.level] - SEVERITY_RANK[a.severity.level];\n if (rank !== 0) return rank;\n return a.packageName.localeCompare(b.packageName);\n}\n\n/** Lowest severity that should trigger a non-zero exit given a `--fail-on` threshold. */\nexport function shouldFail(summary: ScanSummary, failOn: Severity): boolean {\n const levels: Severity[] = ['critical', 'high', 'medium', 'low', 'unknown'];\n return levels.some(\n (level) => SEVERITY_RANK[level] >= SEVERITY_RANK[failOn] && summary[level] > 0,\n );\n}\n","import { join } from 'node:path';\nimport envPaths from 'env-paths';\n\n/**\n * Resolve the on-disk cache directory, honoring (in priority order):\n * 1. an explicit override (the `--cache-dir` flag)\n * 2. the `LOCKHAWK_CACHE` environment variable\n * 3. the OS-conventional cache location (via env-paths)\n */\nexport function resolveCacheDir(override?: string): string {\n if (override) return override;\n if (process.env.LOCKHAWK_CACHE) return process.env.LOCKHAWK_CACHE;\n return envPaths('lockhawk', { suffix: '' }).cache;\n}\n\n/** Directory holding the offline OSV database for the npm ecosystem. */\nexport function offlineDbDir(cacheDir: string): string {\n return join(cacheDir, 'osv-db', 'npm');\n}\n\n/** Number of advisory shard buckets — bounds the on-disk file count for CI caching. */\nexport const SHARD_BUCKETS = 4096;\n\n/** FNV-1a hash → stable shard bucket for a package name. */\nexport function shardBucket(packageName: string): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < packageName.length; i++) {\n hash ^= packageName.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0) % SHARD_BUCKETS;\n}\n\n/** Path to the advisory shard file that holds a given package's advisories. */\nexport function shardPath(cacheDir: string, packageName: string): string {\n return join(offlineDbDir(cacheDir), 'by-name', `${shardBucket(packageName)}.json`);\n}\n\n/** Metadata file describing offline-DB freshness. */\nexport function offlineMetaPath(cacheDir: string): string {\n return join(offlineDbDir(cacheDir), 'meta.json');\n}\n\n/** Per-id online query cache file. */\nexport function queryCachePath(cacheDir: string, id: string): string {\n return join(cacheDir, 'query-cache', `${encodeURIComponent(id)}.json`);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport pLimit from 'p-limit';\nimport pRetry, { AbortError } from 'p-retry';\nimport type { OsvVulnerability } from '../types.js';\nimport { queryCachePath } from '../cache/paths.js';\n\nconst OSV_API = 'https://api.osv.dev/v1';\nconst BATCH_SIZE = 1000;\n\nexport interface PackageRef {\n name: string;\n version: string;\n}\n\nexport interface OnlineClientOptions {\n cacheDir: string;\n concurrency?: number;\n noCache?: boolean;\n cacheTtlHours?: number;\n retries?: number;\n}\n\ninterface BatchResult {\n vulns?: { id: string; modified?: string }[];\n next_page_token?: string;\n}\n\n/**\n * Online OSV source. Uses the batch endpoint (which returns only matched ids)\n * then hydrates each unique id to a full record — caching records by id so\n * repeat scans do no network work. All matching is re-validated downstream by\n * `buildFindings`, so this client only has to gather candidate records.\n */\nexport class OsvClient {\n private readonly limit;\n\n constructor(private readonly opts: OnlineClientOptions) {\n this.limit = pLimit(opts.concurrency ?? 5);\n }\n\n /** Fetch advisories affecting the given packages, keyed by package name. */\n async fetchAdvisories(packages: PackageRef[]): Promise<Map<string, OsvVulnerability[]>> {\n const unique = dedupePackages(packages);\n const idsByName = await this.queryBatch(unique);\n\n const allIds = new Set<string>();\n for (const ids of idsByName.values()) for (const id of ids) allIds.add(id);\n\n const records = await this.hydrate([...allIds]);\n\n const byName = new Map<string, OsvVulnerability[]>();\n for (const [name, ids] of idsByName) {\n const list: OsvVulnerability[] = [];\n for (const id of ids) {\n const record = records.get(id);\n if (record) list.push(record);\n }\n if (list.length) byName.set(name, list);\n }\n return byName;\n }\n\n private async queryBatch(packages: PackageRef[]): Promise<Map<string, Set<string>>> {\n const idsByName = new Map<string, Set<string>>();\n\n for (let i = 0; i < packages.length; i += BATCH_SIZE) {\n const chunk = packages.slice(i, i + BATCH_SIZE);\n const body = {\n queries: chunk.map((p) => ({\n package: { name: p.name, ecosystem: 'npm' },\n version: p.version,\n })),\n };\n const data = await this.request<{ results: BatchResult[] }>(`${OSV_API}/querybatch`, body);\n\n for (let j = 0; j < chunk.length; j++) {\n const pkg = chunk[j]!;\n const result = data.results[j];\n if (!result) continue;\n const set = idsByName.get(pkg.name) ?? new Set<string>();\n for (const vuln of result.vulns ?? []) set.add(vuln.id);\n // Pagination is rare for a single npm package; pull remaining pages if present.\n let pageToken = result.next_page_token;\n while (pageToken) {\n const page = await this.request<BatchResult>(`${OSV_API}/query`, {\n package: { name: pkg.name, ecosystem: 'npm' },\n version: pkg.version,\n page_token: pageToken,\n });\n for (const vuln of page.vulns ?? []) set.add(vuln.id);\n pageToken = page.next_page_token;\n }\n if (set.size) idsByName.set(pkg.name, set);\n }\n }\n return idsByName;\n }\n\n private async hydrate(ids: string[]): Promise<Map<string, OsvVulnerability>> {\n const records = new Map<string, OsvVulnerability>();\n await Promise.all(\n ids.map((id) =>\n this.limit(async () => {\n const record = await this.getVulnerability(id);\n if (record) records.set(id, record);\n }),\n ),\n );\n return records;\n }\n\n private async getVulnerability(id: string): Promise<OsvVulnerability | undefined> {\n const cached = await this.readCache(id);\n if (cached) return cached;\n const record = await this.request<OsvVulnerability>(\n `${OSV_API}/vulns/${encodeURIComponent(id)}`,\n );\n await this.writeCache(id, record);\n return record;\n }\n\n private async request<T>(url: string, body?: unknown): Promise<T> {\n const retries = this.opts.retries ?? 3;\n return pRetry(\n async () => {\n const res = await fetch(url, {\n method: body ? 'POST' : 'GET',\n headers: body ? { 'content-type': 'application/json' } : undefined,\n body: body ? JSON.stringify(body) : undefined,\n });\n if (res.ok) return (await res.json()) as T;\n if (res.status === 429 || res.status >= 500) {\n throw new Error(`OSV ${res.status} for ${url}`); // retryable\n }\n throw new AbortError(`OSV ${res.status} for ${url}`); // client error: do not retry\n },\n { retries },\n );\n }\n\n private async readCache(id: string): Promise<OsvVulnerability | undefined> {\n if (this.opts.noCache) return undefined;\n try {\n const parsed = JSON.parse(await readFile(queryCachePath(this.opts.cacheDir, id), 'utf8')) as {\n fetchedAt: number;\n vuln: OsvVulnerability;\n };\n const ttlMs = (this.opts.cacheTtlHours ?? 24) * 3_600_000;\n if (Date.now() - parsed.fetchedAt > ttlMs) return undefined;\n return parsed.vuln;\n } catch {\n return undefined;\n }\n }\n\n private async writeCache(id: string, vuln: OsvVulnerability): Promise<void> {\n if (this.opts.noCache) return;\n try {\n const path = queryCachePath(this.opts.cacheDir, id);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify({ fetchedAt: Date.now(), vuln }));\n } catch {\n // Cache write failures are non-fatal.\n }\n }\n}\n\nfunction dedupePackages(packages: PackageRef[]): PackageRef[] {\n const seen = new Set<string>();\n const out: PackageRef[] = [];\n for (const p of packages) {\n const key = `${p.name}@${p.version}`;\n if (!seen.has(key)) {\n seen.add(key);\n out.push(p);\n }\n }\n return out;\n}\n","import { createWriteStream } from 'node:fs';\nimport { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { gunzipSync, gzipSync } from 'node:zlib';\nimport yauzl from 'yauzl';\nimport type { OsvVulnerability } from '../types.js';\nimport { offlineDbDir, offlineMetaPath, shardBucket } from '../cache/paths.js';\n\nconst OSV_NPM_ZIP_URL = 'https://storage.googleapis.com/osv-vulnerabilities/npm/all.zip';\n\n// OSV advisory JSON files are small (well under 1 MiB). Cap per-entry size so a\n// malformed or hostile archive cannot exhaust memory. The download is from the\n// fixed OSV HTTPS bucket, so this is defense-in-depth, not the primary control.\nconst MAX_ENTRY_BYTES = 8 * 1024 * 1024;\n\nexport interface OfflineMeta {\n ecosystem: 'npm';\n source: string;\n /** ISO timestamp of the last successful refresh/check. */\n lastUpdated: string;\n recordCount: number;\n packageCount: number;\n etag?: string;\n lastModified?: string;\n}\n\nexport interface UpdateResult {\n status: 'updated' | 'unchanged';\n meta: OfflineMeta;\n}\n\nexport class OfflineDbMissingError extends Error {\n constructor() {\n super('No offline OSV database found. Run `lockhawk db update` first.');\n this.name = 'OfflineDbMissingError';\n }\n}\n\n// The cached ETag / Last-Modified are read back from a local file and echoed to\n// OSV as conditional-request headers. They originate from OSV's own responses\n// and the URL is fixed, so this is defense-in-depth: constrain each to its RFC\n// 9110 grammar so a tampered meta file can't inject arbitrary header content.\nconst IMF_FIXDATE = /^[A-Za-z]{3}, \\d{2} [A-Za-z]{3} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/;\n// entity-tag = [ \"W/\" ] DQUOTE *( %x21 / %x23-7E ) DQUOTE (excludes DQUOTE/CTLs)\nconst ENTITY_TAG = /^(?:W\\/)?\"[\\x21\\x23-\\x7e]*\"$/;\n\n/** A well-formed HTTP `Last-Modified` value (IMF-fixdate), else `undefined`. */\nexport function sanitizeHttpDate(value: string | undefined): string | undefined {\n return value && IMF_FIXDATE.test(value) ? value : undefined;\n}\n\n/** A well-formed entity-tag (strong or weak), else `undefined`. */\nexport function sanitizeETag(value: string | undefined): string | undefined {\n return value && ENTITY_TAG.test(value) ? value : undefined;\n}\n\n/** Read the offline DB metadata, or `undefined` if it has never been built. */\nexport async function readOfflineMeta(cacheDir: string): Promise<OfflineMeta | undefined> {\n try {\n return JSON.parse(await readFile(offlineMetaPath(cacheDir), 'utf8')) as OfflineMeta;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Download (or conditionally refresh) the npm OSV database and rebuild the\n * per-package shards. Uses ETag / Last-Modified so an unchanged DB costs a\n * single 304 and no rewrite. `nowIso` is injected so callers stamp the time\n * (the engine never calls Date.now itself in pure paths).\n */\nexport async function updateOfflineDatabase(opts: {\n cacheDir: string;\n nowIso: string;\n force?: boolean;\n onProgress?: (message: string) => void;\n}): Promise<UpdateResult> {\n const { cacheDir, nowIso, force, onProgress } = opts;\n const dir = offlineDbDir(cacheDir);\n await mkdir(dir, { recursive: true });\n\n const previous = force ? undefined : await readOfflineMeta(cacheDir);\n const headers: Record<string, string> = {};\n const etag = sanitizeETag(previous?.etag);\n const lastModified = sanitizeHttpDate(previous?.lastModified);\n if (etag) headers['If-None-Match'] = etag;\n if (lastModified) headers['If-Modified-Since'] = lastModified;\n\n onProgress?.('Fetching npm advisory database from OSV.dev…');\n const res = await fetch(OSV_NPM_ZIP_URL, { headers });\n\n if (res.status === 304 && previous) {\n const meta: OfflineMeta = { ...previous, lastUpdated: nowIso };\n await writeFile(offlineMetaPath(cacheDir), JSON.stringify(meta, null, 2));\n return { status: 'unchanged', meta };\n }\n if (!res.ok || !res.body) {\n throw new Error(`OSV database download failed: HTTP ${res.status}`);\n }\n\n // Extract from a private temp dir (not a predictable shared path), and always\n // clean it up — including on the error path.\n const tmp = await mkdtemp(join(tmpdir(), 'lockhawk-osv-'));\n const zipPath = join(tmp, 'all.zip');\n let records: OsvVulnerability[];\n try {\n await pipeline(\n Readable.fromWeb(res.body as Parameters<typeof Readable.fromWeb>[0]),\n createWriteStream(zipPath),\n );\n onProgress?.('Extracting advisories…');\n records = await readZipRecords(zipPath);\n } finally {\n await rm(tmp, { recursive: true, force: true });\n }\n\n onProgress?.('Building package index…');\n const byName = groupByPackage(records);\n await writeShards(cacheDir, byName);\n\n const meta: OfflineMeta = {\n ecosystem: 'npm',\n source: 'osv.dev',\n lastUpdated: nowIso,\n recordCount: records.length,\n packageCount: byName.size,\n etag: res.headers.get('etag') ?? undefined,\n lastModified: res.headers.get('last-modified') ?? undefined,\n };\n await writeFile(offlineMetaPath(cacheDir), JSON.stringify(meta, null, 2));\n return { status: 'updated', meta };\n}\n\ntype Bucket = Record<string, OsvVulnerability[]>;\n\nfunction bucketDir(cacheDir: string): string {\n return join(offlineDbDir(cacheDir), 'by-name');\n}\n\nfunction bucketPath(cacheDir: string, bucket: number): string {\n // Shards are gzipped: advisory JSON compresses ~5–6×, keeping the on-disk DB\n // (and the CI cache that stores it) small.\n return join(bucketDir(cacheDir), `${bucket}.json.gz`);\n}\n\n/**\n * Load advisories for the given package names. Names are grouped by shard\n * bucket so each bucket file is read at most once, and a scan only touches the\n * buckets its dependencies fall into.\n */\nexport async function loadAdvisoriesForPackages(\n cacheDir: string,\n names: Iterable<string>,\n): Promise<Map<string, OsvVulnerability[]>> {\n if (!(await readOfflineMeta(cacheDir))) throw new OfflineDbMissingError();\n\n const namesByBucket = new Map<number, string[]>();\n for (const name of new Set(names)) {\n const bucket = shardBucket(name);\n const list = namesByBucket.get(bucket);\n if (list) list.push(name);\n else namesByBucket.set(bucket, [name]);\n }\n\n const result = new Map<string, OsvVulnerability[]>();\n await Promise.all(\n [...namesByBucket.entries()].map(async ([bucket, bucketNames]) => {\n try {\n const data = JSON.parse(\n gunzipSync(await readFile(bucketPath(cacheDir, bucket))).toString('utf8'),\n ) as Bucket;\n for (const name of bucketNames) {\n const records = data[name];\n if (records?.length) result.set(name, records);\n }\n } catch {\n // No bucket file → none of these packages have advisories.\n }\n }),\n );\n return result;\n}\n\nfunction groupByPackage(records: OsvVulnerability[]): Map<string, OsvVulnerability[]> {\n const byName = new Map<string, OsvVulnerability[]>();\n for (const record of records) {\n if (record.withdrawn) continue;\n const names = new Set<string>();\n for (const affected of record.affected ?? []) {\n const ecosystem = affected.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (affected.package?.name) names.add(affected.package.name);\n }\n for (const name of names) {\n const list = byName.get(name);\n if (list) list.push(record);\n else byName.set(name, [record]);\n }\n }\n return byName;\n}\n\nasync function writeShards(\n cacheDir: string,\n byName: Map<string, OsvVulnerability[]>,\n): Promise<void> {\n const dir = bucketDir(cacheDir);\n await rm(dir, { recursive: true, force: true });\n await mkdir(dir, { recursive: true });\n\n // Group packages into a bounded number of bucket files (CI-cache friendly).\n const buckets = new Map<number, Bucket>();\n for (const [name, records] of byName) {\n const bucket = shardBucket(name);\n const map = buckets.get(bucket) ?? {};\n map[name] = records;\n buckets.set(bucket, map);\n }\n\n const entries = [...buckets.entries()];\n const BATCH = 256;\n for (let i = 0; i < entries.length; i += BATCH) {\n await Promise.all(\n entries\n .slice(i, i + BATCH)\n .map(([bucket, map]) =>\n writeFile(bucketPath(cacheDir, bucket), gzipSync(Buffer.from(JSON.stringify(map)))),\n ),\n );\n }\n}\n\nfunction readZipRecords(zipPath: string): Promise<OsvVulnerability[]> {\n return new Promise((resolve, reject) => {\n const out: OsvVulnerability[] = [];\n yauzl.open(zipPath, { lazyEntries: true }, (err, zip) => {\n if (err || !zip) return reject(err ?? new Error('Failed to open OSV zip'));\n zip.on('entry', (entry) => {\n if (!entry.fileName.endsWith('.json')) return zip.readEntry();\n // Bound memory: skip implausibly large entries (advisory JSON is small).\n if (entry.uncompressedSize > MAX_ENTRY_BYTES) return zip.readEntry();\n zip.openReadStream(entry, (streamErr, stream) => {\n if (streamErr || !stream) return zip.readEntry();\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('error', () => zip.readEntry());\n stream.on('end', () => {\n try {\n out.push(JSON.parse(Buffer.concat(chunks).toString('utf8')) as OsvVulnerability);\n } catch {\n // Skip malformed entries rather than failing the whole import.\n }\n zip.readEntry();\n });\n });\n });\n zip.on('end', () => resolve(out));\n zip.on('error', reject);\n zip.readEntry();\n });\n });\n}\n","import type { DatabaseInfo, OsvVulnerability, SourceMode } from '../types.js';\nimport { OsvClient } from './client.js';\nimport type { PackageRef } from './client.js';\nimport { OfflineDbMissingError, loadAdvisoriesForPackages, readOfflineMeta } from './offline-db.js';\n\n/** A source prepared for a specific package set: synchronous lookup + provenance. */\nexport interface ResolvedSource {\n candidatesFor(name: string): OsvVulnerability[];\n database: DatabaseInfo;\n}\n\n/** Strategy for obtaining advisories (offline DB, online API, or auto). */\nexport interface VulnSource {\n prepare(packages: PackageRef[]): Promise<ResolvedSource>;\n}\n\nexport interface SourceOptions {\n cacheDir: string;\n concurrency?: number;\n noCache?: boolean;\n cacheTtlHours?: number;\n /** Fail hard on network errors instead of degrading to cache. */\n strictNetwork?: boolean;\n /** Offline DB older than this many hours is flagged stale (default 24). */\n staleAfterHours?: number;\n}\n\nconst HOUR_MS = 3_600_000;\n\n/** Reads advisories from the on-disk offline database. */\nexport class OfflineSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const meta = await readOfflineMeta(this.opts.cacheDir);\n if (!meta) throw new OfflineDbMissingError();\n const map = await loadAdvisoriesForPackages(\n this.opts.cacheDir,\n packages.map((p) => p.name),\n );\n\n const ageHours = (Date.now() - Date.parse(meta.lastUpdated)) / HOUR_MS;\n const stale = ageHours > (this.opts.staleAfterHours ?? 24);\n const warnings = stale\n ? [\n `Offline database is ${Math.round(ageHours)}h old. Run \\`lockhawk db update\\` for current results.`,\n ]\n : [];\n\n return {\n candidatesFor: (name) => map.get(name) ?? [],\n database: {\n source: 'offline',\n recordCount: meta.recordCount,\n lastUpdated: meta.lastUpdated,\n ageHours: Math.round(ageHours * 10) / 10,\n stale,\n warnings,\n },\n };\n }\n}\n\n/** Queries the live OSV.dev API. Fail-open unless `strictNetwork` is set. */\nexport class OnlineSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const client = new OsvClient({\n cacheDir: this.opts.cacheDir,\n concurrency: this.opts.concurrency,\n noCache: this.opts.noCache,\n cacheTtlHours: this.opts.cacheTtlHours,\n });\n try {\n const map = await client.fetchAdvisories(packages);\n return {\n candidatesFor: (name) => map.get(name) ?? [],\n database: { source: 'online', stale: false, warnings: [] },\n };\n } catch (err) {\n if (this.opts.strictNetwork) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n return {\n candidatesFor: () => [],\n database: {\n source: 'online',\n stale: true,\n warnings: [\n `OSV.dev was unreachable (${reason}). Scan completed without online data — results may be incomplete.`,\n ],\n },\n };\n }\n }\n}\n\n/**\n * Prefers a fresh offline DB (fast, zero network), falls back to the online API,\n * and finally to a stale offline DB if the network is down — always degrading\n * gracefully so a scan never hard-fails on a transient outage.\n */\nexport class AutoSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const meta = await readOfflineMeta(this.opts.cacheDir);\n const ttl = this.opts.staleAfterHours ?? 24;\n\n if (meta) {\n const ageHours = (Date.now() - Date.parse(meta.lastUpdated)) / HOUR_MS;\n if (ageHours <= ttl) {\n return new OfflineSource(this.opts).prepare(packages); // fresh offline → fast path\n }\n }\n\n try {\n return await new OnlineSource({ ...this.opts, strictNetwork: true }).prepare(packages);\n } catch (err) {\n if (meta) {\n const resolved = await new OfflineSource(this.opts).prepare(packages);\n resolved.database.warnings.push(\n 'Used the stale offline database because OSV.dev was unreachable.',\n );\n return resolved;\n }\n if (this.opts.strictNetwork) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n return {\n candidatesFor: () => [],\n database: {\n source: 'online',\n stale: true,\n warnings: [\n `No offline database and OSV.dev was unreachable (${reason}). Run \\`lockhawk db update\\`.`,\n ],\n },\n };\n }\n }\n}\n\n/** Build the right source for the requested mode. */\nexport function createSource(mode: SourceMode, opts: SourceOptions): VulnSource {\n switch (mode) {\n case 'offline':\n return new OfflineSource(opts);\n case 'online':\n return new OnlineSource(opts);\n default:\n return new AutoSource(opts);\n }\n}\n","import type { ScanResult } from '../types.js';\n\n/** Serialize a scan result as pretty-printed JSON. */\nexport function toJson(result: ScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n","import type { Finding, ScanResult, Severity } from '../types.js';\n\n// Minimal SARIF 2.1.0 shapes (avoids a dependency on the `sarif` types package).\ninterface SarifRule {\n id: string;\n name?: string;\n shortDescription: { text: string };\n fullDescription?: { text: string };\n helpUri?: string;\n properties?: Record<string, unknown>;\n}\ninterface SarifResult {\n ruleId: string;\n level: 'error' | 'warning' | 'note';\n message: { text: string };\n locations: unknown[];\n partialFingerprints: Record<string, string>;\n properties?: Record<string, unknown>;\n}\nexport interface SarifLog {\n $schema: string;\n version: '2.1.0';\n runs: unknown[];\n}\n\nconst INFO_URI = 'https://github.com/lockhawk/lockhawk';\n\n/** First http(s) reference, if any — never propagate javascript:/data: URIs. */\nfunction helpUriFor(references: string[]): string | undefined {\n return references.find((ref) => {\n try {\n const u = new URL(ref);\n return u.protocol === 'http:' || u.protocol === 'https:';\n } catch {\n return false;\n }\n });\n}\n\n/** GitHub renders findings by `security-severity` (a CVSS-like number 0–10). */\nfunction securitySeverity(finding: Finding): number {\n if (typeof finding.severity.score === 'number') return finding.severity.score;\n switch (finding.severity.level) {\n case 'critical':\n return 9.5;\n case 'high':\n return 7.5;\n case 'medium':\n return 5;\n case 'low':\n return 2;\n default:\n return 0;\n }\n}\n\nfunction sarifLevel(severity: Severity): 'error' | 'warning' | 'note' {\n if (severity === 'critical' || severity === 'high') return 'error';\n if (severity === 'medium') return 'warning';\n return 'note';\n}\n\n/**\n * Convert a scan result to SARIF 2.1.0 for GitHub code scanning / Azure DevOps.\n * One rule per advisory; results carry stable `partialFingerprints` so the same\n * finding is not re-flagged as new on every run.\n */\nexport function toSarif(result: ScanResult): SarifLog {\n const lockfileUri = result.target.lockfile || 'package-lock.json';\n\n const rules = new Map<string, SarifRule>();\n const results: SarifResult[] = [];\n\n for (const finding of result.findings) {\n if (!rules.has(finding.id)) {\n rules.set(finding.id, {\n id: finding.id,\n name: `${finding.packageName} ${finding.id}`,\n shortDescription: { text: finding.summary },\n fullDescription: finding.details ? { text: finding.details } : undefined,\n helpUri: helpUriFor(finding.references),\n properties: {\n 'security-severity': String(securitySeverity(finding)),\n tags: ['security', 'dependency', finding.severity.level],\n },\n });\n }\n\n const path = finding.dependencyPaths[0]?.join(' › ') ?? finding.packageName;\n const fix = finding.fixedVersions[0] ? ` Fixed in ${finding.fixedVersions[0]}.` : '';\n results.push({\n ruleId: finding.id,\n level: sarifLevel(finding.severity.level),\n message: {\n text: `${finding.severity.level.toUpperCase()}: ${finding.packageName}@${finding.version} — ${finding.summary}.${fix} Path: ${path}.`,\n },\n locations: [\n {\n physicalLocation: {\n artifactLocation: { uri: lockfileUri },\n region: { startLine: 1 },\n },\n },\n ],\n partialFingerprints: {\n lockhawkFinding: `${finding.packageName}@${finding.version}@${finding.id}`,\n },\n properties: {\n package: finding.packageName,\n version: finding.version,\n scope: finding.scope,\n fixedVersions: finding.fixedVersions,\n },\n });\n }\n\n return {\n $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n name: result.tool.name,\n version: result.tool.version,\n informationUri: INFO_URI,\n rules: [...rules.values()],\n },\n },\n results,\n properties: {\n scannedAt: result.scannedAt,\n databaseSource: result.database.source,\n databaseAgeHours: result.database.ageHours,\n databaseStale: result.database.stale,\n },\n },\n ],\n };\n}\n\n/** Stringified SARIF log. */\nexport function toSarifString(result: ScanResult): string {\n return JSON.stringify(toSarif(result), null, 2);\n}\n","import type { ScanResult, Severity } from '../types.js';\n\n/** Placeholder the report UI shell embeds so we can inject scan data at scan time. */\nexport const DATA_MARKER = '<!--LOCKHAWK_DATA-->';\n\n/** Escape a JSON string for safe embedding inside a <script> tag. */\nfunction embed(result: ScanResult): string {\n // U+2028/U+2029 are legal in JSON but terminate lines inside inline <script>.\n const json = JSON.stringify(result)\n .replace(/</g, '\\\\u003c')\n .replace(/\\u2028/g, '\\\\u2028')\n .replace(/\\u2029/g, '\\\\u2029');\n return `<script>window.__SCAN_RESULT__ = ${json};</script>`;\n}\n\n/**\n * Produce a self-contained HTML report. When given the built report-UI `shell`\n * (M6), the scan data is injected into it; otherwise a dependency-free fallback\n * template is rendered so `--format html` always works.\n */\nexport function toHtml(result: ScanResult, shell?: string): string {\n const dataScript = embed(result);\n if (shell) {\n if (shell.includes(DATA_MARKER)) return shell.replace(DATA_MARKER, dataScript);\n return shell.replace('</head>', `${dataScript}</head>`);\n }\n return fallbackTemplate(result, dataScript);\n}\n\nconst SEVERITY_COLORS: Record<Severity, string> = {\n critical: '#b4232c',\n high: '#d9822b',\n medium: '#c9a227',\n low: '#3a7bd5',\n unknown: '#7a7a7a',\n none: '#3a9e54',\n};\n\nfunction esc(text: string): string {\n return text.replace(\n /[&<>\"]/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c]!,\n );\n}\n\n/** Only http(s) URLs are safe to render as links (blocks javascript:/data: hrefs). */\nfunction httpHref(url: string): string | undefined {\n try {\n const u = new URL(url);\n return u.protocol === 'http:' || u.protocol === 'https:' ? url : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction fallbackTemplate(result: ScanResult, dataScript: string): string {\n const { summary } = result;\n const cards = (['critical', 'high', 'medium', 'low', 'unknown'] as Severity[])\n .map(\n (sev) => `\n <div class=\"card\" style=\"border-top:4px solid ${SEVERITY_COLORS[sev]}\">\n <div class=\"count\">${summary[sev]}</div><div class=\"label\">${sev}</div>\n </div>`,\n )\n .join('');\n\n const rows = result.findings\n .map((f) => {\n const path = f.dependencyPaths[0]?.join(' › ') ?? f.packageName;\n const refs = f.references\n .slice(0, 3)\n .map((u) => httpHref(u))\n .filter((u): u is string => u !== undefined)\n .map((u) => `<a href=\"${esc(u)}\" target=\"_blank\" rel=\"noopener\">link</a>`)\n .join(' ');\n return `\n <tr>\n <td><span class=\"pill\" style=\"background:${SEVERITY_COLORS[f.severity.level]}\">${f.severity.level}${\n f.severity.score ? ` ${f.severity.score}` : ''\n }</span></td>\n <td><code>${esc(f.packageName)}@${esc(f.version)}</code><div class=\"scope\">${f.scope}${\n f.direct ? ' · direct' : ''\n }</div></td>\n <td><a href=\"https://osv.dev/${esc(f.id)}\" target=\"_blank\" rel=\"noopener\">${esc(f.id)}</a></td>\n <td>${esc(f.summary)}<div class=\"path\">${esc(path)}</div></td>\n <td>${f.fixedVersions[0] ? esc(f.fixedVersions[0]) : '—'}</td>\n <td>${refs}</td>\n </tr>`;\n })\n .join('');\n\n const dbWarnings = result.database.warnings\n .map((w) => `<div class=\"warn\">⚠ ${esc(w)}</div>`)\n .join('');\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>lockhawk report — ${esc(result.target.root.name)}</title>\n${dataScript}\n<style>\n :root { color-scheme: light dark; }\n * { box-sizing: border-box; }\n body { font: 15px/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; margin: 0; background: #f6f7f9; color: #1c1e21; }\n header { background: #11161d; color: #fff; padding: 24px 32px; }\n header h1 { margin: 0 0 4px; font-size: 20px; }\n header .meta { color: #9aa4b2; font-size: 13px; }\n main { max-width: 1100px; margin: 0 auto; padding: 24px 32px; }\n .cards { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; margin-bottom: 8px; }\n .card { background: #fff; border-radius: 8px; padding: 14px 16px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }\n .card .count { font-size: 28px; font-weight: 700; }\n .card .label { text-transform: capitalize; color: #6b7280; font-size: 13px; }\n .warn { background: #fff7e6; border: 1px solid #ffd591; color: #874d00; padding: 8px 12px; border-radius: 6px; margin: 12px 0; font-size: 13px; }\n table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 8px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,.08); margin-top: 16px; }\n th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eef0f3; vertical-align: top; font-size: 13px; }\n th { background: #f0f2f5; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; color: #6b7280; }\n .pill { color: #fff; padding: 2px 8px; border-radius: 999px; font-size: 12px; text-transform: capitalize; white-space: nowrap; }\n .scope, .path { color: #6b7280; font-size: 12px; }\n .path { margin-top: 4px; }\n code { background: #eef0f3; padding: 1px 5px; border-radius: 4px; }\n .empty { background: #fff; border-radius: 8px; padding: 40px; text-align: center; color: #3a9e54; font-size: 18px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }\n footer { max-width: 1100px; margin: 0 auto; padding: 16px 32px 40px; color: #9aa4b2; font-size: 12px; }\n</style>\n</head>\n<body>\n<header>\n <h1>lockhawk report</h1>\n <div class=\"meta\">${esc(result.target.root.name)}${\n result.target.root.version ? `@${esc(result.target.root.version)}` : ''\n } · ${esc(result.target.manager)} · ${result.stats.totalPackages} packages · scanned ${esc(result.scannedAt)}</div>\n</header>\n<main>\n <div class=\"cards\">${cards}</div>\n ${dbWarnings}\n ${\n result.findings.length === 0\n ? '<div class=\"empty\">✓ No known vulnerabilities found.</div>'\n : `<table>\n <thead><tr><th>Severity</th><th>Package</th><th>Advisory</th><th>Summary & path</th><th>Fixed in</th><th>Refs</th></tr></thead>\n <tbody>${rows}</tbody>\n </table>`\n }\n</main>\n<footer>Generated by lockhawk v${esc(result.tool.version)} · data from OSV.dev · database: ${esc(\n result.database.source,\n )}</footer>\n</body>\n</html>`;\n}\n","import type { Finding, ScanResult } from '../types.js';\n\n// JUnit XML reporter. Each vulnerability is emitted as a failed <testcase> so\n// CI systems that render JUnit results natively — Azure DevOps \"Tests\" tab,\n// GitHub test reporters, GitLab's test report / MR widget — show the findings\n// as a pass/fail dashboard with full detail, no custom UI required. A clean\n// scan emits a single passing test.\n\nfunction xml(text: string): string {\n return text.replace(\n /[&<>\"']/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!,\n );\n}\n\nfunction failureBody(f: Finding): string {\n const lines = [\n `Package: ${f.packageName}@${f.version} (${f.scope}${f.direct ? ', direct' : ', transitive'})`,\n `Severity: ${f.severity.level}${f.severity.score !== undefined ? `, CVSS ${f.severity.score}` : ''}${\n f.severity.vector ? ` (${f.severity.vector})` : ''\n }`,\n f.fixedVersions.length ? `Fixed in: ${f.fixedVersions.join(', ')}` : 'Fix: none available yet',\n f.dependencyPaths[0] ? `Dependency path: ${f.dependencyPaths[0].join(' > ')}` : '',\n f.recommendation ? `Recommendation: ${f.recommendation}` : '',\n f.references.length ? `References:\\n${f.references.join('\\n')}` : '',\n ];\n return lines.filter(Boolean).join('\\n');\n}\n\n/** Render a scan result as JUnit XML (one failed test per finding). */\nexport function toJunit(result: ScanResult): string {\n const { findings } = result;\n const failures = findings.length;\n const tests = findings.length === 0 ? 1 : findings.length;\n const time = ((result.stats.durationMs ?? 0) / 1000).toFixed(3);\n const suiteName = `${result.target.root.name} npm dependency vulnerabilities`;\n\n const cases =\n findings.length === 0\n ? [' <testcase name=\"No known vulnerabilities\" classname=\"lockhawk\" time=\"0\" />']\n : findings.map((f) => {\n const name = `${f.packageName}@${f.version}: ${f.id} (${f.severity.level})`;\n const message = `${f.severity.level.toUpperCase()}${\n f.severity.score !== undefined ? ` ${f.severity.score}` : ''\n } ${f.id}: ${f.summary}`;\n return [\n ` <testcase name=\"${xml(name)}\" classname=\"lockhawk.${xml(f.severity.level)}\" time=\"0\">`,\n ` <failure message=\"${xml(message)}\" type=\"${xml(f.severity.level)}\">${xml(failureBody(f))}</failure>`,\n ` </testcase>`,\n ].join('\\n');\n });\n\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n `<testsuites name=\"lockhawk\" tests=\"${tests}\" failures=\"${failures}\" errors=\"0\" time=\"${time}\">`,\n ` <testsuite name=\"${xml(suiteName)}\" tests=\"${tests}\" failures=\"${failures}\" errors=\"0\" time=\"${time}\">`,\n ...cases,\n ' </testsuite>',\n '</testsuites>',\n '',\n ].join('\\n');\n}\n"],"mappings":"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,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA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","names":["readFileSync","readFileSync","m","readFileSync","dirname","require","readFileSync","dirname","resolve","readFileSync","dirname","yaml","yaml","readFileSync","dirname","name","version","semver","score","m","semver","resolve","join","join","dirname","dirname","mkdir","readFile","writeFile","join","readFile","mkdir","meta","writeFile","join","resolve","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/lockfiles/normalize.ts","../src/lockfiles/detect.ts","../src/lockfiles/raw.ts","../src/lockfiles/npm.ts","../src/lockfiles/yarn.ts","../src/lockfiles/pnpm.ts","../src/graph/paths.ts","../src/match/ranges.ts","../src/match/dedupe.ts","../src/match/findings.ts","../src/score/cvss4-data.ts","../src/score/cvss4.ts","../src/score/cvss.ts","../src/osv/database.ts","../src/engine.ts","../src/cache/paths.ts","../src/osv/client.ts","../src/osv/offline-db.ts","../src/osv/source.ts","../src/report/json.ts","../src/report/sarif.ts","../src/report/html.ts","../src/report/junit.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// Shared data model for lockhawk.\n//\n// Every package (CLI, report UI, GitHub Action) depends on these types — this\n// is the contract that keeps the pipeline stages and the reporters in sync.\n// ---------------------------------------------------------------------------\n\n/** Qualitative severity bands (CVSS-aligned, plus `unknown` for un-scored advisories). */\nexport type Severity = 'critical' | 'high' | 'medium' | 'low' | 'none' | 'unknown';\n\n/** Ordering used for `--severity-threshold` and `--fail-on` comparisons. */\nexport const SEVERITY_RANK: Record<Severity, number> = {\n none: 0,\n unknown: 1,\n low: 2,\n medium: 3,\n high: 4,\n critical: 5,\n};\n\n/** `true` when `level` is at least as severe as `threshold`. */\nexport function severityAtLeast(level: Severity, threshold: Severity): boolean {\n return SEVERITY_RANK[level] >= SEVERITY_RANK[threshold];\n}\n\nexport type PackageManager = 'npm' | 'yarn' | 'pnpm';\n\n/** How a dependency is reachable from the project root. */\nexport type DepScope = 'prod' | 'dev' | 'optional' | 'peer';\n\n/** Unique identity of an installed package: `name@version`. */\nexport type PkgKey = string;\n\n/** Build a {@link PkgKey} from a name and version. */\nexport function pkgKey(name: string, version: string): PkgKey {\n return `${name}@${version}`;\n}\n\n/** A single installed package in the dependency graph. */\nexport interface DepNode {\n /** `name@version` — the node's key in {@link DependencyGraph.nodes}. */\n key: PkgKey;\n name: string;\n version: string;\n /** Strongest scope by which this node is reachable (prod beats dev/optional). */\n scope: DepScope;\n /** Whether this is a direct dependency of the project root. */\n direct: boolean;\n /** Keys of packages this node depends on (edges out). */\n dependencies: PkgKey[];\n /** Set when the package has no queryable registry version (file:/link:/git:). */\n unscannable?: { reason: string };\n}\n\n/** The normalized dependency tree, independent of which package manager produced it. */\nexport interface DependencyGraph {\n manager: PackageManager;\n lockfilePath: string;\n lockfileVersion?: string | number;\n root: { name: string; version?: string };\n /** All installed packages, keyed by {@link PkgKey}. */\n nodes: Record<PkgKey, DepNode>;\n /** Keys of the project's direct dependencies. */\n directKeys: PkgKey[];\n}\n\n// --- OSV schema (the subset we consume) -----------------------------------\n// https://ossf.github.io/osv-schema/\n\nexport interface OsvEvent {\n introduced?: string;\n fixed?: string;\n last_affected?: string;\n limit?: string;\n}\n\nexport interface OsvRange {\n type: 'SEMVER' | 'ECOSYSTEM' | 'GIT';\n events: OsvEvent[];\n repo?: string;\n}\n\nexport interface OsvSeverity {\n /** e.g. `CVSS_V3`, `CVSS_V4`. */\n type: string;\n /** CVSS vector string. */\n score: string;\n}\n\nexport interface OsvAffected {\n package?: { ecosystem?: string; name?: string; purl?: string };\n ranges?: OsvRange[];\n versions?: string[];\n severity?: OsvSeverity[];\n ecosystem_specific?: Record<string, unknown>;\n database_specific?: Record<string, unknown>;\n}\n\nexport interface OsvReference {\n type?: string;\n url: string;\n}\n\nexport interface OsvVulnerability {\n id: string;\n modified?: string;\n published?: string;\n /** RFC3339 timestamp; when present the advisory has been retracted and must be ignored. */\n withdrawn?: string;\n aliases?: string[];\n related?: string[];\n summary?: string;\n details?: string;\n severity?: OsvSeverity[];\n affected?: OsvAffected[];\n references?: OsvReference[];\n database_specific?: Record<string, unknown>;\n}\n\n// --- Scan results ----------------------------------------------------------\n\n/** Resolved severity for a finding, with provenance so the UI never shows a bare number. */\nexport interface SeverityInfo {\n level: Severity;\n /** Numeric CVSS base score (0–10) when computable. */\n score?: number;\n /** CVSS vector string the score was derived from. */\n vector?: string;\n /** e.g. `CVSS:3.1`, `CVSS:4.0`. */\n cvssVersion?: string;\n source: 'cvss' | 'database' | 'unknown';\n}\n\n/** One vulnerability affecting one installed package version. */\nexport interface Finding {\n /** Canonical id (prefers CVE, then GHSA, then the OSV id). */\n id: string;\n /** All known identifiers for this advisory, including the canonical one. */\n aliases: string[];\n packageName: string;\n version: string;\n scope: DepScope;\n direct: boolean;\n severity: SeverityInfo;\n summary: string;\n details?: string;\n references: string[];\n /** Versions that resolve this advisory (derived from OSV `fixed` events). */\n fixedVersions: string[];\n /** Human-readable mitigation guidance. */\n recommendation?: string;\n /** Each path runs root → … → `name@version`, explaining why the package is present. */\n dependencyPaths: PkgKey[][];\n source: string;\n}\n\nexport interface DatabaseInfo {\n source: 'offline' | 'online' | 'mixed';\n recordCount?: number;\n /** ISO timestamp of when the offline DB was last refreshed. */\n lastUpdated?: string;\n ageHours?: number;\n stale: boolean;\n warnings: string[];\n}\n\nexport interface ScanSummary {\n total: number;\n critical: number;\n high: number;\n medium: number;\n low: number;\n unknown: number;\n none: number;\n /** Number of distinct vulnerable packages (not advisories). */\n vulnerablePackages: number;\n /** Number of findings that have at least one known fixed version. */\n fixable: number;\n}\n\nexport interface ScanStats {\n totalPackages: number;\n uniquePackages: number;\n directDependencies: number;\n unscannable: number;\n durationMs?: number;\n}\n\nexport interface UnscannablePackage {\n name: string;\n version: string;\n reason: string;\n}\n\n/** The complete output of a scan — what reporters serialize and the dashboard renders. */\nexport interface ScanResult {\n schemaVersion: 1;\n tool: { name: string; version: string };\n /** ISO timestamp. */\n scannedAt: string;\n target: {\n path: string;\n manager: PackageManager;\n lockfile: string;\n root: { name: string; version?: string };\n };\n database: DatabaseInfo;\n summary: ScanSummary;\n stats: ScanStats;\n findings: Finding[];\n unscannable: UnscannablePackage[];\n}\n\n// --- Engine options --------------------------------------------------------\n\nexport type SourceMode = 'auto' | 'offline' | 'online';\n\nexport interface ScanOptions {\n /** Project directory to scan (defaults to cwd). */\n path?: string;\n /** Vulnerability-source strategy. */\n mode?: SourceMode;\n cacheDir?: string;\n cacheTtlHours?: number;\n noCache?: boolean;\n concurrency?: number;\n /** Ignore dev dependencies. */\n prodOnly?: boolean;\n /** Advisory ids (CVE/GHSA/OSV) to suppress. */\n ignore?: string[];\n /** Fail hard on network errors instead of degrading to cache (fail-open). */\n strictNetwork?: boolean;\n /** Limit the scan to a single workspace by name. */\n workspace?: string;\n /** Drop findings below this severity from the report. */\n severityThreshold?: Severity;\n /** Progress callback (used by the CLI spinner). */\n onProgress?: (message: string) => void;\n}\n","import { resolve } from 'node:path';\nimport type { DependencyGraph } from '../types.js';\nimport { detectLockfile } from './detect.js';\nimport type { DetectedLockfile } from './detect.js';\nimport { buildDependencyGraph } from './raw.js';\nimport type { RawGraph } from './raw.js';\nimport { parseNpm } from './npm.js';\nimport { parseYarn } from './yarn.js';\nimport { parsePnpm } from './pnpm.js';\n\nexport class LockfileError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'LockfileError';\n }\n}\n\n/** Parse a detected lockfile into the manager-agnostic {@link RawGraph}. */\nexport function parseLockfile(detected: DetectedLockfile): RawGraph {\n try {\n switch (detected.manager) {\n case 'npm':\n return parseNpm(detected.path);\n case 'yarn':\n return parseYarn(detected.path);\n case 'pnpm':\n return parsePnpm(detected.path);\n }\n } catch (err) {\n throw new LockfileError(\n `Failed to parse ${detected.filename}: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\n/**\n * Detect, parse and normalize the lockfile in `dir` into a {@link DependencyGraph}.\n * Throws {@link LockfileError} when no lockfile is present or parsing fails.\n */\nexport function loadDependencyGraph(dir: string): DependencyGraph {\n const detected = detectLockfile(resolve(dir));\n if (!detected) {\n throw new LockfileError(\n `No lockfile found in ${dir}. Expected one of: package-lock.json, yarn.lock, pnpm-lock.yaml.`,\n );\n }\n return buildDependencyGraph(parseLockfile(detected));\n}\n","import { existsSync, readFileSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport type { PackageManager } from '../types.js';\n\nexport interface DetectedLockfile {\n manager: PackageManager;\n /** Absolute or relative path to the lockfile. */\n path: string;\n filename: string;\n}\n\nconst LOCKFILES: { filename: string; manager: PackageManager }[] = [\n { filename: 'pnpm-lock.yaml', manager: 'pnpm' },\n { filename: 'yarn.lock', manager: 'yarn' },\n { filename: 'package-lock.json', manager: 'npm' },\n { filename: 'npm-shrinkwrap.json', manager: 'npm' },\n];\n\n/**\n * Find the lockfile to scan in `dir`. If several are present we prefer pnpm,\n * then yarn, then npm — mirroring how a project that committed multiple\n * lockfiles is most likely actually installed.\n */\nexport function detectLockfile(dir: string): DetectedLockfile | undefined {\n for (const { filename, manager } of LOCKFILES) {\n const path = join(dir, filename);\n if (existsSync(path) && statSync(path).isFile()) {\n return { manager, path, filename };\n }\n }\n return undefined;\n}\n\nexport interface RootManifest {\n name: string;\n version?: string;\n dependencies: Record<string, string>;\n devDependencies: Record<string, string>;\n optionalDependencies: Record<string, string>;\n peerDependencies: Record<string, string>;\n}\n\n/** Read and normalize the project's `package.json` (used to determine direct deps). */\nexport function readRootManifest(dir: string): RootManifest {\n const path = join(dir, 'package.json');\n let raw: Record<string, unknown> = {};\n if (existsSync(path)) {\n try {\n raw = JSON.parse(readFileSync(path, 'utf8')) as Record<string, unknown>;\n } catch {\n raw = {};\n }\n }\n const asMap = (v: unknown): Record<string, string> =>\n v && typeof v === 'object' ? (v as Record<string, string>) : {};\n return {\n name: typeof raw.name === 'string' ? raw.name : 'project',\n version: typeof raw.version === 'string' ? raw.version : undefined,\n dependencies: asMap(raw.dependencies),\n devDependencies: asMap(raw.devDependencies),\n optionalDependencies: asMap(raw.optionalDependencies),\n peerDependencies: asMap(raw.peerDependencies),\n };\n}\n","import type {\n DependencyGraph,\n DepNode,\n DepScope,\n PackageManager,\n PkgKey,\n UnscannablePackage,\n} from '../types.js';\n\n/**\n * Manager-agnostic parser output. Each lockfile parser produces one of these;\n * a single {@link buildDependencyGraph} step then classifies scopes by\n * reachability and assembles the final {@link DependencyGraph}.\n *\n * Computing scope from reachability (rather than per-package `dev` flags) is\n * what lets us treat npm, yarn and pnpm uniformly — pnpm v9 lockfiles, for\n * instance, no longer carry a per-package `dev` field.\n */\nexport interface RawNode {\n key: PkgKey;\n name: string;\n version: string;\n /** Keys of packages this node depends on (edges out). May contain duplicates. */\n dependencies: PkgKey[];\n /** Set when there is no queryable registry version (file:/link:/git:/workspace). */\n unscannable?: { reason: string };\n}\n\nexport interface RawGraph {\n manager: PackageManager;\n lockfilePath: string;\n lockfileVersion?: string | number;\n root: { name: string; version?: string };\n nodes: Record<PkgKey, RawNode>;\n /** Direct production dependencies of the project root. */\n directProd: PkgKey[];\n /** Direct dev dependencies of the project root. */\n directDev: PkgKey[];\n /** Direct optional dependencies of the project root. */\n directOptional: PkgKey[];\n unscannable: UnscannablePackage[];\n}\n\n/** Breadth-first set of all keys reachable from the given starting keys. */\nfunction reachable(start: Iterable<PkgKey>, nodes: Record<PkgKey, RawNode>): Set<PkgKey> {\n const seen = new Set<PkgKey>();\n const queue: PkgKey[] = [];\n for (const k of start) {\n if (!seen.has(k)) {\n seen.add(k);\n queue.push(k);\n }\n }\n for (let i = 0; i < queue.length; i++) {\n const node = nodes[queue[i]!];\n if (!node) continue;\n for (const dep of node.dependencies) {\n if (!seen.has(dep)) {\n seen.add(dep);\n queue.push(dep);\n }\n }\n }\n return seen;\n}\n\n/**\n * Classify every node's scope by reachability and assemble the normalized graph.\n * Priority when a node is reachable multiple ways: prod > optional > dev.\n */\nexport function buildDependencyGraph(raw: RawGraph): DependencyGraph {\n const prodReach = reachable(raw.directProd, raw.nodes);\n const optionalReach = reachable(raw.directOptional, raw.nodes);\n const devReach = reachable(raw.directDev, raw.nodes);\n const direct = new Set<PkgKey>([...raw.directProd, ...raw.directOptional, ...raw.directDev]);\n\n const nodes: Record<PkgKey, DepNode> = {};\n for (const [key, rn] of Object.entries(raw.nodes)) {\n let scope: DepScope;\n if (prodReach.has(key)) scope = 'prod';\n else if (optionalReach.has(key)) scope = 'optional';\n else if (devReach.has(key)) scope = 'dev';\n else scope = 'prod'; // explicitly-listed-but-unreferenced: treat as prod\n\n nodes[key] = {\n key,\n name: rn.name,\n version: rn.version,\n scope,\n direct: direct.has(key),\n dependencies: dedupe(rn.dependencies),\n ...(rn.unscannable ? { unscannable: rn.unscannable } : {}),\n };\n }\n\n return {\n manager: raw.manager,\n lockfilePath: raw.lockfilePath,\n lockfileVersion: raw.lockfileVersion,\n root: raw.root,\n nodes,\n directKeys: [...direct].filter((k) => nodes[k] !== undefined),\n };\n}\n\nfunction dedupe(keys: PkgKey[]): PkgKey[] {\n return keys.length > 1 ? [...new Set(keys)] : keys;\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { pkgKey } from '../types.js';\nimport type { UnscannablePackage } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\n\ninterface PkgEntry {\n name?: string;\n version?: string;\n resolved?: string;\n link?: boolean;\n dependencies?: Record<string, string>;\n devDependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n peerDependencies?: Record<string, string>;\n}\n\ninterface V1Entry {\n version?: string;\n dev?: boolean;\n optional?: boolean;\n requires?: Record<string, string>;\n dependencies?: Record<string, V1Entry>;\n}\n\n/** Parse a `package-lock.json` / `npm-shrinkwrap.json` (lockfile v1, v2 or v3). */\nexport function parseNpm(lockfilePath: string): RawGraph {\n const data = JSON.parse(readFileSync(lockfilePath, 'utf8')) as {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n packages?: Record<string, PkgEntry>;\n dependencies?: Record<string, V1Entry>;\n };\n\n if (data.packages) {\n return parsePackages(data, lockfilePath);\n }\n return parseLegacy(data, lockfilePath);\n}\n\n/** Last `node_modules/<name>` segment of an install path, scope-aware. */\nfunction nameFromPath(p: string): string {\n const marker = 'node_modules/';\n const idx = p.lastIndexOf(marker);\n return idx === -1 ? p : p.slice(idx + marker.length);\n}\n\n/** Lockfile v2/v3: a flat `packages` map keyed by install path. */\nfunction parsePackages(\n data: {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n packages?: Record<string, PkgEntry>;\n },\n lockfilePath: string,\n): RawGraph {\n const packages = data.packages ?? {};\n const rootEntry = packages[''] ?? {};\n const root = {\n name: rootEntry.name ?? data.name ?? 'project',\n version: rootEntry.version ?? data.version,\n };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n const unscannable: UnscannablePackage[] = [];\n const pathToKey: Record<string, string> = Object.create(null);\n\n // First pass: create a node per installed package and map its path → key.\n for (const [p, entry] of Object.entries(packages)) {\n if (p === '' || entry.link) continue;\n const name = entry.name ?? nameFromPath(p);\n const version = entry.version;\n if (!version) continue;\n const key = pkgKey(name, version);\n pathToKey[p] = key;\n if (!nodes[key]) {\n const node: RawNode = { key, name, version, dependencies: [] };\n // A package living outside node_modules is a local workspace package —\n // it is your own code, not something to look up in OSV.\n if (!p.includes('node_modules')) {\n node.unscannable = { reason: 'local workspace package' };\n unscannable.push({ name, version, reason: 'local workspace package' });\n }\n nodes[key] = node;\n }\n }\n\n // Resolve a dependency name from a package path using node_modules hoisting:\n // check the nearest node_modules first, then walk up toward the root.\n const resolveDep = (fromPath: string, depName: string): string | undefined => {\n let prefix = fromPath;\n for (;;) {\n const candidate = `${prefix ? `${prefix}/` : ''}node_modules/${depName}`;\n const entry = packages[candidate];\n if (entry) {\n if (entry.link && typeof entry.resolved === 'string') return entry.resolved;\n return candidate;\n }\n if (!prefix) return undefined;\n const i = prefix.lastIndexOf('/node_modules/');\n prefix = i === -1 ? '' : prefix.slice(0, i);\n }\n };\n\n const directProd = new Set<string>();\n const directDev = new Set<string>();\n const directOptional = new Set<string>();\n\n // Second pass: build edges. Only the root/workspace packages contribute\n // direct deps and dev edges; transitive packages contribute prod/optional only.\n for (const [p, entry] of Object.entries(packages)) {\n if (entry.link) continue;\n const fromKey = p === '' ? undefined : pathToKey[p];\n const isLocalRoot = p === '' || !p.includes('node_modules');\n\n const addEdges = (names: string[], bucket?: Set<string>): void => {\n for (const depName of names) {\n const targetPath = resolveDep(p, depName);\n if (!targetPath) continue; // unmet optional / not installed on this platform\n const targetKey = pathToKey[targetPath];\n if (!targetKey) continue;\n if (fromKey && fromKey !== targetKey) nodes[fromKey]!.dependencies.push(targetKey);\n if (bucket) bucket.add(targetKey);\n }\n };\n\n addEdges(Object.keys(entry.dependencies ?? {}), isLocalRoot ? directProd : undefined);\n addEdges(\n Object.keys(entry.optionalDependencies ?? {}),\n isLocalRoot ? directOptional : undefined,\n );\n if (isLocalRoot) {\n addEdges(Object.keys(entry.devDependencies ?? {}), directDev);\n }\n }\n\n return {\n manager: 'npm',\n lockfilePath,\n lockfileVersion: data.lockfileVersion,\n root,\n nodes,\n directProd: [...directProd],\n directDev: [...directDev],\n directOptional: [...directOptional],\n unscannable,\n };\n}\n\n/** Lockfile v1: a nested `dependencies` tree. Direct deps come from package.json. */\nfunction parseLegacy(\n data: {\n name?: string;\n version?: string;\n lockfileVersion?: number;\n dependencies?: Record<string, V1Entry>;\n },\n lockfilePath: string,\n): RawGraph {\n const manifest = readRootManifest(dirname(lockfilePath));\n const root = { name: data.name ?? manifest.name, version: data.version ?? manifest.version };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n\n const buildLevel = (deps?: Record<string, V1Entry>): Map<string, string> => {\n const m = new Map<string, string>();\n for (const [name, info] of Object.entries(deps ?? {})) {\n if (info?.version) m.set(name, info.version);\n }\n return m;\n };\n\n // Resolve a required name against the visibility chain, nearest level first.\n const resolveFromChain = (name: string, chain: Map<string, string>[]): string | undefined => {\n for (let i = chain.length - 1; i >= 0; i--) {\n const v = chain[i]!.get(name);\n if (v) return v;\n }\n return undefined;\n };\n\n const visit = (\n deps: Record<string, V1Entry> | undefined,\n ancestors: Map<string, string>[],\n ): void => {\n const level = buildLevel(deps);\n const chain = [...ancestors, level];\n for (const [name, info] of Object.entries(deps ?? {})) {\n const version = info?.version;\n if (!version) continue;\n const key = pkgKey(name, version);\n if (!nodes[key]) nodes[key] = { key, name, version, dependencies: [] };\n\n const ownChain = [...chain, buildLevel(info.dependencies)];\n for (const reqName of Object.keys(info.requires ?? {})) {\n const v = resolveFromChain(reqName, ownChain);\n if (v) {\n const targetKey = pkgKey(reqName, v);\n if (targetKey !== key) nodes[key]!.dependencies.push(targetKey);\n }\n }\n if (info.dependencies) visit(info.dependencies, chain);\n }\n };\n visit(data.dependencies, []);\n\n // Direct deps: declared in package.json, resolved to top-level installed versions.\n const topLevel = buildLevel(data.dependencies);\n const directProd: string[] = [];\n const directDev: string[] = [];\n const directOptional: string[] = [];\n const classify = (names: string[], out: string[]): void => {\n for (const name of names) {\n const v = topLevel.get(name);\n if (v) out.push(pkgKey(name, v));\n }\n };\n classify(Object.keys(manifest.dependencies), directProd);\n classify(Object.keys(manifest.optionalDependencies), directOptional);\n classify(Object.keys(manifest.devDependencies), directDev);\n\n return {\n manager: 'npm',\n lockfilePath,\n lockfileVersion: data.lockfileVersion,\n root,\n nodes,\n directProd,\n directDev,\n directOptional,\n unscannable: [],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport { createRequire } from 'node:module';\nimport yaml from 'js-yaml';\nimport { pkgKey } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\nimport type { RootManifest } from './detect.js';\n\n// @yarnpkg/lockfile is CommonJS with no ESM default; load it via require so the\n// interop is identical under vitest (vite) and the built Node ESM bundle.\nconst require = createRequire(import.meta.url);\nconst yarnLockfile = require('@yarnpkg/lockfile') as {\n parse(content: string): { type: string; object: Record<string, YarnEntry> };\n};\n\ninterface YarnEntry {\n version?: string;\n resolution?: string;\n dependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n}\n\n/** Parse a `yarn.lock` (classic v1 or berry v2+). */\nexport function parseYarn(lockfilePath: string): RawGraph {\n const content = readFileSync(lockfilePath, 'utf8');\n const manifest = readRootManifest(dirname(lockfilePath));\n const isBerry = content.includes('__metadata');\n const { descriptorToVersion, entryByVersion, lockfileVersion } = isBerry\n ? parseBerry(content)\n : parseClassic(content);\n return assemble(\n lockfilePath,\n manifest,\n descriptorToVersion,\n entryByVersion,\n lockfileVersion,\n isBerry,\n );\n}\n\n/** Split a \"name@range\" descriptor, scope-aware. */\nfunction splitDescriptor(descriptor: string): { name: string; range: string } | undefined {\n const at = descriptor.lastIndexOf('@');\n if (at <= 0) return undefined;\n return { name: descriptor.slice(0, at), range: descriptor.slice(at + 1) };\n}\n\ninterface ParsedLock {\n /** \"name@range\" → resolved version. */\n descriptorToVersion: Map<string, string>;\n /** \"name@version\" → its dependency ranges. */\n entryByVersion: Map<string, YarnEntry>;\n lockfileVersion: string | number;\n}\n\nfunction parseClassic(content: string): ParsedLock {\n const parsed = yarnLockfile.parse(content) as { object: Record<string, YarnEntry> };\n const descriptorToVersion = new Map<string, string>();\n const entryByVersion = new Map<string, YarnEntry>();\n for (const [rawKey, entry] of Object.entries(parsed.object)) {\n if (!entry.version) continue;\n // A key may list several descriptors joined by \", \".\n for (const descriptor of rawKey.split(/,\\s*/)) {\n const split = splitDescriptor(descriptor);\n if (split) descriptorToVersion.set(`${split.name}@${split.range}`, entry.version);\n if (split) entryByVersion.set(pkgKey(split.name, entry.version), entry);\n }\n }\n return { descriptorToVersion, entryByVersion, lockfileVersion: 1 };\n}\n\nfunction parseBerry(content: string): ParsedLock {\n const doc = (yaml.load(content) as Record<string, YarnEntry & { version?: string }>) ?? {};\n const descriptorToVersion = new Map<string, string>();\n const entryByVersion = new Map<string, YarnEntry>();\n let lockfileVersion: string | number = 'berry';\n for (const [rawKey, entry] of Object.entries(doc)) {\n if (rawKey === '__metadata') {\n const v = (entry as { version?: string | number }).version;\n if (v !== undefined) lockfileVersion = v;\n continue;\n }\n if (!entry.version) continue;\n for (const descriptor of rawKey.split(/,\\s*/)) {\n const split = splitDescriptor(descriptor);\n if (!split) continue;\n descriptorToVersion.set(`${split.name}@${split.range}`, entry.version);\n entryByVersion.set(pkgKey(split.name, entry.version), entry);\n }\n }\n return { descriptorToVersion, entryByVersion, lockfileVersion };\n}\n\nfunction assemble(\n lockfilePath: string,\n manifest: RootManifest,\n descriptorToVersion: Map<string, string>,\n entryByVersion: Map<string, YarnEntry>,\n lockfileVersion: string | number,\n isBerry: boolean,\n): RawGraph {\n // Resolve a (name, range) request to an installed version, tolerating berry's\n // protocol prefixes (e.g. \"npm:^1.0.0\") that the manifest omits.\n const resolve = (name: string, range: string): string | undefined => {\n const candidates = isBerry\n ? [`${name}@${range}`, `${name}@npm:${range}`]\n : [`${name}@${range}`];\n for (const c of candidates) {\n const v = descriptorToVersion.get(c);\n if (v) return v;\n }\n return undefined;\n };\n\n const nodes: Record<string, RawNode> = Object.create(null);\n for (const [key, entry] of entryByVersion) {\n // `key` is already a `name@version` PkgKey; recover both halves.\n const at = key.lastIndexOf('@');\n const name = key.slice(0, at);\n const version = key.slice(at + 1);\n if (!nodes[key]) nodes[key] = { key, name, version, dependencies: [] };\n const addEdges = (deps?: Record<string, string>): void => {\n for (const [depName, depRange] of Object.entries(deps ?? {})) {\n const v = resolve(depName, depRange);\n if (!v) continue;\n const targetKey = pkgKey(depName, v);\n if (targetKey !== key) nodes[key]!.dependencies.push(targetKey);\n }\n };\n addEdges(entry.dependencies);\n addEdges(entry.optionalDependencies);\n }\n\n const toDirect = (deps: Record<string, string>): string[] => {\n const out: string[] = [];\n for (const [name, range] of Object.entries(deps)) {\n const v = resolve(name, range);\n if (v) out.push(pkgKey(name, v));\n }\n return out;\n };\n\n return {\n manager: 'yarn',\n lockfilePath,\n lockfileVersion,\n root: { name: manifest.name, version: manifest.version },\n nodes,\n directProd: toDirect(manifest.dependencies),\n directDev: toDirect(manifest.devDependencies),\n directOptional: toDirect(manifest.optionalDependencies),\n unscannable: [],\n };\n}\n","import { readFileSync } from 'node:fs';\nimport { dirname } from 'node:path';\nimport yaml from 'js-yaml';\nimport { pkgKey } from '../types.js';\nimport type { RawGraph, RawNode } from './raw.js';\nimport { readRootManifest } from './detect.js';\n\ninterface PnpmEntry {\n dependencies?: Record<string, string>;\n optionalDependencies?: Record<string, string>;\n}\n\ninterface ImporterDeps {\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n}\n\ninterface PnpmLock {\n lockfileVersion?: string | number;\n importers?: Record<string, ImporterDeps>;\n packages?: Record<string, PnpmEntry>;\n snapshots?: Record<string, PnpmEntry>;\n dependencies?: Record<string, unknown>;\n devDependencies?: Record<string, unknown>;\n optionalDependencies?: Record<string, unknown>;\n}\n\n/** Parse a `pnpm-lock.yaml` (lockfile v5, v6 or v9). */\nexport function parsePnpm(lockfilePath: string): RawGraph {\n const doc = (yaml.load(readFileSync(lockfilePath, 'utf8')) as PnpmLock) ?? {};\n const manifest = readRootManifest(dirname(lockfilePath));\n const major = majorVersion(doc.lockfileVersion);\n\n const nodes: Record<string, RawNode> = Object.create(null);\n\n // Nodes come from the `packages` map (one entry per installed package).\n for (const key of Object.keys(doc.packages ?? {})) {\n const parsed = parseKey(key, major);\n if (!parsed) continue;\n const nodeKey = pkgKey(parsed.name, parsed.version);\n if (!nodes[nodeKey]) {\n nodes[nodeKey] = {\n key: nodeKey,\n name: parsed.name,\n version: parsed.version,\n dependencies: [],\n };\n }\n }\n\n // Edges: from `snapshots` in v9, else from `packages` directly.\n const edgeSource = major >= 9 ? (doc.snapshots ?? {}) : (doc.packages ?? {});\n for (const [key, entry] of Object.entries(edgeSource)) {\n const parsed = parseKey(key, major);\n if (!parsed) continue;\n const fromKey = pkgKey(parsed.name, parsed.version);\n if (!nodes[fromKey]) {\n nodes[fromKey] = {\n key: fromKey,\n name: parsed.name,\n version: parsed.version,\n dependencies: [],\n };\n }\n const addEdges = (deps?: Record<string, string>): void => {\n for (const [depName, depValue] of Object.entries(deps ?? {})) {\n const targetKey = pkgKey(depName, stripVersion(depValue, major));\n if (targetKey !== fromKey && nodes[targetKey]) nodes[fromKey]!.dependencies.push(targetKey);\n }\n };\n addEdges(entry.dependencies);\n addEdges(entry.optionalDependencies);\n }\n\n // Roots: from `importers` (workspaces + modern single project) or the\n // top-level dependency maps (older single-project lockfiles).\n const importers: Record<string, ImporterDeps> = doc.importers ?? {\n '.': {\n dependencies: doc.dependencies,\n devDependencies: doc.devDependencies,\n optionalDependencies: doc.optionalDependencies,\n },\n };\n\n const directProd = new Set<string>();\n const directDev = new Set<string>();\n const directOptional = new Set<string>();\n const collect = (deps: Record<string, unknown> | undefined, into: Set<string>): void => {\n for (const [name, val] of Object.entries(deps ?? {})) {\n const version = importerVersion(val, major);\n if (!version) continue;\n const key = pkgKey(name, version);\n if (nodes[key]) into.add(key);\n }\n };\n for (const imp of Object.values(importers)) {\n collect(imp.dependencies, directProd);\n collect(imp.optionalDependencies, directOptional);\n collect(imp.devDependencies, directDev);\n }\n\n return {\n manager: 'pnpm',\n lockfilePath,\n lockfileVersion: doc.lockfileVersion,\n root: { name: manifest.name, version: manifest.version },\n nodes,\n directProd: [...directProd],\n directDev: [...directDev],\n directOptional: [...directOptional],\n unscannable: [],\n };\n}\n\nfunction majorVersion(v: string | number | undefined): number {\n const n = parseFloat(String(v ?? '9'));\n return Number.isNaN(n) ? 9 : Math.floor(n);\n}\n\n/** Parse a pnpm package key into `{ name, version }`, format-aware. */\nfunction parseKey(key: string, major: number): { name: string; version: string } | undefined {\n const k = key.startsWith('/') ? key.slice(1) : key;\n if (major < 6) {\n // `name/version[_peers]`\n const lastSlash = k.lastIndexOf('/');\n if (lastSlash <= 0) return undefined;\n const name = k.slice(0, lastSlash);\n const version = stripVersion(k.slice(lastSlash + 1), major);\n return version ? { name, version } : undefined;\n }\n // `name@version[(peers)]`\n const at = k.lastIndexOf('@');\n if (at <= 0) return undefined;\n const name = k.slice(0, at);\n const version = stripVersion(k.slice(at + 1), major);\n return version ? { name, version } : undefined;\n}\n\n/** Strip pnpm's peer-dependency suffix from a version ref. */\nfunction stripVersion(value: string, major: number): string {\n let v = value;\n if (major < 6) {\n const us = v.indexOf('_');\n if (us !== -1) v = v.slice(0, us);\n }\n const paren = v.indexOf('(');\n if (paren !== -1) v = v.slice(0, paren);\n return v;\n}\n\n/** Extract the installed version from an importer dependency entry. */\nfunction importerVersion(val: unknown, major: number): string | undefined {\n let ref: string | undefined;\n if (typeof val === 'string') ref = val;\n else if (\n val &&\n typeof val === 'object' &&\n typeof (val as { version?: unknown }).version === 'string'\n ) {\n ref = (val as { version: string }).version;\n }\n if (!ref) return undefined;\n if (ref.startsWith('link:') || ref.startsWith('file:') || ref.startsWith('workspace:'))\n return undefined;\n return stripVersion(ref, major);\n}\n","import type { DependencyGraph, PkgKey } from '../types.js';\n\n/** Label for the project root used as the first element of a dependency path. */\nexport function rootLabel(graph: DependencyGraph): string {\n return graph.root.version ? `${graph.root.name}@${graph.root.version}` : graph.root.name;\n}\n\n/**\n * Shortest dependency path from the project root to `targetKey`, answering\n * \"why is this package in my tree?\". Returns `[root, …, target]` or `null` if\n * the target is not reachable. Uses BFS from a virtual root connected to the\n * project's direct dependencies.\n */\nexport function shortestPath(graph: DependencyGraph, targetKey: PkgKey): PkgKey[] | null {\n if (!graph.nodes[targetKey]) return null;\n\n const VIRTUAL_ROOT = '\u0000root';\n const prev = new Map<PkgKey, PkgKey>();\n const visited = new Set<PkgKey>([VIRTUAL_ROOT]);\n const queue: PkgKey[] = [VIRTUAL_ROOT];\n\n for (let i = 0; i < queue.length; i++) {\n const current = queue[i]!;\n const neighbors =\n current === VIRTUAL_ROOT ? graph.directKeys : (graph.nodes[current]?.dependencies ?? []);\n for (const next of neighbors) {\n if (visited.has(next)) continue;\n visited.add(next);\n prev.set(next, current);\n if (next === targetKey) return reconstruct(graph, prev, targetKey, VIRTUAL_ROOT);\n queue.push(next);\n }\n }\n // Listed-but-unreferenced (e.g. a direct dep with no edges recorded).\n return [rootLabel(graph), targetKey];\n}\n\nfunction reconstruct(\n graph: DependencyGraph,\n prev: Map<PkgKey, PkgKey>,\n target: PkgKey,\n virtualRoot: string,\n): PkgKey[] {\n const path: PkgKey[] = [];\n let cursor: PkgKey | undefined = target;\n while (cursor !== undefined && cursor !== virtualRoot) {\n path.unshift(cursor);\n cursor = prev.get(cursor);\n }\n path.unshift(rootLabel(graph));\n return path;\n}\n","import semver from 'semver';\nimport type { OsvAffected, OsvEvent, OsvVulnerability } from '../types.js';\n\n/**\n * Whether `version` is affected by a single OSV `affected` entry — the heart of\n * accuracy. We honor enumerated `versions[]` exactly and walk `ranges[].events`\n * with the canonical OSV sweep. We never coerce a non-semver installed version\n * into a range match (that would manufacture false positives); such versions\n * only match via the explicit `versions[]` list.\n */\nexport function isVersionAffected(version: string, affected: OsvAffected): boolean {\n if (affected.versions?.includes(version)) return true;\n\n const installed = semver.parse(version, { loose: true });\n if (!installed) return false; // non-semver: only the enumerated list (checked above) can match\n\n for (const range of affected.ranges ?? []) {\n if (range.type === 'GIT') continue; // not applicable to npm\n if (rangeAffects(installed, range.events)) return true;\n }\n return false;\n}\n\ntype Boundary = { kind: 'introduced' | 'fixed' | 'last_affected'; version: semver.SemVer | null };\n\n/**\n * OSV event sweep: sort the introduced/fixed/last_affected boundaries ascending\n * and replay them. `introduced` opens the affected interval (`\"0\"` = from the\n * beginning), `fixed` closes it exclusively, `last_affected` closes it inclusively.\n */\nfunction rangeAffects(installed: semver.SemVer, events: OsvEvent[]): boolean {\n const boundaries: Boundary[] = [];\n for (const event of events) {\n if (event.introduced !== undefined) {\n boundaries.push({\n kind: 'introduced',\n version: event.introduced === '0' ? null : parse(event.introduced),\n });\n } else if (event.fixed !== undefined) {\n boundaries.push({ kind: 'fixed', version: parse(event.fixed) });\n } else if (event.last_affected !== undefined) {\n boundaries.push({ kind: 'last_affected', version: parse(event.last_affected) });\n }\n // `limit` events are not affected-state boundaries; ignore.\n }\n\n boundaries.sort((a, b) => {\n if (a.version === null) return b.version === null ? 0 : -1; // introduced:0 sorts first (-inf)\n if (b.version === null) return 1;\n return a.version.compare(b.version);\n });\n\n let affected = false;\n for (const boundary of boundaries) {\n if (boundary.version === null) {\n affected = true; // introduced from the beginning\n continue;\n }\n const cmp = installed.compare(boundary.version);\n switch (boundary.kind) {\n case 'introduced':\n if (cmp >= 0) affected = true;\n break;\n case 'fixed':\n if (cmp >= 0) affected = false; // fixed is exclusive\n break;\n case 'last_affected':\n if (cmp > 0) affected = false; // last_affected is inclusive\n break;\n }\n }\n return affected;\n}\n\nfunction parse(version: string): semver.SemVer | null {\n return semver.parse(version, { loose: true }) ?? semver.coerce(version);\n}\n\nexport interface VulnMatch {\n affected: boolean;\n /** Distinct `fixed` versions across the matching affected entries. */\n fixedVersions: string[];\n}\n\n/**\n * Whether a whole OSV record affects `name@version` for the npm ecosystem, and\n * which fixed versions it advertises. Withdrawn advisories never match.\n */\nexport function vulnerabilityAffects(\n name: string,\n version: string,\n vuln: OsvVulnerability,\n): VulnMatch {\n if (vuln.withdrawn) return { affected: false, fixedVersions: [] };\n\n let affected = false;\n const fixed = new Set<string>();\n for (const entry of vuln.affected ?? []) {\n const ecosystem = entry.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (entry.package?.name && entry.package.name !== name) continue;\n if (!isVersionAffected(version, entry)) continue;\n affected = true;\n for (const range of entry.ranges ?? []) {\n for (const event of range.events) {\n if (event.fixed) fixed.add(event.fixed);\n }\n }\n }\n return { affected, fixedVersions: [...fixed] };\n}\n\n/**\n * The lowest advertised fixed version strictly greater than `installed`\n * (the nearest safe upgrade), or `undefined` if none is known.\n */\nexport function nearestFix(installed: string, fixedVersions: string[]): string | undefined {\n const current = semver.parse(installed, { loose: true });\n const candidates = fixedVersions\n .map((v) => semver.parse(v, { loose: true }) ?? semver.coerce(v))\n .filter((v): v is semver.SemVer => v !== null)\n .filter((v) => (current ? v.compare(current) > 0 : true))\n .sort((a, b) => a.compare(b));\n return candidates[0]?.version;\n}\n","import type { OsvAffected, OsvReference, OsvSeverity, OsvVulnerability } from '../types.js';\n\n/** All identifiers a record is known by (its id plus aliases). */\nfunction tokensOf(vuln: OsvVulnerability): string[] {\n return [vuln.id, ...(vuln.aliases ?? [])];\n}\n\n/** Pick the human-facing id: prefer CVE, then GHSA, then the raw OSV id. */\nexport function canonicalId(ids: Iterable<string>): string {\n const list = [...ids];\n return (\n list.find((id) => id.startsWith('CVE-')) ??\n list.find((id) => id.startsWith('GHSA-')) ??\n list[0]!\n );\n}\n\n/**\n * Collapse advisories that describe the same vulnerability. Records are grouped\n * by the connected components of their shared ids/aliases (a CVE surfaced under\n * both a GHSA and an OSV id becomes one finding), then each group is merged into\n * a single representative carrying the union of aliases, references and severity.\n */\nexport function dedupeVulnerabilities(vulns: OsvVulnerability[]): OsvVulnerability[] {\n if (vulns.length <= 1) return vulns;\n\n const parent = new Map<string, string>();\n const find = (x: string): string => {\n let root = x;\n while (parent.get(root) !== undefined && parent.get(root) !== root) root = parent.get(root)!;\n parent.set(x, root);\n return root;\n };\n const union = (a: string, b: string): void => {\n parent.set(find(a), find(b));\n };\n\n for (const vuln of vulns) {\n const tokens = tokensOf(vuln);\n if (!parent.has(tokens[0]!)) parent.set(tokens[0]!, tokens[0]!);\n for (const token of tokens.slice(1)) {\n if (!parent.has(token)) parent.set(token, token);\n union(tokens[0]!, token);\n }\n }\n\n const groups = new Map<string, OsvVulnerability[]>();\n for (const vuln of vulns) {\n const root = find(vuln.id);\n const group = groups.get(root);\n if (group) group.push(vuln);\n else groups.set(root, [vuln]);\n }\n\n return [...groups.values()].map(mergeGroup);\n}\n\nfunction mergeGroup(group: OsvVulnerability[]): OsvVulnerability {\n if (group.length === 1) return group[0]!;\n\n const allIds = new Set<string>();\n const references = new Map<string, OsvReference>();\n const severity: OsvSeverity[] = [];\n const affected: OsvAffected[] = [];\n let summary: string | undefined;\n let details: string | undefined;\n let database_specific: Record<string, unknown> | undefined;\n\n for (const vuln of group) {\n for (const token of tokensOf(vuln)) allIds.add(token);\n for (const ref of vuln.references ?? []) references.set(ref.url, ref);\n for (const sev of vuln.severity ?? []) severity.push(sev);\n for (const aff of vuln.affected ?? []) affected.push(aff);\n summary ??= vuln.summary;\n details ??= vuln.details;\n database_specific ??= vuln.database_specific;\n }\n\n const id = canonicalId(allIds);\n return {\n id,\n aliases: [...allIds].filter((token) => token !== id),\n summary,\n details,\n references: [...references.values()],\n severity,\n affected,\n database_specific,\n };\n}\n","import semver from 'semver';\nimport type { DependencyGraph, Finding, OsvVulnerability, PackageManager } from '../types.js';\nimport { shortestPath } from '../graph/paths.js';\nimport { dedupeVulnerabilities } from './dedupe.js';\nimport { nearestFix, vulnerabilityAffects } from './ranges.js';\nimport { resolveSeverity } from '../score/cvss.js';\n\nexport interface FindingsOptions {\n /** Skip dev-only dependencies. */\n prodOnly?: boolean;\n /** Advisory ids/aliases to suppress. */\n ignore?: Set<string>;\n}\n\n/**\n * Turn a dependency graph plus a per-package advisory lookup into findings.\n *\n * `candidatesFor(name)` returns advisories that *name* the package; this\n * function performs the authoritative version match, de-duplicates aliased\n * advisories, scores severity and traces the dependency path. Keeping the\n * version match here (rather than trusting the source) means offline and online\n * sources share one accuracy-critical code path.\n */\nexport function buildFindings(\n graph: DependencyGraph,\n candidatesFor: (name: string) => OsvVulnerability[],\n options: FindingsOptions = {},\n): Finding[] {\n const findings: Finding[] = [];\n\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable) continue;\n if (options.prodOnly && node.scope === 'dev') continue;\n\n const candidates = candidatesFor(node.name);\n if (candidates.length === 0) continue;\n\n const matched = candidates.filter(\n (vuln) => vulnerabilityAffects(node.name, node.version, vuln).affected,\n );\n if (matched.length === 0) continue;\n\n const path = shortestPath(graph, node.key);\n for (const vuln of dedupeVulnerabilities(matched)) {\n if (isIgnored(vuln, options.ignore)) continue;\n\n const { fixedVersions } = vulnerabilityAffects(node.name, node.version, vuln);\n const sortedFixes = sortVersions(fixedVersions);\n const nearest = nearestFix(node.version, fixedVersions);\n\n findings.push({\n id: vuln.id,\n aliases: vuln.aliases ?? [],\n packageName: node.name,\n version: node.version,\n scope: node.scope,\n direct: node.direct,\n severity: resolveSeverity(vuln),\n summary: vuln.summary ?? vuln.id,\n details: vuln.details,\n references: (vuln.references ?? []).map((ref) => ref.url),\n fixedVersions: sortedFixes,\n recommendation: buildRecommendation(node.name, node.direct, nearest, graph.manager),\n dependencyPaths: path ? [path] : [],\n source: 'osv',\n });\n }\n }\n\n return findings;\n}\n\nfunction isIgnored(vuln: OsvVulnerability, ignore?: Set<string>): boolean {\n if (!ignore || ignore.size === 0) return false;\n if (ignore.has(vuln.id)) return true;\n return (vuln.aliases ?? []).some((alias) => ignore.has(alias));\n}\n\nfunction sortVersions(versions: string[]): string[] {\n return [...new Set(versions)].sort((a, b) => {\n const pa = semver.parse(a, { loose: true });\n const pb = semver.parse(b, { loose: true });\n if (pa && pb) return pa.compare(pb);\n return a.localeCompare(b);\n });\n}\n\nconst INSTALL_COMMAND: Record<PackageManager, string> = {\n npm: 'npm install',\n yarn: 'yarn add',\n pnpm: 'pnpm add',\n};\n\nfunction buildRecommendation(\n name: string,\n direct: boolean,\n nearest: string | undefined,\n manager: PackageManager,\n): string {\n if (!nearest) {\n return direct\n ? 'No fixed version is available yet. Watch the advisory, or evaluate an alternative package.'\n : 'No fixed version is available yet. Pressure the parent dependency to update, or override the version.';\n }\n if (direct) {\n return `Upgrade to ${name}@${nearest} or later (e.g. \\`${INSTALL_COMMAND[manager]} ${name}@${nearest}\\`).`;\n }\n return `Update the dependency that pulls in ${name} so it resolves to ${name}@${nearest} or later. If it cannot, force the resolution via an override.`;\n}\n","// Auto-generated from FIRST.org cvss-v4-calculator (BSD-2-Clause licensed).\n// Source: https://github.com/FIRSTdotorg/cvss-v4-calculator\n// Do not edit by hand. 270 macrovector entries.\n\nexport const CVSS4_LOOKUP: Record<string, number> = {\n '100000': 9.8,\n '100001': 9.5,\n '100010': 9.4,\n '100011': 8.7,\n '100020': 9.1,\n '100021': 8.1,\n '100100': 9.4,\n '100101': 8.9,\n '100110': 8.6,\n '100111': 7.4,\n '100120': 7.7,\n '100121': 6.4,\n '100200': 8.7,\n '100201': 7.5,\n '100210': 7.4,\n '100211': 6.3,\n '100220': 6.3,\n '100221': 4.9,\n '101000': 9.4,\n '101001': 8.9,\n '101010': 8.8,\n '101011': 7.7,\n '101020': 7.6,\n '101021': 6.7,\n '101100': 8.6,\n '101101': 7.6,\n '101110': 7.4,\n '101111': 5.8,\n '101120': 5.9,\n '101121': 5,\n '101200': 7.2,\n '101201': 5.7,\n '101210': 5.7,\n '101211': 5.2,\n '101220': 5.2,\n '101221': 2.5,\n '102001': 8.3,\n '102011': 7,\n '102021': 5.4,\n '102101': 6.5,\n '102111': 5.8,\n '102121': 2.6,\n '102201': 5.3,\n '102211': 2.1,\n '102221': 1.3,\n '110000': 9.5,\n '110001': 9,\n '110010': 8.8,\n '110011': 7.6,\n '110020': 7.6,\n '110021': 7,\n '110100': 9,\n '110101': 7.7,\n '110110': 7.5,\n '110111': 6.2,\n '110120': 6.1,\n '110121': 5.3,\n '110200': 7.7,\n '110201': 6.6,\n '110210': 6.8,\n '110211': 5.9,\n '110220': 5.2,\n '110221': 3,\n '111000': 8.9,\n '111001': 7.8,\n '111010': 7.6,\n '111011': 6.7,\n '111020': 6.2,\n '111021': 5.8,\n '111100': 7.4,\n '111101': 5.9,\n '111110': 5.7,\n '111111': 5.7,\n '111120': 4.7,\n '111121': 2.3,\n '111200': 6.1,\n '111201': 5.2,\n '111210': 5.7,\n '111211': 2.9,\n '111220': 2.4,\n '111221': 1.6,\n '112001': 7.1,\n '112011': 5.9,\n '112021': 3,\n '112101': 5.8,\n '112111': 2.6,\n '112121': 1.5,\n '112201': 2.3,\n '112211': 1.3,\n '112221': 0.6,\n '200000': 9.3,\n '200001': 8.7,\n '200010': 8.6,\n '200011': 7.2,\n '200020': 7.5,\n '200021': 5.8,\n '200100': 8.6,\n '200101': 7.4,\n '200110': 7.4,\n '200111': 6.1,\n '200120': 5.6,\n '200121': 3.4,\n '200200': 7,\n '200201': 5.4,\n '200210': 5.2,\n '200211': 4,\n '200220': 4,\n '200221': 2.2,\n '201000': 8.5,\n '201001': 7.5,\n '201010': 7.4,\n '201011': 5.5,\n '201020': 6.2,\n '201021': 5.1,\n '201100': 7.2,\n '201101': 5.7,\n '201110': 5.5,\n '201111': 4.1,\n '201120': 4.6,\n '201121': 1.9,\n '201200': 5.3,\n '201201': 3.6,\n '201210': 3.4,\n '201211': 1.9,\n '201220': 1.9,\n '201221': 0.8,\n '202001': 6.4,\n '202011': 5.1,\n '202021': 2,\n '202101': 4.7,\n '202111': 2.1,\n '202121': 1.1,\n '202201': 2.4,\n '202211': 0.9,\n '202221': 0.4,\n '210000': 8.8,\n '210001': 7.5,\n '210010': 7.3,\n '210011': 5.3,\n '210020': 6,\n '210021': 5,\n '210100': 7.3,\n '210101': 5.5,\n '210110': 5.9,\n '210111': 4,\n '210120': 4.1,\n '210121': 2,\n '210200': 5.4,\n '210201': 4.3,\n '210210': 4.5,\n '210211': 2.2,\n '210220': 2,\n '210221': 1.1,\n '211000': 7.5,\n '211001': 5.5,\n '211010': 5.8,\n '211011': 4.5,\n '211020': 4,\n '211021': 2.1,\n '211100': 6.1,\n '211101': 5.1,\n '211110': 4.8,\n '211111': 1.8,\n '211120': 2,\n '211121': 0.9,\n '211200': 4.6,\n '211201': 1.8,\n '211210': 1.7,\n '211211': 0.7,\n '211220': 0.8,\n '211221': 0.2,\n '212001': 5.3,\n '212011': 2.4,\n '212021': 1.4,\n '212101': 2.4,\n '212111': 1.2,\n '212121': 0.5,\n '212201': 1,\n '212211': 0.3,\n '212221': 0.1,\n '000000': 10,\n '000001': 9.9,\n '000010': 9.8,\n '000011': 9.5,\n '000020': 9.5,\n '000021': 9.2,\n '000100': 10,\n '000101': 9.6,\n '000110': 9.3,\n '000111': 8.7,\n '000120': 9.1,\n '000121': 8.1,\n '000200': 9.3,\n '000201': 9,\n '000210': 8.9,\n '000211': 8,\n '000220': 8.1,\n '000221': 6.8,\n '001000': 9.8,\n '001001': 9.5,\n '001010': 9.5,\n '001011': 9.2,\n '001020': 9,\n '001021': 8.4,\n '001100': 9.3,\n '001101': 9.2,\n '001110': 8.9,\n '001111': 8.1,\n '001120': 8.1,\n '001121': 6.5,\n '001200': 8.8,\n '001201': 8,\n '001210': 7.8,\n '001211': 7,\n '001220': 6.9,\n '001221': 4.8,\n '002001': 9.2,\n '002011': 8.2,\n '002021': 7.2,\n '002101': 7.9,\n '002111': 6.9,\n '002121': 5,\n '002201': 6.9,\n '002211': 5.5,\n '002221': 2.7,\n '010000': 9.9,\n '010001': 9.7,\n '010010': 9.5,\n '010011': 9.2,\n '010020': 9.2,\n '010021': 8.5,\n '010100': 9.5,\n '010101': 9.1,\n '010110': 9,\n '010111': 8.3,\n '010120': 8.4,\n '010121': 7.1,\n '010200': 9.2,\n '010201': 8.1,\n '010210': 8.2,\n '010211': 7.1,\n '010220': 7.2,\n '010221': 5.3,\n '011000': 9.5,\n '011001': 9.3,\n '011010': 9.2,\n '011011': 8.5,\n '011020': 8.5,\n '011021': 7.3,\n '011100': 9.2,\n '011101': 8.2,\n '011110': 8,\n '011111': 7.2,\n '011120': 7,\n '011121': 5.9,\n '011200': 8.4,\n '011201': 7,\n '011210': 7.1,\n '011211': 5.2,\n '011220': 5,\n '011221': 3,\n '012001': 8.6,\n '012011': 7.5,\n '012021': 5.2,\n '012101': 7.1,\n '012111': 5.2,\n '012121': 2.9,\n '012201': 6.3,\n '012211': 2.9,\n '012221': 1.7,\n};\n\nexport const CVSS4_MAX_COMPOSED: Record<string, Record<string, unknown>> = {\n eq1: {\n '0': ['AV:N/PR:N/UI:N/'],\n '1': ['AV:A/PR:N/UI:N/', 'AV:N/PR:L/UI:N/', 'AV:N/PR:N/UI:P/'],\n '2': ['AV:P/PR:N/UI:N/', 'AV:A/PR:L/UI:P/'],\n },\n eq2: {\n '0': ['AC:L/AT:N/'],\n '1': ['AC:H/AT:N/', 'AC:L/AT:P/'],\n },\n eq3: {\n '0': {\n '0': ['VC:H/VI:H/VA:H/CR:H/IR:H/AR:H/'],\n '1': ['VC:H/VI:H/VA:L/CR:M/IR:M/AR:H/', 'VC:H/VI:H/VA:H/CR:M/IR:M/AR:M/'],\n },\n '1': {\n '0': ['VC:L/VI:H/VA:H/CR:H/IR:H/AR:H/', 'VC:H/VI:L/VA:H/CR:H/IR:H/AR:H/'],\n '1': [\n 'VC:L/VI:H/VA:L/CR:H/IR:M/AR:H/',\n 'VC:L/VI:H/VA:H/CR:H/IR:M/AR:M/',\n 'VC:H/VI:L/VA:H/CR:M/IR:H/AR:M/',\n 'VC:H/VI:L/VA:L/CR:M/IR:H/AR:H/',\n 'VC:L/VI:L/VA:H/CR:H/IR:H/AR:M/',\n ],\n },\n '2': {\n '1': ['VC:L/VI:L/VA:L/CR:H/IR:H/AR:H/'],\n },\n },\n eq4: {\n '0': ['SC:H/SI:S/SA:S/'],\n '1': ['SC:H/SI:H/SA:H/'],\n '2': ['SC:L/SI:L/SA:L/'],\n },\n eq5: {\n '0': ['E:A/'],\n '1': ['E:P/'],\n '2': ['E:U/'],\n },\n};\n\nexport const CVSS4_MAX_SEVERITY: Record<string, Record<string, number | Record<string, number>>> = {\n eq1: {\n '0': 1,\n '1': 4,\n '2': 5,\n },\n eq2: {\n '0': 1,\n '1': 2,\n },\n eq3eq6: {\n '0': {\n '0': 7,\n '1': 6,\n },\n '1': {\n '0': 8,\n '1': 8,\n },\n '2': {\n '1': 10,\n },\n },\n eq4: {\n '0': 6,\n '1': 5,\n '2': 4,\n },\n eq5: {\n '0': 1,\n '1': 1,\n '2': 1,\n },\n};\n","// CVSS v4.0 base-score computation, ported faithfully from the FIRST.org\n// reference calculator (BSD-2-Clause). We compute the base score (CVSS-B):\n// threat/environmental metrics are absent and therefore default to their\n// worst case (E:A, CR/IR/AR:H), exactly as the reference does.\nimport { CVSS4_LOOKUP, CVSS4_MAX_COMPOSED, CVSS4_MAX_SEVERITY } from './cvss4-data.js';\n\nconst BASE_METRICS = ['AV', 'AC', 'AT', 'PR', 'UI', 'VC', 'VI', 'VA', 'SC', 'SI', 'SA'] as const;\n\ntype Sel = Record<string, string>;\n\nconst AV_levels: Record<string, number> = { N: 0.0, A: 0.1, L: 0.2, P: 0.3 };\nconst PR_levels: Record<string, number> = { N: 0.0, L: 0.1, H: 0.2 };\nconst UI_levels: Record<string, number> = { N: 0.0, P: 0.1, A: 0.2 };\nconst AC_levels: Record<string, number> = { L: 0.0, H: 0.1 };\nconst AT_levels: Record<string, number> = { N: 0.0, P: 0.1 };\nconst VC_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst VI_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst VA_levels: Record<string, number> = { H: 0.0, L: 0.1, N: 0.2 };\nconst SC_levels: Record<string, number> = { H: 0.1, L: 0.2, N: 0.3 };\nconst SI_levels: Record<string, number> = { S: 0.0, H: 0.1, L: 0.2, N: 0.3 };\nconst SA_levels: Record<string, number> = { S: 0.0, H: 0.1, L: 0.2, N: 0.3 };\nconst CR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\nconst IR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\nconst AR_levels: Record<string, number> = { H: 0.0, M: 0.1, L: 0.2 };\n\n/** Compute the CVSS v4.0 base score from a vector string, or null if invalid. */\nexport function scoreV4(vector: string): number | null {\n const sel = parseV4(vector);\n if (!sel) return null;\n const macro = macroVector(sel);\n if (CVSS4_LOOKUP[macro] === undefined) return null;\n return cvssScore(sel, macro);\n}\n\nfunction parseV4(vector: string): Sel | null {\n const parts = vector.split('/');\n if (parts[0] !== 'CVSS:4.0') return null;\n const sel: Sel = {};\n for (const part of parts.slice(1)) {\n const [k, v] = part.split(':');\n if (k && v) sel[k] = v;\n }\n for (const metric of BASE_METRICS) if (!(metric in sel)) return null;\n for (const metric of ['E', 'CR', 'IR', 'AR']) if (!(metric in sel)) sel[metric] = 'X';\n return sel;\n}\n\n/** Effective metric value, applying modified-metric and worst-case-default rules. */\nfunction m(sel: Sel, metric: string): string {\n const selected = sel[metric];\n if (metric === 'E' && selected === 'X') return 'A';\n if ((metric === 'CR' || metric === 'IR' || metric === 'AR') && selected === 'X') return 'H';\n const modified = sel[`M${metric}`];\n if (modified !== undefined && modified !== 'X') return modified;\n return selected ?? '';\n}\n\nfunction macroVector(sel: Sel): string {\n const av = m(sel, 'AV');\n const pr = m(sel, 'PR');\n const ui = m(sel, 'UI');\n let eq1 = '2';\n if (av === 'N' && pr === 'N' && ui === 'N') eq1 = '0';\n else if ((av === 'N' || pr === 'N' || ui === 'N') && av !== 'P') eq1 = '1';\n\n const eq2 = m(sel, 'AC') === 'L' && m(sel, 'AT') === 'N' ? '0' : '1';\n\n const vc = m(sel, 'VC');\n const vi = m(sel, 'VI');\n const va = m(sel, 'VA');\n let eq3 = '2';\n if (vc === 'H' && vi === 'H') eq3 = '0';\n else if (vc === 'H' || vi === 'H' || va === 'H') eq3 = '1';\n\n const msi = m(sel, 'MSI');\n const msa = m(sel, 'MSA');\n let eq4 = '2';\n if (msi === 'S' || msa === 'S') eq4 = '0';\n else if (m(sel, 'SC') === 'H' || m(sel, 'SI') === 'H' || m(sel, 'SA') === 'H') eq4 = '1';\n\n const e = m(sel, 'E');\n const eq5 = e === 'A' ? '0' : e === 'P' ? '1' : '2';\n\n const cr = m(sel, 'CR');\n const ir = m(sel, 'IR');\n const ar = m(sel, 'AR');\n const eq6 =\n (cr === 'H' && vc === 'H') || (ir === 'H' && vi === 'H') || (ar === 'H' && va === 'H')\n ? '0'\n : '1';\n\n return `${eq1}${eq2}${eq3}${eq4}${eq5}${eq6}`;\n}\n\nfunction lvl(map: Record<string, number>, key: string): number {\n return map[key] ?? 0;\n}\n\nfunction eqMaxes(macro: string, eq: number): string[] {\n const group = CVSS4_MAX_COMPOSED[`eq${eq}`] as Record<string, string[]>;\n return group[macro[eq - 1]!] ?? [];\n}\n\nfunction extractValueMetric(metric: string, str: string): string {\n const start = str.indexOf(metric) + metric.length + 1;\n const rest = str.slice(start);\n const slash = rest.indexOf('/');\n return slash > 0 ? rest.substring(0, slash) : rest;\n}\n\nfunction cvssScore(sel: Sel, macro: string): number {\n if (BASE_METRICS.slice(5).every((metric) => m(sel, metric) === 'N')) return 0; // VC..SA all None\n\n let value = CVSS4_LOOKUP[macro]!;\n\n const eq1 = Number(macro[0]);\n const eq3 = Number(macro[2]);\n const eq6 = Number(macro[5]);\n\n const lower = (parts: [number, number, number, number, number, number]): number =>\n CVSS4_LOOKUP[parts.join('')] ?? NaN;\n\n const d = macro.split('').map(Number) as [number, number, number, number, number, number];\n const scoreEq1Lower = lower([d[0] + 1, d[1], d[2], d[3], d[4], d[5]]);\n const scoreEq2Lower = lower([d[0], d[1] + 1, d[2], d[3], d[4], d[5]]);\n\n let scoreEq3Eq6Lower: number;\n if (eq3 === 1 && eq6 === 1) scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n else if (eq3 === 0 && eq6 === 1)\n scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n else if (eq3 === 1 && eq6 === 0)\n scoreEq3Eq6Lower = lower([d[0], d[1], d[2], d[3], d[4], d[5] + 1]);\n else if (eq3 === 0 && eq6 === 0) {\n const left = lower([d[0], d[1], d[2], d[3], d[4], d[5] + 1]);\n const right = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5]]);\n scoreEq3Eq6Lower = left > right ? left : right;\n } else scoreEq3Eq6Lower = lower([d[0], d[1], d[2] + 1, d[3], d[4], d[5] + 1]);\n\n const scoreEq4Lower = lower([d[0], d[1], d[2], d[3] + 1, d[4], d[5]]);\n const scoreEq5Lower = lower([d[0], d[1], d[2], d[3], d[4] + 1, d[5]]);\n\n const eq1Maxes = eqMaxes(macro, 1);\n const eq2Maxes = eqMaxes(macro, 2);\n const eq3Eq6Maxes = (CVSS4_MAX_COMPOSED.eq3 as Record<string, Record<string, string[]>>)[\n macro[2]!\n ]![macro[5]!]!;\n const eq4Maxes = eqMaxes(macro, 4);\n const eq5Maxes = eqMaxes(macro, 5);\n\n const maxVectors: string[] = [];\n for (const a of eq1Maxes)\n for (const b of eq2Maxes)\n for (const c of eq3Eq6Maxes)\n for (const e of eq4Maxes) for (const f of eq5Maxes) maxVectors.push(a + b + c + e + f);\n\n let sdAV = 0,\n sdPR = 0,\n sdUI = 0,\n sdAC = 0,\n sdAT = 0,\n sdVC = 0,\n sdVI = 0,\n sdVA = 0,\n sdSC = 0,\n sdSI = 0,\n sdSA = 0,\n sdCR = 0,\n sdIR = 0,\n sdAR = 0;\n\n for (const maxVector of maxVectors) {\n sdAV = lvl(AV_levels, m(sel, 'AV')) - lvl(AV_levels, extractValueMetric('AV', maxVector));\n sdPR = lvl(PR_levels, m(sel, 'PR')) - lvl(PR_levels, extractValueMetric('PR', maxVector));\n sdUI = lvl(UI_levels, m(sel, 'UI')) - lvl(UI_levels, extractValueMetric('UI', maxVector));\n sdAC = lvl(AC_levels, m(sel, 'AC')) - lvl(AC_levels, extractValueMetric('AC', maxVector));\n sdAT = lvl(AT_levels, m(sel, 'AT')) - lvl(AT_levels, extractValueMetric('AT', maxVector));\n sdVC = lvl(VC_levels, m(sel, 'VC')) - lvl(VC_levels, extractValueMetric('VC', maxVector));\n sdVI = lvl(VI_levels, m(sel, 'VI')) - lvl(VI_levels, extractValueMetric('VI', maxVector));\n sdVA = lvl(VA_levels, m(sel, 'VA')) - lvl(VA_levels, extractValueMetric('VA', maxVector));\n sdSC = lvl(SC_levels, m(sel, 'SC')) - lvl(SC_levels, extractValueMetric('SC', maxVector));\n sdSI = lvl(SI_levels, m(sel, 'SI')) - lvl(SI_levels, extractValueMetric('SI', maxVector));\n sdSA = lvl(SA_levels, m(sel, 'SA')) - lvl(SA_levels, extractValueMetric('SA', maxVector));\n sdCR = lvl(CR_levels, m(sel, 'CR')) - lvl(CR_levels, extractValueMetric('CR', maxVector));\n sdIR = lvl(IR_levels, m(sel, 'IR')) - lvl(IR_levels, extractValueMetric('IR', maxVector));\n sdAR = lvl(AR_levels, m(sel, 'AR')) - lvl(AR_levels, extractValueMetric('AR', maxVector));\n\n const distances = [\n sdAV,\n sdPR,\n sdUI,\n sdAC,\n sdAT,\n sdVC,\n sdVI,\n sdVA,\n sdSC,\n sdSI,\n sdSA,\n sdCR,\n sdIR,\n sdAR,\n ];\n if (distances.some((x) => x < 0)) continue;\n break;\n }\n\n const csdEq1 = sdAV + sdPR + sdUI;\n const csdEq2 = sdAC + sdAT;\n const csdEq3Eq6 = sdVC + sdVI + sdVA + sdCR + sdIR + sdAR;\n const csdEq4 = sdSC + sdSI + sdSA;\n\n const step = 0.1;\n const availEq1 = value - scoreEq1Lower;\n const availEq2 = value - scoreEq2Lower;\n const availEq3Eq6 = value - scoreEq3Eq6Lower;\n const availEq4 = value - scoreEq4Lower;\n const availEq5 = value - scoreEq5Lower;\n\n const maxSev = CVSS4_MAX_SEVERITY;\n const maxSevEq1 = (maxSev.eq1 as Record<string, number>)[String(eq1)]! * step;\n const maxSevEq2 = (maxSev.eq2 as Record<string, number>)[macro[1]!]! * step;\n const maxSevEq3Eq6 =\n (maxSev.eq3eq6 as Record<string, Record<string, number>>)[String(eq3)]![String(eq6)]! * step;\n const maxSevEq4 = (maxSev.eq4 as Record<string, number>)[macro[3]!]! * step;\n\n let n = 0;\n let nsEq1 = 0,\n nsEq2 = 0,\n nsEq3Eq6 = 0,\n nsEq4 = 0;\n if (!Number.isNaN(availEq1)) {\n n++;\n nsEq1 = availEq1 * (csdEq1 / maxSevEq1);\n }\n if (!Number.isNaN(availEq2)) {\n n++;\n nsEq2 = availEq2 * (csdEq2 / maxSevEq2);\n }\n if (!Number.isNaN(availEq3Eq6)) {\n n++;\n nsEq3Eq6 = availEq3Eq6 * (csdEq3Eq6 / maxSevEq3Eq6);\n }\n if (!Number.isNaN(availEq4)) {\n n++;\n nsEq4 = availEq4 * (csdEq4 / maxSevEq4);\n }\n if (!Number.isNaN(availEq5)) {\n n++; // eq5 proportion is always 0\n }\n\n const meanDistance = n === 0 ? 0 : (nsEq1 + nsEq2 + nsEq3Eq6 + nsEq4) / n;\n value -= meanDistance;\n if (value < 0) value = 0;\n if (value > 10) value = 10;\n return Math.round(value * 10) / 10;\n}\n","import type { OsvVulnerability, Severity, SeverityInfo } from '../types.js';\nimport { scoreV4 } from './cvss4.js';\n\n// CVSS base-score computation from a vector string. v3.0/v3.1 are computed from\n// the public formula; v4.0 is computed via the FIRST.org reference algorithm\n// (see cvss4.ts). Both feed the same severity-band mapping.\n\nconst AV: Record<string, number> = { N: 0.85, A: 0.62, L: 0.55, P: 0.2 };\nconst AC: Record<string, number> = { L: 0.77, H: 0.44 };\nconst UI: Record<string, number> = { N: 0.85, R: 0.62 };\nconst PR_UNCHANGED: Record<string, number> = { N: 0.85, L: 0.62, H: 0.27 };\nconst PR_CHANGED: Record<string, number> = { N: 0.85, L: 0.68, H: 0.5 };\nconst CIA: Record<string, number> = { H: 0.56, L: 0.22, N: 0 };\n\nexport interface CvssResult {\n score: number;\n level: Severity;\n /** e.g. `CVSS:3.1`. */\n version: string;\n}\n\n/** Map a numeric CVSS base score to its qualitative band. */\nexport function levelFromScore(score: number): Severity {\n if (score <= 0) return 'none';\n if (score < 4) return 'low';\n if (score < 7) return 'medium';\n if (score < 9) return 'high';\n return 'critical';\n}\n\n/** Map a qualitative label (GHSA-style) to a {@link Severity}. */\nexport function levelFromLabel(label: string): Severity {\n switch (label.trim().toUpperCase()) {\n case 'CRITICAL':\n return 'critical';\n case 'HIGH':\n return 'high';\n case 'MODERATE':\n case 'MEDIUM':\n return 'medium';\n case 'LOW':\n return 'low';\n case 'NONE':\n return 'none';\n default:\n return 'unknown';\n }\n}\n\n/** CVSS 3.1 Roundup: smallest one-decimal number ≥ input (integer-math, float-safe). */\nfunction roundUp(input: number): number {\n const scaled = Math.round(input * 100000);\n if (scaled % 10000 === 0) return scaled / 100000;\n return (Math.floor(scaled / 10000) + 1) / 10;\n}\n\n/** Compute a base score from a CVSS v3.0/v3.1/v4.0 vector string, or null if unparseable. */\nexport function scoreFromVector(vector: string): CvssResult | null {\n const parts = vector.split('/');\n const header = parts[0] ?? '';\n if (header === 'CVSS:4.0') {\n const score = scoreV4(vector);\n return score === null ? null : { score, level: levelFromScore(score), version: header };\n }\n if (!/^CVSS:3\\.[01]$/.test(header)) return null;\n\n const m: Record<string, string> = {};\n for (const part of parts.slice(1)) {\n const [k, v] = part.split(':');\n if (k && v) m[k] = v;\n }\n const av = AV[m.AV ?? ''];\n const ac = AC[m.AC ?? ''];\n const ui = UI[m.UI ?? ''];\n const scopeChanged = m.S === 'C';\n const pr = (scopeChanged ? PR_CHANGED : PR_UNCHANGED)[m.PR ?? ''];\n const c = CIA[m.C ?? ''];\n const i = CIA[m.I ?? ''];\n const a = CIA[m.A ?? ''];\n if ([av, ac, ui, pr, c, i, a].some((x) => x === undefined)) return null;\n\n const iss = 1 - (1 - c!) * (1 - i!) * (1 - a!);\n const impact = scopeChanged ? 7.52 * (iss - 0.029) - 3.25 * Math.pow(iss - 0.02, 15) : 6.42 * iss;\n const exploitability = 8.22 * av! * ac! * pr! * ui!;\n\n let score: number;\n if (impact <= 0) score = 0;\n else if (scopeChanged) score = roundUp(Math.min(1.08 * (impact + exploitability), 10));\n else score = roundUp(Math.min(impact + exploitability, 10));\n\n return { score, level: levelFromScore(score), version: header };\n}\n\n/**\n * Resolve the severity of a whole advisory, with provenance. Prefers a computed\n * CVSS v3 score (highest across all vectors), then the advisory's qualitative\n * `database_specific.severity`, then `unknown`.\n */\nexport function resolveSeverity(vuln: OsvVulnerability): SeverityInfo {\n const vectors: string[] = [];\n for (const s of vuln.severity ?? []) if (s.score) vectors.push(s.score);\n for (const affected of vuln.affected ?? []) {\n for (const s of affected.severity ?? []) if (s.score) vectors.push(s.score);\n }\n\n let best: CvssResult | null = null;\n for (const vector of vectors) {\n const result = scoreFromVector(vector);\n if (result && (!best || result.score > best.score)) best = result;\n }\n if (best) {\n return {\n level: best.level,\n score: best.score,\n vector: vectorFor(best, vectors),\n cvssVersion: best.version,\n source: 'cvss',\n };\n }\n\n const label = qualitativeLabel(vuln);\n if (label) return { level: levelFromLabel(label), source: 'database' };\n\n return { level: 'unknown', source: 'unknown' };\n}\n\nfunction vectorFor(best: CvssResult, vectors: string[]): string | undefined {\n return vectors.find((v) => v.startsWith(best.version));\n}\n\nfunction qualitativeLabel(vuln: OsvVulnerability): string | undefined {\n const fromRecord = (db: Record<string, unknown> | undefined): string | undefined => {\n const sev = db?.severity;\n return typeof sev === 'string' ? sev : undefined;\n };\n const top = fromRecord(vuln.database_specific);\n if (top) return top;\n for (const affected of vuln.affected ?? []) {\n const label = fromRecord(affected.database_specific);\n if (label) return label;\n }\n return undefined;\n}\n","import type { OsvVulnerability } from '../types.js';\n\n/**\n * In-memory index of OSV advisories for the npm ecosystem, keyed by package\n * name. Populated either from the downloaded offline DB zip (M3) or from online\n * API responses, then queried per installed package during a scan.\n *\n * Withdrawn advisories are dropped on insert so they can never produce a finding.\n */\nexport class OsvDatabase {\n private readonly byName = new Map<string, OsvVulnerability[]>();\n private readonly ids = new Set<string>();\n\n add(vuln: OsvVulnerability): void {\n if (vuln.withdrawn) return;\n if (this.ids.has(vuln.id)) return;\n this.ids.add(vuln.id);\n\n const names = new Set<string>();\n for (const affected of vuln.affected ?? []) {\n const ecosystem = affected.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (affected.package?.name) names.add(affected.package.name);\n }\n for (const name of names) {\n const list = this.byName.get(name);\n if (list) list.push(vuln);\n else this.byName.set(name, [vuln]);\n }\n }\n\n addAll(vulns: Iterable<OsvVulnerability>): void {\n for (const vuln of vulns) this.add(vuln);\n }\n\n /** Candidate advisories that name `packageName` (still need a version check). */\n vulnerabilitiesFor(packageName: string): OsvVulnerability[] {\n return this.byName.get(packageName) ?? [];\n }\n\n /** Number of distinct advisories indexed. */\n get size(): number {\n return this.ids.size;\n }\n}\n","import { resolve } from 'node:path';\nimport type {\n DependencyGraph,\n Finding,\n ScanOptions,\n ScanResult,\n ScanSummary,\n Severity,\n UnscannablePackage,\n} from './types.js';\nimport { SEVERITY_RANK, severityAtLeast } from './types.js';\nimport { loadDependencyGraph } from './lockfiles/normalize.js';\nimport { detectLockfile } from './lockfiles/detect.js';\nimport { buildFindings } from './match/findings.js';\nimport { resolveCacheDir } from './cache/paths.js';\nimport { createSource } from './osv/source.js';\nimport type { VulnSource } from './osv/source.js';\nimport type { PackageRef } from './osv/client.js';\n\nexport const TOOL = { name: 'lockhawk', version: '0.1.0' } as const;\n\n/**\n * Run a full scan: load and normalize the lockfile, query OSV for the unique\n * scannable packages, build findings, and assemble a {@link ScanResult}.\n *\n * A `source` can be injected (used by tests and by the CLI once it has resolved\n * options); otherwise one is created from `options.mode`.\n */\nexport async function scan(options: ScanOptions = {}, source?: VulnSource): Promise<ScanResult> {\n const start = Date.now();\n const dir = resolve(options.path ?? '.');\n const graph = loadDependencyGraph(dir);\n const detected = detectLockfile(dir);\n\n const scannable = uniqueScannablePackages(graph, options.prodOnly);\n const cacheDir = resolveCacheDir(options.cacheDir);\n const src =\n source ??\n createSource(options.mode ?? 'auto', {\n cacheDir,\n concurrency: options.concurrency,\n noCache: options.noCache,\n cacheTtlHours: options.cacheTtlHours,\n strictNetwork: options.strictNetwork,\n });\n\n options.onProgress?.('Checking dependencies against OSV.dev…');\n const resolved = await src.prepare(scannable);\n\n let findings = buildFindings(graph, resolved.candidatesFor, {\n prodOnly: options.prodOnly,\n ignore: options.ignore && options.ignore.length ? new Set(options.ignore) : undefined,\n });\n if (options.severityThreshold && options.severityThreshold !== 'none') {\n findings = findings.filter((f) =>\n severityAtLeast(f.severity.level, options.severityThreshold!),\n );\n }\n findings.sort(bySeverityThenName);\n\n const unscannable = unscannablePackages(graph);\n\n return {\n schemaVersion: 1,\n tool: { ...TOOL },\n scannedAt: new Date(start).toISOString(),\n target: {\n path: dir,\n manager: graph.manager,\n lockfile: detected?.filename ?? '',\n root: graph.root,\n },\n database: resolved.database,\n summary: summarize(findings),\n stats: {\n totalPackages: Object.keys(graph.nodes).length,\n uniquePackages: scannable.length,\n directDependencies: graph.directKeys.length,\n unscannable: unscannable.length,\n durationMs: Date.now() - start,\n },\n findings,\n unscannable,\n };\n}\n\n/** Unique `name@version` packages worth querying (skips local/unscannable, optionally dev). */\nexport function uniqueScannablePackages(graph: DependencyGraph, prodOnly?: boolean): PackageRef[] {\n const seen = new Set<string>();\n const out: PackageRef[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable) continue;\n if (prodOnly && node.scope === 'dev') continue;\n if (seen.has(node.key)) continue;\n seen.add(node.key);\n out.push({ name: node.name, version: node.version });\n }\n return out;\n}\n\nfunction unscannablePackages(graph: DependencyGraph): UnscannablePackage[] {\n const out: UnscannablePackage[] = [];\n for (const node of Object.values(graph.nodes)) {\n if (node.unscannable)\n out.push({ name: node.name, version: node.version, reason: node.unscannable.reason });\n }\n return out;\n}\n\nfunction summarize(findings: Finding[]): ScanSummary {\n const summary: ScanSummary = {\n total: findings.length,\n critical: 0,\n high: 0,\n medium: 0,\n low: 0,\n unknown: 0,\n none: 0,\n vulnerablePackages: 0,\n fixable: 0,\n };\n const vulnerable = new Set<string>();\n for (const f of findings) {\n summary[f.severity.level] += 1;\n vulnerable.add(`${f.packageName}@${f.version}`);\n if (f.fixedVersions.length > 0) summary.fixable += 1;\n }\n summary.vulnerablePackages = vulnerable.size;\n return summary;\n}\n\nfunction bySeverityThenName(a: Finding, b: Finding): number {\n const rank = SEVERITY_RANK[b.severity.level] - SEVERITY_RANK[a.severity.level];\n if (rank !== 0) return rank;\n return a.packageName.localeCompare(b.packageName);\n}\n\n/** Lowest severity that should trigger a non-zero exit given a `--fail-on` threshold. */\nexport function shouldFail(summary: ScanSummary, failOn: Severity): boolean {\n const levels: Severity[] = ['critical', 'high', 'medium', 'low', 'unknown'];\n return levels.some(\n (level) => SEVERITY_RANK[level] >= SEVERITY_RANK[failOn] && summary[level] > 0,\n );\n}\n","import { join } from 'node:path';\nimport envPaths from 'env-paths';\n\n/**\n * Resolve the on-disk cache directory, honoring (in priority order):\n * 1. an explicit override (the `--cache-dir` flag)\n * 2. the `LOCKHAWK_CACHE` environment variable\n * 3. the OS-conventional cache location (via env-paths)\n */\nexport function resolveCacheDir(override?: string): string {\n if (override) return override;\n if (process.env.LOCKHAWK_CACHE) return process.env.LOCKHAWK_CACHE;\n return envPaths('lockhawk', { suffix: '' }).cache;\n}\n\n/** Directory holding the offline OSV database for the npm ecosystem. */\nexport function offlineDbDir(cacheDir: string): string {\n return join(cacheDir, 'osv-db', 'npm');\n}\n\n/** Number of advisory shard buckets — bounds the on-disk file count for CI caching. */\nexport const SHARD_BUCKETS = 4096;\n\n/** FNV-1a hash → stable shard bucket for a package name. */\nexport function shardBucket(packageName: string): number {\n let hash = 0x811c9dc5;\n for (let i = 0; i < packageName.length; i++) {\n hash ^= packageName.charCodeAt(i);\n hash = Math.imul(hash, 0x01000193);\n }\n return (hash >>> 0) % SHARD_BUCKETS;\n}\n\n/** Path to the advisory shard file that holds a given package's advisories. */\nexport function shardPath(cacheDir: string, packageName: string): string {\n return join(offlineDbDir(cacheDir), 'by-name', `${shardBucket(packageName)}.json`);\n}\n\n/** Metadata file describing offline-DB freshness. */\nexport function offlineMetaPath(cacheDir: string): string {\n return join(offlineDbDir(cacheDir), 'meta.json');\n}\n\n/** Per-id online query cache file. */\nexport function queryCachePath(cacheDir: string, id: string): string {\n return join(cacheDir, 'query-cache', `${encodeURIComponent(id)}.json`);\n}\n","import { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport { dirname } from 'node:path';\nimport pLimit from 'p-limit';\nimport pRetry, { AbortError } from 'p-retry';\nimport type { OsvVulnerability } from '../types.js';\nimport { queryCachePath } from '../cache/paths.js';\n\nconst OSV_API = 'https://api.osv.dev/v1';\nconst BATCH_SIZE = 1000;\n\nexport interface PackageRef {\n name: string;\n version: string;\n}\n\nexport interface OnlineClientOptions {\n cacheDir: string;\n concurrency?: number;\n noCache?: boolean;\n cacheTtlHours?: number;\n retries?: number;\n}\n\ninterface BatchResult {\n vulns?: { id: string; modified?: string }[];\n next_page_token?: string;\n}\n\n/**\n * Online OSV source. Uses the batch endpoint (which returns only matched ids)\n * then hydrates each unique id to a full record — caching records by id so\n * repeat scans do no network work. All matching is re-validated downstream by\n * `buildFindings`, so this client only has to gather candidate records.\n */\nexport class OsvClient {\n private readonly limit;\n\n constructor(private readonly opts: OnlineClientOptions) {\n this.limit = pLimit(opts.concurrency ?? 5);\n }\n\n /** Fetch advisories affecting the given packages, keyed by package name. */\n async fetchAdvisories(packages: PackageRef[]): Promise<Map<string, OsvVulnerability[]>> {\n const unique = dedupePackages(packages);\n const idsByName = await this.queryBatch(unique);\n\n const allIds = new Set<string>();\n for (const ids of idsByName.values()) for (const id of ids) allIds.add(id);\n\n const records = await this.hydrate([...allIds]);\n\n const byName = new Map<string, OsvVulnerability[]>();\n for (const [name, ids] of idsByName) {\n const list: OsvVulnerability[] = [];\n for (const id of ids) {\n const record = records.get(id);\n if (record) list.push(record);\n }\n if (list.length) byName.set(name, list);\n }\n return byName;\n }\n\n private async queryBatch(packages: PackageRef[]): Promise<Map<string, Set<string>>> {\n const idsByName = new Map<string, Set<string>>();\n\n for (let i = 0; i < packages.length; i += BATCH_SIZE) {\n const chunk = packages.slice(i, i + BATCH_SIZE);\n const body = {\n queries: chunk.map((p) => ({\n package: { name: p.name, ecosystem: 'npm' },\n version: p.version,\n })),\n };\n const data = await this.request<{ results: BatchResult[] }>(`${OSV_API}/querybatch`, body);\n\n for (let j = 0; j < chunk.length; j++) {\n const pkg = chunk[j]!;\n const result = data.results[j];\n if (!result) continue;\n const set = idsByName.get(pkg.name) ?? new Set<string>();\n for (const vuln of result.vulns ?? []) set.add(vuln.id);\n // Pagination is rare for a single npm package; pull remaining pages if present.\n let pageToken = result.next_page_token;\n while (pageToken) {\n const page = await this.request<BatchResult>(`${OSV_API}/query`, {\n package: { name: pkg.name, ecosystem: 'npm' },\n version: pkg.version,\n page_token: pageToken,\n });\n for (const vuln of page.vulns ?? []) set.add(vuln.id);\n pageToken = page.next_page_token;\n }\n if (set.size) idsByName.set(pkg.name, set);\n }\n }\n return idsByName;\n }\n\n private async hydrate(ids: string[]): Promise<Map<string, OsvVulnerability>> {\n const records = new Map<string, OsvVulnerability>();\n await Promise.all(\n ids.map((id) =>\n this.limit(async () => {\n const record = await this.getVulnerability(id);\n if (record) records.set(id, record);\n }),\n ),\n );\n return records;\n }\n\n private async getVulnerability(id: string): Promise<OsvVulnerability | undefined> {\n const cached = await this.readCache(id);\n if (cached) return cached;\n const record = await this.request<OsvVulnerability>(\n `${OSV_API}/vulns/${encodeURIComponent(id)}`,\n );\n await this.writeCache(id, record);\n return record;\n }\n\n private async request<T>(url: string, body?: unknown): Promise<T> {\n const retries = this.opts.retries ?? 3;\n return pRetry(\n async () => {\n const res = await fetch(url, {\n method: body ? 'POST' : 'GET',\n headers: body ? { 'content-type': 'application/json' } : undefined,\n body: body ? JSON.stringify(body) : undefined,\n });\n if (res.ok) return (await res.json()) as T;\n if (res.status === 429 || res.status >= 500) {\n throw new Error(`OSV ${res.status} for ${url}`); // retryable\n }\n throw new AbortError(`OSV ${res.status} for ${url}`); // client error: do not retry\n },\n { retries },\n );\n }\n\n private async readCache(id: string): Promise<OsvVulnerability | undefined> {\n if (this.opts.noCache) return undefined;\n try {\n const parsed = JSON.parse(await readFile(queryCachePath(this.opts.cacheDir, id), 'utf8')) as {\n fetchedAt: number;\n vuln: OsvVulnerability;\n };\n const ttlMs = (this.opts.cacheTtlHours ?? 24) * 3_600_000;\n if (Date.now() - parsed.fetchedAt > ttlMs) return undefined;\n return parsed.vuln;\n } catch {\n return undefined;\n }\n }\n\n private async writeCache(id: string, vuln: OsvVulnerability): Promise<void> {\n if (this.opts.noCache) return;\n try {\n const path = queryCachePath(this.opts.cacheDir, id);\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, JSON.stringify({ fetchedAt: Date.now(), vuln }));\n } catch {\n // Cache write failures are non-fatal.\n }\n }\n}\n\nfunction dedupePackages(packages: PackageRef[]): PackageRef[] {\n const seen = new Set<string>();\n const out: PackageRef[] = [];\n for (const p of packages) {\n const key = `${p.name}@${p.version}`;\n if (!seen.has(key)) {\n seen.add(key);\n out.push(p);\n }\n }\n return out;\n}\n","import { createWriteStream } from 'node:fs';\nimport { mkdir, mkdtemp, readFile, rm, writeFile } from 'node:fs/promises';\nimport { tmpdir } from 'node:os';\nimport { join } from 'node:path';\nimport { Readable } from 'node:stream';\nimport { pipeline } from 'node:stream/promises';\nimport { gunzipSync, gzipSync } from 'node:zlib';\nimport yauzl from 'yauzl';\nimport type { OsvVulnerability } from '../types.js';\nimport { offlineDbDir, offlineMetaPath, shardBucket } from '../cache/paths.js';\n\nconst OSV_NPM_ZIP_URL = 'https://storage.googleapis.com/osv-vulnerabilities/npm/all.zip';\n\n// OSV advisory JSON files are small (well under 1 MiB). Cap per-entry size so a\n// malformed or hostile archive cannot exhaust memory. The download is from the\n// fixed OSV HTTPS bucket, so this is defense-in-depth, not the primary control.\nconst MAX_ENTRY_BYTES = 8 * 1024 * 1024;\n\nexport interface OfflineMeta {\n ecosystem: 'npm';\n source: string;\n /** ISO timestamp of the last successful refresh/check. */\n lastUpdated: string;\n recordCount: number;\n packageCount: number;\n etag?: string;\n lastModified?: string;\n}\n\nexport interface UpdateResult {\n status: 'updated' | 'unchanged';\n meta: OfflineMeta;\n}\n\nexport class OfflineDbMissingError extends Error {\n constructor() {\n super('No offline OSV database found. Run `lockhawk db update` first.');\n this.name = 'OfflineDbMissingError';\n }\n}\n\n// The cached ETag / Last-Modified are read back from a local file and echoed to\n// OSV as conditional-request headers. They originate from OSV's own responses\n// and the URL is fixed, so this is defense-in-depth: constrain each to its RFC\n// 9110 grammar so a tampered meta file can't inject arbitrary header content.\nconst IMF_FIXDATE = /^[A-Za-z]{3}, \\d{2} [A-Za-z]{3} \\d{4} \\d{2}:\\d{2}:\\d{2} GMT$/;\n// entity-tag = [ \"W/\" ] DQUOTE *( %x21 / %x23-7E ) DQUOTE (excludes DQUOTE/CTLs)\nconst ENTITY_TAG = /^(?:W\\/)?\"[\\x21\\x23-\\x7e]*\"$/;\n\n/** A well-formed HTTP `Last-Modified` value (IMF-fixdate), else `undefined`. */\nexport function sanitizeHttpDate(value: string | undefined): string | undefined {\n return value && IMF_FIXDATE.test(value) ? value : undefined;\n}\n\n/** A well-formed entity-tag (strong or weak), else `undefined`. */\nexport function sanitizeETag(value: string | undefined): string | undefined {\n return value && ENTITY_TAG.test(value) ? value : undefined;\n}\n\n/** Read the offline DB metadata, or `undefined` if it has never been built. */\nexport async function readOfflineMeta(cacheDir: string): Promise<OfflineMeta | undefined> {\n try {\n return JSON.parse(await readFile(offlineMetaPath(cacheDir), 'utf8')) as OfflineMeta;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Download (or conditionally refresh) the npm OSV database and rebuild the\n * per-package shards. Uses ETag / Last-Modified so an unchanged DB costs a\n * single 304 and no rewrite. `nowIso` is injected so callers stamp the time\n * (the engine never calls Date.now itself in pure paths).\n */\nexport async function updateOfflineDatabase(opts: {\n cacheDir: string;\n nowIso: string;\n force?: boolean;\n onProgress?: (message: string) => void;\n}): Promise<UpdateResult> {\n const { cacheDir, nowIso, force, onProgress } = opts;\n const dir = offlineDbDir(cacheDir);\n await mkdir(dir, { recursive: true });\n\n const previous = force ? undefined : await readOfflineMeta(cacheDir);\n const headers: Record<string, string> = {};\n const etag = sanitizeETag(previous?.etag);\n const lastModified = sanitizeHttpDate(previous?.lastModified);\n if (etag) headers['If-None-Match'] = etag;\n if (lastModified) headers['If-Modified-Since'] = lastModified;\n\n onProgress?.('Fetching npm advisory database from OSV.dev…');\n const res = await fetch(OSV_NPM_ZIP_URL, { headers });\n\n if (res.status === 304 && previous) {\n const meta: OfflineMeta = { ...previous, lastUpdated: nowIso };\n await writeFile(offlineMetaPath(cacheDir), JSON.stringify(meta, null, 2));\n return { status: 'unchanged', meta };\n }\n if (!res.ok || !res.body) {\n throw new Error(`OSV database download failed: HTTP ${res.status}`);\n }\n\n // Extract from a private temp dir (not a predictable shared path), and always\n // clean it up — including on the error path.\n const tmp = await mkdtemp(join(tmpdir(), 'lockhawk-osv-'));\n const zipPath = join(tmp, 'all.zip');\n let records: OsvVulnerability[];\n try {\n await pipeline(\n Readable.fromWeb(res.body as Parameters<typeof Readable.fromWeb>[0]),\n createWriteStream(zipPath),\n );\n onProgress?.('Extracting advisories…');\n records = await readZipRecords(zipPath);\n } finally {\n await rm(tmp, { recursive: true, force: true });\n }\n\n onProgress?.('Building package index…');\n const byName = groupByPackage(records);\n await writeShards(cacheDir, byName);\n\n const meta: OfflineMeta = {\n ecosystem: 'npm',\n source: 'osv.dev',\n lastUpdated: nowIso,\n recordCount: records.length,\n packageCount: byName.size,\n etag: res.headers.get('etag') ?? undefined,\n lastModified: res.headers.get('last-modified') ?? undefined,\n };\n await writeFile(offlineMetaPath(cacheDir), JSON.stringify(meta, null, 2));\n return { status: 'updated', meta };\n}\n\ntype Bucket = Record<string, OsvVulnerability[]>;\n\nfunction bucketDir(cacheDir: string): string {\n return join(offlineDbDir(cacheDir), 'by-name');\n}\n\nfunction bucketPath(cacheDir: string, bucket: number): string {\n // Shards are gzipped: advisory JSON compresses ~5–6×, keeping the on-disk DB\n // (and the CI cache that stores it) small.\n return join(bucketDir(cacheDir), `${bucket}.json.gz`);\n}\n\n/**\n * Load advisories for the given package names. Names are grouped by shard\n * bucket so each bucket file is read at most once, and a scan only touches the\n * buckets its dependencies fall into.\n */\nexport async function loadAdvisoriesForPackages(\n cacheDir: string,\n names: Iterable<string>,\n): Promise<Map<string, OsvVulnerability[]>> {\n if (!(await readOfflineMeta(cacheDir))) throw new OfflineDbMissingError();\n\n const namesByBucket = new Map<number, string[]>();\n for (const name of new Set(names)) {\n const bucket = shardBucket(name);\n const list = namesByBucket.get(bucket);\n if (list) list.push(name);\n else namesByBucket.set(bucket, [name]);\n }\n\n const result = new Map<string, OsvVulnerability[]>();\n await Promise.all(\n [...namesByBucket.entries()].map(async ([bucket, bucketNames]) => {\n try {\n const data = JSON.parse(\n gunzipSync(await readFile(bucketPath(cacheDir, bucket))).toString('utf8'),\n ) as Bucket;\n for (const name of bucketNames) {\n const records = data[name];\n if (records?.length) result.set(name, records);\n }\n } catch {\n // No bucket file → none of these packages have advisories.\n }\n }),\n );\n return result;\n}\n\nfunction groupByPackage(records: OsvVulnerability[]): Map<string, OsvVulnerability[]> {\n const byName = new Map<string, OsvVulnerability[]>();\n for (const record of records) {\n if (record.withdrawn) continue;\n const names = new Set<string>();\n for (const affected of record.affected ?? []) {\n const ecosystem = affected.package?.ecosystem;\n if (ecosystem && ecosystem !== 'npm') continue;\n if (affected.package?.name) names.add(affected.package.name);\n }\n for (const name of names) {\n const list = byName.get(name);\n if (list) list.push(record);\n else byName.set(name, [record]);\n }\n }\n return byName;\n}\n\nasync function writeShards(\n cacheDir: string,\n byName: Map<string, OsvVulnerability[]>,\n): Promise<void> {\n const dir = bucketDir(cacheDir);\n await rm(dir, { recursive: true, force: true });\n await mkdir(dir, { recursive: true });\n\n // Group packages into a bounded number of bucket files (CI-cache friendly).\n const buckets = new Map<number, Bucket>();\n for (const [name, records] of byName) {\n const bucket = shardBucket(name);\n const map = buckets.get(bucket) ?? {};\n map[name] = records;\n buckets.set(bucket, map);\n }\n\n const entries = [...buckets.entries()];\n const BATCH = 256;\n for (let i = 0; i < entries.length; i += BATCH) {\n await Promise.all(\n entries\n .slice(i, i + BATCH)\n .map(([bucket, map]) =>\n writeFile(bucketPath(cacheDir, bucket), gzipSync(Buffer.from(JSON.stringify(map)))),\n ),\n );\n }\n}\n\nfunction readZipRecords(zipPath: string): Promise<OsvVulnerability[]> {\n return new Promise((resolve, reject) => {\n const out: OsvVulnerability[] = [];\n yauzl.open(zipPath, { lazyEntries: true }, (err, zip) => {\n if (err || !zip) return reject(err ?? new Error('Failed to open OSV zip'));\n zip.on('entry', (entry) => {\n if (!entry.fileName.endsWith('.json')) return zip.readEntry();\n // Bound memory: skip implausibly large entries (advisory JSON is small).\n if (entry.uncompressedSize > MAX_ENTRY_BYTES) return zip.readEntry();\n zip.openReadStream(entry, (streamErr, stream) => {\n if (streamErr || !stream) return zip.readEntry();\n const chunks: Buffer[] = [];\n stream.on('data', (chunk: Buffer) => chunks.push(chunk));\n stream.on('error', () => zip.readEntry());\n stream.on('end', () => {\n try {\n out.push(JSON.parse(Buffer.concat(chunks).toString('utf8')) as OsvVulnerability);\n } catch {\n // Skip malformed entries rather than failing the whole import.\n }\n zip.readEntry();\n });\n });\n });\n zip.on('end', () => resolve(out));\n zip.on('error', reject);\n zip.readEntry();\n });\n });\n}\n","import type { DatabaseInfo, OsvVulnerability, SourceMode } from '../types.js';\nimport { OsvClient } from './client.js';\nimport type { PackageRef } from './client.js';\nimport { OfflineDbMissingError, loadAdvisoriesForPackages, readOfflineMeta } from './offline-db.js';\n\n/** A source prepared for a specific package set: synchronous lookup + provenance. */\nexport interface ResolvedSource {\n candidatesFor(name: string): OsvVulnerability[];\n database: DatabaseInfo;\n}\n\n/** Strategy for obtaining advisories (offline DB, online API, or auto). */\nexport interface VulnSource {\n prepare(packages: PackageRef[]): Promise<ResolvedSource>;\n}\n\nexport interface SourceOptions {\n cacheDir: string;\n concurrency?: number;\n noCache?: boolean;\n cacheTtlHours?: number;\n /** Fail hard on network errors instead of degrading to cache. */\n strictNetwork?: boolean;\n /** Offline DB older than this many hours is flagged stale (default 24). */\n staleAfterHours?: number;\n}\n\nconst HOUR_MS = 3_600_000;\n\n/** Reads advisories from the on-disk offline database. */\nexport class OfflineSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const meta = await readOfflineMeta(this.opts.cacheDir);\n if (!meta) throw new OfflineDbMissingError();\n const map = await loadAdvisoriesForPackages(\n this.opts.cacheDir,\n packages.map((p) => p.name),\n );\n\n const ageHours = (Date.now() - Date.parse(meta.lastUpdated)) / HOUR_MS;\n const stale = ageHours > (this.opts.staleAfterHours ?? 24);\n const warnings = stale\n ? [\n `Offline database is ${Math.round(ageHours)}h old. Run \\`lockhawk db update\\` for current results.`,\n ]\n : [];\n\n return {\n candidatesFor: (name) => map.get(name) ?? [],\n database: {\n source: 'offline',\n recordCount: meta.recordCount,\n lastUpdated: meta.lastUpdated,\n ageHours: Math.round(ageHours * 10) / 10,\n stale,\n warnings,\n },\n };\n }\n}\n\n/** Queries the live OSV.dev API. Fail-open unless `strictNetwork` is set. */\nexport class OnlineSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const client = new OsvClient({\n cacheDir: this.opts.cacheDir,\n concurrency: this.opts.concurrency,\n noCache: this.opts.noCache,\n cacheTtlHours: this.opts.cacheTtlHours,\n });\n try {\n const map = await client.fetchAdvisories(packages);\n return {\n candidatesFor: (name) => map.get(name) ?? [],\n database: { source: 'online', stale: false, warnings: [] },\n };\n } catch (err) {\n if (this.opts.strictNetwork) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n return {\n candidatesFor: () => [],\n database: {\n source: 'online',\n stale: true,\n warnings: [\n `OSV.dev was unreachable (${reason}). Scan completed without online data — results may be incomplete.`,\n ],\n },\n };\n }\n }\n}\n\n/**\n * Prefers a fresh offline DB (fast, zero network), falls back to the online API,\n * and finally to a stale offline DB if the network is down — always degrading\n * gracefully so a scan never hard-fails on a transient outage.\n */\nexport class AutoSource implements VulnSource {\n constructor(private readonly opts: SourceOptions) {}\n\n async prepare(packages: PackageRef[]): Promise<ResolvedSource> {\n const meta = await readOfflineMeta(this.opts.cacheDir);\n const ttl = this.opts.staleAfterHours ?? 24;\n\n if (meta) {\n const ageHours = (Date.now() - Date.parse(meta.lastUpdated)) / HOUR_MS;\n if (ageHours <= ttl) {\n return new OfflineSource(this.opts).prepare(packages); // fresh offline → fast path\n }\n }\n\n try {\n return await new OnlineSource({ ...this.opts, strictNetwork: true }).prepare(packages);\n } catch (err) {\n if (meta) {\n const resolved = await new OfflineSource(this.opts).prepare(packages);\n resolved.database.warnings.push(\n 'Used the stale offline database because OSV.dev was unreachable.',\n );\n return resolved;\n }\n if (this.opts.strictNetwork) throw err;\n const reason = err instanceof Error ? err.message : String(err);\n return {\n candidatesFor: () => [],\n database: {\n source: 'online',\n stale: true,\n warnings: [\n `No offline database and OSV.dev was unreachable (${reason}). Run \\`lockhawk db update\\`.`,\n ],\n },\n };\n }\n }\n}\n\n/** Build the right source for the requested mode. */\nexport function createSource(mode: SourceMode, opts: SourceOptions): VulnSource {\n switch (mode) {\n case 'offline':\n return new OfflineSource(opts);\n case 'online':\n return new OnlineSource(opts);\n default:\n return new AutoSource(opts);\n }\n}\n","import type { ScanResult } from '../types.js';\n\n/** Serialize a scan result as pretty-printed JSON. */\nexport function toJson(result: ScanResult): string {\n return JSON.stringify(result, null, 2);\n}\n","import type { Finding, ScanResult, Severity } from '../types.js';\n\n// Minimal SARIF 2.1.0 shapes (avoids a dependency on the `sarif` types package).\ninterface SarifRule {\n id: string;\n name?: string;\n shortDescription: { text: string };\n fullDescription?: { text: string };\n helpUri?: string;\n properties?: Record<string, unknown>;\n}\ninterface SarifResult {\n ruleId: string;\n level: 'error' | 'warning' | 'note';\n message: { text: string };\n locations: unknown[];\n partialFingerprints: Record<string, string>;\n properties?: Record<string, unknown>;\n}\nexport interface SarifLog {\n $schema: string;\n version: '2.1.0';\n runs: unknown[];\n}\n\nconst INFO_URI = 'https://github.com/lockhawk/lockhawk';\n\n/** First http(s) reference, if any — never propagate javascript:/data: URIs. */\nfunction helpUriFor(references: string[]): string | undefined {\n return references.find((ref) => {\n try {\n const u = new URL(ref);\n return u.protocol === 'http:' || u.protocol === 'https:';\n } catch {\n return false;\n }\n });\n}\n\n/** GitHub renders findings by `security-severity` (a CVSS-like number 0–10). */\nfunction securitySeverity(finding: Finding): number {\n if (typeof finding.severity.score === 'number') return finding.severity.score;\n switch (finding.severity.level) {\n case 'critical':\n return 9.5;\n case 'high':\n return 7.5;\n case 'medium':\n return 5;\n case 'low':\n return 2;\n default:\n return 0;\n }\n}\n\nfunction sarifLevel(severity: Severity): 'error' | 'warning' | 'note' {\n if (severity === 'critical' || severity === 'high') return 'error';\n if (severity === 'medium') return 'warning';\n return 'note';\n}\n\n/**\n * Convert a scan result to SARIF 2.1.0 for GitHub code scanning / Azure DevOps.\n * One rule per advisory; results carry stable `partialFingerprints` so the same\n * finding is not re-flagged as new on every run.\n */\nexport function toSarif(result: ScanResult): SarifLog {\n const lockfileUri = result.target.lockfile || 'package-lock.json';\n\n const rules = new Map<string, SarifRule>();\n const results: SarifResult[] = [];\n\n for (const finding of result.findings) {\n if (!rules.has(finding.id)) {\n rules.set(finding.id, {\n id: finding.id,\n name: `${finding.packageName} ${finding.id}`,\n shortDescription: { text: finding.summary },\n fullDescription: finding.details ? { text: finding.details } : undefined,\n helpUri: helpUriFor(finding.references),\n properties: {\n 'security-severity': String(securitySeverity(finding)),\n tags: ['security', 'dependency', finding.severity.level],\n },\n });\n }\n\n const path = finding.dependencyPaths[0]?.join(' › ') ?? finding.packageName;\n const fix = finding.fixedVersions[0] ? ` Fixed in ${finding.fixedVersions[0]}.` : '';\n results.push({\n ruleId: finding.id,\n level: sarifLevel(finding.severity.level),\n message: {\n text: `${finding.severity.level.toUpperCase()}: ${finding.packageName}@${finding.version} — ${finding.summary}.${fix} Path: ${path}.`,\n },\n locations: [\n {\n physicalLocation: {\n artifactLocation: { uri: lockfileUri },\n region: { startLine: 1 },\n },\n },\n ],\n partialFingerprints: {\n lockhawkFinding: `${finding.packageName}@${finding.version}@${finding.id}`,\n },\n properties: {\n package: finding.packageName,\n version: finding.version,\n scope: finding.scope,\n fixedVersions: finding.fixedVersions,\n },\n });\n }\n\n return {\n $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n name: result.tool.name,\n version: result.tool.version,\n informationUri: INFO_URI,\n rules: [...rules.values()],\n },\n },\n results,\n properties: {\n scannedAt: result.scannedAt,\n databaseSource: result.database.source,\n databaseAgeHours: result.database.ageHours,\n databaseStale: result.database.stale,\n },\n },\n ],\n };\n}\n\n/** Stringified SARIF log. */\nexport function toSarifString(result: ScanResult): string {\n return JSON.stringify(toSarif(result), null, 2);\n}\n","import type { ScanResult, Severity } from '../types.js';\n\n/**\n * Produce a self-contained HTML report for a scan result.\n *\n * The page is fully server-rendered: no client-side JavaScript, no embedded\n * data blob, no external resources. Every dynamic value is HTML-escaped, the\n * layout flows normally within a width-constrained container, and long advisory\n * text lives in a collapsed, contained block — so the report cannot overflow the\n * viewport or render attacker-controlled advisory text as live markup.\n */\nexport function toHtml(result: ScanResult): string {\n return renderHtml(result);\n}\n\nconst SEVERITY_COLORS: Record<Severity, string> = {\n critical: '#b4232c',\n high: '#d9822b',\n medium: '#c9a227',\n low: '#3a7bd5',\n unknown: '#7a7a7a',\n none: '#3a9e54',\n};\n\nfunction esc(text: string): string {\n return text.replace(\n /[&<>\"]/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"' })[c]!,\n );\n}\n\n/** Only http(s) URLs are safe to render as links (blocks javascript:/data: hrefs). */\nfunction httpHref(url: string): string | undefined {\n try {\n const u = new URL(url);\n return u.protocol === 'http:' || u.protocol === 'https:' ? url : undefined;\n } catch {\n return undefined;\n }\n}\n\nfunction renderHtml(result: ScanResult): string {\n const { summary } = result;\n const cards = (['critical', 'high', 'medium', 'low', 'unknown'] as Severity[])\n .map(\n (sev) => `\n <div class=\"card\" style=\"border-top:4px solid ${SEVERITY_COLORS[sev]}\">\n <div class=\"count\">${summary[sev]}</div><div class=\"label\">${sev}</div>\n </div>`,\n )\n .join('');\n\n const rows = result.findings\n .map((f) => {\n const path = f.dependencyPaths[0]?.join(' › ') ?? f.packageName;\n const refs = f.references\n .slice(0, 3)\n .map((u) => httpHref(u))\n .filter((u): u is string => u !== undefined)\n .map((u) => `<a href=\"${esc(u)}\" target=\"_blank\" rel=\"noopener\">link</a>`)\n .join(' ');\n const rec = f.recommendation\n ? `<p class=\"rec\"><strong>Recommendation:</strong> ${esc(f.recommendation)}</p>`\n : '';\n return `\n <tr>\n <td><span class=\"pill\" style=\"background:${SEVERITY_COLORS[f.severity.level]}\">${esc(\n f.severity.level,\n )}${f.severity.score ? ` ${f.severity.score}` : ''}</span></td>\n <td><code>${esc(f.packageName)}@${esc(f.version)}</code><div class=\"scope\">${esc(f.scope)}${\n f.direct ? ' · direct' : ''\n }</div></td>\n <td><a href=\"https://osv.dev/${encodeURIComponent(f.id)}\" target=\"_blank\" rel=\"noopener\">${esc(\n f.id,\n )}</a></td>\n <td>${esc(f.summary)}<div class=\"path\">${esc(path)}</div></td>\n <td>${f.fixedVersions[0] ? esc(f.fixedVersions[0]) : '—'}</td>\n <td class=\"refs\">${refs}</td>\n </tr>\n <tr class=\"detail-row\">\n <td colspan=\"6\">\n <details>\n <summary>Advisory details</summary>\n ${rec}<pre class=\"advisory\">${esc(f.details ?? f.summary)}</pre>\n </details>\n </td>\n </tr>`;\n })\n .join('');\n\n const dbWarnings = result.database.warnings\n .map((w) => `<div class=\"warn\">⚠ ${esc(w)}</div>`)\n .join('');\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>lockhawk report — ${esc(result.target.root.name)}</title>\n<style>\n :root { color-scheme: light dark; }\n * { box-sizing: border-box; }\n html, body { max-width: 100%; overflow-x: hidden; }\n body { font: 15px/1.5 -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif; margin: 0; background: #f6f7f9; color: #1c1e21; }\n header { background: #11161d; color: #fff; padding: 24px 32px; }\n header h1 { margin: 0 0 4px; font-size: 20px; }\n header .meta { color: #9aa4b2; font-size: 13px; overflow-wrap: anywhere; }\n main { max-width: 1100px; margin: 0 auto; padding: 24px clamp(16px, 4vw, 32px) 40px; }\n .cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(110px, 1fr)); gap: 12px; margin-bottom: 8px; }\n .card { background: #fff; border-radius: 8px; padding: 14px 16px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }\n .card .count { font-size: 28px; font-weight: 700; }\n .card .label { text-transform: capitalize; color: #6b7280; font-size: 13px; }\n .warn { background: #fff7e6; border: 1px solid #ffd591; color: #874d00; padding: 8px 12px; border-radius: 6px; margin: 12px 0; font-size: 13px; overflow-wrap: anywhere; }\n .table-wrap { margin-top: 16px; overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: 8px; box-shadow: 0 1px 3px rgba(0,0,0,.08); }\n table { width: 100%; border-collapse: collapse; background: #fff; }\n th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #eef0f3; vertical-align: top; font-size: 13px; overflow-wrap: anywhere; word-break: break-word; }\n th { background: #f0f2f5; font-size: 12px; text-transform: uppercase; letter-spacing: .03em; color: #6b7280; white-space: nowrap; }\n .pill { color: #fff; padding: 2px 8px; border-radius: 999px; font-size: 12px; text-transform: capitalize; white-space: nowrap; }\n .scope, .path { color: #6b7280; font-size: 12px; }\n .path { margin-top: 4px; }\n .refs { white-space: nowrap; }\n code { background: #eef0f3; padding: 1px 5px; border-radius: 4px; max-width: 100%; }\n .detail-row td { border-bottom: 2px solid #eef0f3; padding-top: 0; }\n details { font-size: 13px; }\n summary { cursor: pointer; color: #3a7bd5; font-size: 12px; padding: 4px 0; width: max-content; }\n .rec { margin: 8px 0; font-size: 13px; }\n pre.advisory { white-space: pre-wrap; word-break: break-word; overflow-x: auto; max-width: 100%; background: #f6f7f9; border: 1px solid #eef0f3; border-radius: 6px; padding: 10px 12px; margin: 6px 0 4px; font-size: 12.5px; }\n .empty { background: #fff; border-radius: 8px; padding: 40px; text-align: center; color: #3a9e54; font-size: 18px; box-shadow: 0 1px 3px rgba(0,0,0,.08); margin-top: 16px; }\n footer { max-width: 1100px; margin: 0 auto; padding: 16px clamp(16px, 4vw, 32px) 40px; color: #9aa4b2; font-size: 12px; }\n</style>\n</head>\n<body>\n<header>\n <h1>lockhawk report</h1>\n <div class=\"meta\">${esc(result.target.root.name)}${\n result.target.root.version ? `@${esc(result.target.root.version)}` : ''\n } · ${esc(result.target.manager)} · ${result.stats.totalPackages} packages · scanned ${esc(\n result.scannedAt,\n )}</div>\n</header>\n<main>\n <div class=\"cards\">${cards}</div>\n ${dbWarnings}\n ${\n result.findings.length === 0\n ? '<div class=\"empty\">✓ No known vulnerabilities found.</div>'\n : `<div class=\"table-wrap\"><table>\n <thead><tr><th>Severity</th><th>Package</th><th>Advisory</th><th>Summary & path</th><th>Fixed in</th><th>Refs</th></tr></thead>\n <tbody>${rows}</tbody>\n </table></div>`\n }\n</main>\n<footer>Generated by lockhawk v${esc(result.tool.version)} · data from OSV.dev · database: ${esc(\n result.database.source,\n )}</footer>\n</body>\n</html>`;\n}\n","import type { Finding, ScanResult } from '../types.js';\n\n// JUnit XML reporter. Each vulnerability is emitted as a failed <testcase> so\n// CI systems that render JUnit results natively — Azure DevOps \"Tests\" tab,\n// GitHub test reporters, GitLab's test report / MR widget — show the findings\n// as a pass/fail dashboard with full detail, no custom UI required. A clean\n// scan emits a single passing test.\n\nfunction xml(text: string): string {\n return text.replace(\n /[&<>\"']/g,\n (c) => ({ '&': '&', '<': '<', '>': '>', '\"': '"', \"'\": ''' })[c]!,\n );\n}\n\nfunction failureBody(f: Finding): string {\n const lines = [\n `Package: ${f.packageName}@${f.version} (${f.scope}${f.direct ? ', direct' : ', transitive'})`,\n `Severity: ${f.severity.level}${f.severity.score !== undefined ? `, CVSS ${f.severity.score}` : ''}${\n f.severity.vector ? ` (${f.severity.vector})` : ''\n }`,\n f.fixedVersions.length ? `Fixed in: ${f.fixedVersions.join(', ')}` : 'Fix: none available yet',\n f.dependencyPaths[0] ? `Dependency path: ${f.dependencyPaths[0].join(' > ')}` : '',\n f.recommendation ? `Recommendation: ${f.recommendation}` : '',\n f.references.length ? `References:\\n${f.references.join('\\n')}` : '',\n ];\n return lines.filter(Boolean).join('\\n');\n}\n\n/** Render a scan result as JUnit XML (one failed test per finding). */\nexport function toJunit(result: ScanResult): string {\n const { findings } = result;\n const failures = findings.length;\n const tests = findings.length === 0 ? 1 : findings.length;\n const time = ((result.stats.durationMs ?? 0) / 1000).toFixed(3);\n const suiteName = `${result.target.root.name} npm dependency vulnerabilities`;\n\n const cases =\n findings.length === 0\n ? [' <testcase name=\"No known vulnerabilities\" classname=\"lockhawk\" time=\"0\" />']\n : findings.map((f) => {\n const name = `${f.packageName}@${f.version}: ${f.id} (${f.severity.level})`;\n const message = `${f.severity.level.toUpperCase()}${\n f.severity.score !== undefined ? ` ${f.severity.score}` : ''\n } ${f.id}: ${f.summary}`;\n return [\n ` <testcase name=\"${xml(name)}\" classname=\"lockhawk.${xml(f.severity.level)}\" time=\"0\">`,\n ` <failure message=\"${xml(message)}\" type=\"${xml(f.severity.level)}\">${xml(failureBody(f))}</failure>`,\n ` </testcase>`,\n ].join('\\n');\n });\n\n return [\n '<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n `<testsuites name=\"lockhawk\" tests=\"${tests}\" failures=\"${failures}\" errors=\"0\" time=\"${time}\">`,\n ` <testsuite name=\"${xml(suiteName)}\" tests=\"${tests}\" failures=\"${failures}\" errors=\"0\" time=\"${time}\">`,\n ...cases,\n ' </testsuite>',\n '</testsuites>',\n '',\n ].join('\\n');\n}\n"],"mappings":"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,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA,EACV,UAAU;AAAA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","names":["readFileSync","readFileSync","m","readFileSync","dirname","require","readFileSync","dirname","resolve","readFileSync","dirname","yaml","yaml","readFileSync","dirname","name","version","semver","score","m","semver","resolve","join","join","dirname","dirname","mkdir","readFile","writeFile","join","readFile","mkdir","meta","writeFile","join","resolve","resolve"]}
|