/** * 分析已有 Flock HAR / network JSON(无需再开浏览器) * * 用法: * npm run analyze:flock-har -- .rpa/flock-network-poc/flock-xxxx.har * npm run analyze:flock-har -- .rpa/flock-network-poc/flock-xxxx-network.json */ import fs from "node:fs"; import path from "node:path"; import { analyzeFlockHarEntries, analyzeFlockNetworkLog, mergeAndDedupeCandidates, summarizeFlockHosts, verdictFromCandidates, type FlockHarFile, type FlockNetworkLogEntry, } from "@/lib/flock/har-analyze"; function main(): void { const target = process.argv[2]; if (!target) { console.error( "用法: npm run analyze:flock-har -- ", ); process.exit(2); } const abs = path.isAbsolute(target) ? target : path.join(process.cwd(), target); if (!fs.existsSync(abs)) { console.error(`文件不存在: ${abs}`); process.exit(1); } const raw = fs.readFileSync(abs, "utf8"); const parsed = JSON.parse(raw) as unknown; let candidates; let hosts: Array<{ host: string; count: number; methods: string[] }> = []; if (Array.isArray(parsed)) { candidates = analyzeFlockNetworkLog(parsed as FlockNetworkLogEntry[]); } else if ( parsed && typeof parsed === "object" && "log" in (parsed as object) ) { const har = parsed as FlockHarFile; const entries = har.log?.entries ?? []; candidates = analyzeFlockHarEntries(entries); hosts = summarizeFlockHosts(entries); } else if ( parsed && typeof parsed === "object" && Array.isArray((parsed as { candidates?: unknown }).candidates) ) { console.log("输入已是 summary JSON,直接打印 candidates"); console.log(JSON.stringify(parsed, null, 2)); return; } else { console.error("无法识别为 HAR 或 network-log JSON"); process.exit(1); } const merged = mergeAndDedupeCandidates([candidates]); const verdict = verdictFromCandidates(merged); console.log(`verdict=${verdict} candidates=${merged.length}`); if (hosts.length) { console.log("hosts:"); for (const h of hosts.slice(0, 15)) { console.log(` ${h.host} ×${h.count} ${h.methods.join(",")}`); } } for (const c of merged.slice(0, 12)) { console.log(`[${c.score}] ${c.method} ${c.status} ${c.urlWithoutQuery}`); if (c.responsePreview) { console.log(` resp: ${c.responsePreview.slice(0, 200)}`); } } } main();