/**
 * OSV.dev severity enrichment.
 *
 * Several dependency scanners (pip-audit, govulncheck) report vulnerabilities
 * without per-finding severity tiers. This module looks up the vulnerability
 * IDs against https://api.osv.dev/v1/vulns/{id} and classifies them into
 * critical/high/medium/low buckets.
 *
 * Offline safety: if the API is unreachable or an ID is unknown, the caller
 * falls back to a default bucket (pip-audit → medium, govulncheck → high).
 * The analyzer must never fail because OSV was slow.
 */
export type Severity = 'critical' | 'high' | 'medium' | 'low' | 'unknown';
export interface OsvVuln {
    id?: string;
    severity?: Array<{
        type: string;
        score: string;
    }>;
    database_specific?: {
        severity?: string;
    };
    affected?: Array<{
        severity?: Array<{
            type: string;
            score: string;
        }>;
        /**
         * D042 (2.4.7): OSV records expose patch-version info via
         * `affected[].ranges[].events[]`. Each range describes one
         * affected version interval with bounding events:
         *   `{"introduced": "0.0.0"}` (or `"introduced": "X.Y.Z"`)
         *   `{"fixed": "X.Y.Z"}`            ← patch-available signal
         *   `{"limit": "X.Y.Z"}`            ← exclusion upper bound
         *
         * We extract the first non-empty `fixed` event as the
         * `fixedVersion` recommendation for the customer's upgrade
         * path. Pre-D042 this field was unread; both csharp/kotlin/
         * java/ruby's osv-scanner findings rendered `Fix: —`.
         */
        ranges?: Array<{
            type?: string;
            events?: Array<{
                introduced?: string;
                fixed?: string;
                limit?: string;
            }>;
        }>;
    }>;
    aliases?: string[];
    summary?: string;
    details?: string;
    references?: Array<{
        type?: string;
        url: string;
    }>;
}
/**
 * Extract the patch-available version from an OSV record (D042). Walks
 * `affected[].ranges[].events[]` in document order and returns the
 * first non-empty `fixed` event. Multiple `fixed` events can exist
 * when the advisory covers multiple version branches (e.g., a
 * vulnerability backported across 1.x and 2.x lines); the first one
 * is conventionally the lowest patch version — which is the right
 * "minimum upgrade to clear this advisory" answer for most customers.
 *
 * Returns `undefined` when no `fixed` event exists (advisory exists
 * but no patch has been released yet — customer should consider
 * mitigations rather than waiting). Returns `undefined` for the
 * pathological case of empty `affected` / `ranges` / `events` arrays.
 */
export declare function extractOsvFixVersion(vuln: OsvVuln): string | undefined;
/** Enriched OSV detail returned by lookups. cvssScore is the max CVSS base
 *  score across V4/V3 vectors when parseable; null otherwise. */
export interface OsvDetail {
    severity: Severity;
    cvssScore: number | null;
}
/** NVD CVSS 3.x base-score bands. */
export declare function scoreToTier(score: number): Severity;
/**
 * Minimal CVSS v3.0/3.1 base-score calculator.
 * Spec: https://www.first.org/cvss/v3.1/specification-document#7-1-Base-Metrics-Equations
 * Returns null if the vector is malformed or missing required metrics.
 */
export declare function parseCvssV3BaseScore(vector: string): number | null;
/**
 * Extract the maximum CVSS base score from an OSV record. Considers both
 * CVSS_V4 (preferred when present — modern CVEs increasingly use V4 only)
 * and CVSS_V3 vectors at the top level and inside `affected[].severity[]`.
 * Returns null when no parseable vector exists; callers fall back to the
 * `database_specific.severity` string for tier classification.
 */
export declare function extractOsvCvssScore(vuln: OsvVuln): number | null;
/** Classify a single OSV record. Prefers CVSS vector, then database_specific string. */
export declare function classifyOsvSeverity(vuln: OsvVuln): Severity;
/** Signature of the fetcher — swapped in tests to avoid real network. */
export type OsvFetcher = (id: string) => Promise<OsvVuln | null>;
/**
 * Look up severity + CVSS score for a batch of vuln IDs against OSV.dev.
 * Runs requests in parallel, session-caches results, returns a map keyed
 * by ID. IDs that fail (network error, 404, unparseable) map to
 * `{severity: 'unknown', cvssScore: null}` — caller uses a per-scanner
 * default bucket for those.
 */
export declare function enrichOsv(ids: string[], fetcher?: OsvFetcher): Promise<Map<string, OsvDetail>>;
/**
 * Best-effort CVSS score resolution with alias-fallback. For each input
 * finding returns the highest-confidence base score available, in this
 * preference order:
 *   1. The score the producing tool already shipped (`embeddedCvss`) —
 *      preferred because it required no network call
 *   2. OSV.dev lookup of `primaryId` — works for GHSA / RUSTSEC / etc.
 *   3. OSV.dev lookup of each alias in order — necessary for Go's
 *      `GO-YYYY-NNNN` and Python's `PYSEC-YYYY-NNNN` records which
 *      frequently lack CVSS vectors that the corresponding CVE alias
 *      carries (e.g. GO-2025-3750 has no severity but CVE-2025-0913 does)
 *
 * Returns a map keyed by `primaryId`; values are the resolved score or
 * null when neither the embedded data nor any alias yields a parseable
 * vector. Lookups are batched across all inputs so callers pay at most
 * two API roundtrips regardless of finding count.
 */
export declare function resolveCvssScores(inputs: Array<{
    primaryId: string;
    embeddedCvss: number | null;
    aliases: string[];
}>, fetcher?: OsvFetcher): Promise<Map<string, number | null>>;
/**
 * Look up the `aliases` list for each ID against OSV.dev. GHSA/RUSTSEC/
 * GO-YYYY-NNNN primaries frequently have a CVE in their aliases that
 * the producing tool (npm-audit, cargo-audit, govulncheck) didn't
 * surface — we pull them here so downstream enrichers (EPSS) can
 * query against CVE IDs even when the primary isn't one.
 *
 * Falls back to an empty list for IDs the fetcher can't resolve.
 * Session-cached via the same map as `enrichOsv` so a find-severity
 * pass and a find-aliases pass cost at most one roundtrip per ID.
 */
export declare function resolveAliases(ids: ReadonlyArray<string>, fetcher?: OsvFetcher): Promise<Map<string, string[]>>;
/** Test-only — reset the process cache between tests. */
export declare function __clearOsvCache(): void;
//# sourceMappingURL=osv.d.ts.map