/** Parses enough of RFC 4180 to show a CSV as a table: quoted fields, doubled quotes, CRLF. */ export function parseCsvPreview( text: string, maxRows = 500, ): { rows: string[][]; truncated: boolean } { const rows: string[][] = []; let row: string[] = []; let field = ""; let quoted = false; let index = 0; const endRow = () => { row.push(field); field = ""; if (row.length > 1 || row[0] !== "") rows.push(row); row = []; }; while (index < text.length) { const char = text[index]; if (quoted) { if (char === '"' && text[index + 1] === '"') { field += '"'; index += 2; continue; } if (char === '"') quoted = false; else field += char; index += 1; continue; } if (char === '"' && field === "") quoted = true; else if (char === ",") { row.push(field); field = ""; } else if (char === "\n" || char === "\r") { endRow(); if (char === "\r" && text[index + 1] === "\n") index += 1; if (rows.length > maxRows) break; } else field += char; index += 1; } if (rows.length <= maxRows && (field !== "" || row.length > 0)) endRow(); return { rows: rows.slice(0, maxRows), truncated: rows.length > maxRows }; }