/** Response body presentation: content kind detection and pretty-printing. */ export type BodyKind = "json" | "xml" | "html" | "text"; export function bodyKind(contentType: string | null | undefined, body: string): BodyKind { const ct = (contentType ?? "").toLowerCase(); if (ct.includes("json")) return "json"; if (ct.includes("html")) return "html"; if (ct.includes("xml")) return "xml"; const t = body.trimStart(); if (t.startsWith("{") || t.startsWith("[")) { try { JSON.parse(body); return "json"; } catch { return "text"; } } if (/^]/i.test(t)) return "html"; if (t.startsWith("/]/.test(t)) return "xml"; return "text"; } export function prettyJson(body: string): string { try { return JSON.stringify(JSON.parse(body), null, 2); } catch { return body; } } const VOID_HTML = new Set([ "area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr", ]); /** * Re-indents XML / HTML by tag nesting. Text-only elements stay on one line; * `