import fs from "node:fs"; export type HarEntry = { request: { url: string; method: string }; response: { status: number; content?: { mimeType?: string; text?: string }; }; }; export type HarFile = { log?: { entries?: HarEntry[] }; }; export function readHarFile(harPath: string): HarFile { const raw = fs.readFileSync(harPath, "utf8"); return JSON.parse(raw) as HarFile; } export function listHarEntries(har: HarFile): HarEntry[] { return har.log?.entries ?? []; } export function parseHarResponseJson(entry: HarEntry): unknown | null { const text = entry.response.content?.text; if (!text?.trim()) { return null; } try { return JSON.parse(text) as unknown; } catch { return null; } } const QUOTE_URL_PATTERN = /axel\/quote|api\.mothership\.com|plugins\.mothership\.com|services\.mothership\.com/i; const QUOTE_URL_HINT = /quote|rate|pricing|graphql/i; export function isQuoteHarEntry(entry: HarEntry): boolean { if (entry.response.status < 200 || entry.response.status >= 300) { return false; } const mime = entry.response.content?.mimeType ?? ""; if (!/json/i.test(mime) && !entry.response.content?.text?.trim().startsWith("{")) { return false; } const url = entry.request.url.toLowerCase(); if (QUOTE_URL_PATTERN.test(url)) { return true; } return QUOTE_URL_HINT.test(url) && /mothership/i.test(url); } export function scoreQuoteBody(body: unknown): number { if (body == null || typeof body !== "object") { return 0; } let score = 0; const text = JSON.stringify(body).toLowerCase(); if (text.includes("rates")) { score += 3; } if (text.includes("standard")) { score += 2; } if (text.includes("guaranteed")) { score += 2; } if (text.includes("freight") || text.includes("price")) { score += 1; } if (text.includes("place_id") || text.includes("placeid")) { score += 1; } return score; } export function pickBestQuoteEntry(entries: HarEntry[]): { entry: HarEntry; body: unknown; } | null { let best: { entry: HarEntry; body: unknown; score: number } | null = null; for (const entry of entries) { if (!isQuoteHarEntry(entry)) { continue; } const body = parseHarResponseJson(entry); if (body == null) { continue; } const score = scoreQuoteBody(body); if (score <= 0) { continue; } if (!best || score > best.score) { best = { entry, body, score }; } } return best ? { entry: best.entry, body: best.body } : null; }