// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// engine/runtime-security/checkers/dependency-vuln.ts — SPEC-084 AC-13
// Analyzes lockfiles against an offline CVE database.
import { readFileSync, existsSync } from 'node:fs';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
const CVE_DB_PATH = resolve(MODULE_DIR, '../../../config/known-cves.json');
let cachedDb = null;
function loadCveDatabase() {
    if (cachedDb) {
        return cachedDb;
    }
    try {
        const raw = readFileSync(CVE_DB_PATH, 'utf-8');
        cachedDb = JSON.parse(raw);
        return cachedDb;
    }
    catch {
        return { lastUpdated: '', vulnerabilities: [] };
    }
}
const LOCKFILE_ECOSYSTEMS = {
    'package-lock.json': 'npm',
    'pnpm-lock.yaml': 'npm',
    'yarn.lock': 'npm',
    'Pipfile.lock': 'pip',
    'poetry.lock': 'pip',
    'go.sum': 'go',
    'Cargo.lock': 'cargo',
    'Gemfile.lock': 'gem',
    'composer.lock': 'composer',
    'packages.lock.json': 'nuget',
};
function findLockfiles(projectPath) {
    const results = [];
    for (const [filename, ecosystem] of Object.entries(LOCKFILE_ECOSYSTEMS)) {
        const fullPath = resolve(projectPath, filename);
        if (existsSync(fullPath)) {
            results.push({ path: fullPath, ecosystem });
        }
    }
    return results;
}
export function checkDependencies(projectPath) {
    const db = loadCveDatabase();
    const lockfiles = findLockfiles(projectPath);
    const vulnerabilities = [];
    for (const lockfile of lockfiles) {
        const ecosystemCves = db.vulnerabilities.filter((cve) => cve.ecosystem === lockfile.ecosystem);
        if (ecosystemCves.length === 0) {
            continue;
        }
        try {
            const content = readFileSync(lockfile.path, 'utf-8');
            for (const cve of ecosystemCves) {
                // Simple check: see if package name appears in lockfile
                if (content.includes(cve.package)) {
                    vulnerabilities.push({
                        package: cve.package,
                        version: 'detected',
                        cveId: cve.cveId,
                        severity: cve.severity,
                        description: cve.description,
                        fixVersion: cve.fixVersion,
                        ecosystem: cve.ecosystem,
                    });
                }
            }
        }
        catch {
            // Can't read lockfile — skip
        }
    }
    return vulnerabilities;
}
export const dependencyVulnChecker = {
    type: 'dependency-vulnerability',
    check(_toolName, inputs, _config) {
        const projectPath = typeof inputs.projectPath === 'string' ? inputs.projectPath : null;
        if (!projectPath) {
            return [];
        }
        const vulns = checkDependencies(projectPath);
        return vulns.map((v) => ({
            type: 'dependency-vulnerability',
            severity: v.severity,
            message: `${v.package}: ${v.description} (${v.cveId})`,
            field: 'projectPath',
            pattern: v.cveId,
        }));
    },
};
//# sourceMappingURL=dependency-vuln.js.map