import { execSync } from 'node:child_process';
import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { join } from 'node:path';
import { tmpdir } from 'node:os';
import { Logger } from '../utils/logger.js';
/**
 * Runs `npm audit --json` against the installed package in a temp workspace.
 * This resolves the FULL transitive dependency tree — not just top-level deps.
 */
export async function scanTransitiveCves(packageName, version) {
    const workDir = join(tmpdir(), `mcp-guardian-audit-${Date.now()}`);
    try {
        mkdirSync(workDir, { recursive: true });
        writeFileSync(join(workDir, 'package.json'), JSON.stringify({
            name: 'mcp-guardian-audit-workspace',
            version: '1.0.0',
            private: true,
            dependencies: { [packageName]: version || 'latest' },
        }));
        execSync('npm install --package-lock-only --ignore-scripts', {
            cwd: workDir,
            timeout: 60_000,
            stdio: 'pipe',
        });
        let auditOutput = '';
        try {
            auditOutput = execSync('npm audit --json --audit-level=none', {
                cwd: workDir,
                timeout: 30_000,
                stdio: 'pipe',
            }).toString();
        }
        catch (err) {
            auditOutput = err.stdout?.toString() ?? '';
        }
        if (!auditOutput)
            return emptyResult(packageName);
        return parseAuditOutput(packageName, auditOutput);
    }
    catch (err) {
        Logger.warn(`Transitive CVE scan failed for ${packageName}: ${err instanceof Error ? err.message : String(err)}`);
        return emptyResult(packageName);
    }
    finally {
        try {
            rmSync(workDir, { recursive: true, force: true });
        }
        catch { /* ignore */ }
    }
}
function emptyResult(packageName) {
    return { packageName, totalVulns: 0, critical: 0, high: 0, moderate: 0, low: 0, vulnDetails: [] };
}
function parseAuditOutput(packageName, raw) {
    let parsed;
    try {
        parsed = JSON.parse(raw);
    }
    catch {
        return emptyResult(packageName);
    }
    const vulns = [];
    const metadata = parsed?.metadata?.vulnerabilities ?? {};
    for (const [, vuln] of Object.entries(parsed?.vulnerabilities ?? {})) {
        const v = vuln;
        if (!v.severity)
            continue;
        vulns.push({
            id: v.via?.[0]?.source?.toString() ?? v.name,
            severity: v.severity,
            title: v.via?.[0] != null && typeof v.via[0] === 'object' ? v.via[0].title : v.name,
            url: v.via?.[0] != null && typeof v.via[0] === 'object' ? v.via[0].url : '',
            packageName: v.name,
            range: v.range ?? '*',
            isDirect: v.isDirect ?? false,
        });
    }
    return {
        packageName,
        totalVulns: vulns.length,
        critical: metadata.critical ?? vulns.filter((v) => v.severity === 'critical').length,
        high: metadata.high ?? vulns.filter((v) => v.severity === 'high').length,
        moderate: metadata.moderate ?? vulns.filter((v) => v.severity === 'moderate').length,
        low: metadata.low ?? vulns.filter((v) => v.severity === 'low').length,
        vulnDetails: vulns,
    };
}
//# sourceMappingURL=transitive-cve-scanner.js.map