import { stringifyCell } from '../shared/text'; function escapeCsvCell(value: unknown, delimiter: string, neutralizeFormulas: boolean): string { const originalCell = stringifyCell(value); const isSpreadsheetFormula = /^[\u0000-\u0020]*[=+\-@]/.test(originalCell); const cell = neutralizeFormulas && isSpreadsheetFormula ? `'${originalCell}` : originalCell; const mustQuote = neutralizeFormulas && isSpreadsheetFormula || cell.includes('"') || cell.includes('\n') || cell.includes('\r') || cell.includes(delimiter); return mustQuote ? `"${cell.replaceAll('"', '""')}"` : cell; } export function rowsToCsv(rows: unknown[][], delimiter = ';'): string { return rows .map(row => row.map(value => escapeCsvCell(value, delimiter, false)).join(delimiter)) .join('\n'); } export function rowsToSpreadsheetSafeCsv(rows: unknown[][], delimiter = ';'): string { return rows .map(row => row.map(value => escapeCsvCell(value, delimiter, true)).join(delimiter)) .join('\n'); } export function objectsToCsv(rows: Array>): string { const headers = Object.keys(rows[0] ?? {}); return rowsToSpreadsheetSafeCsv([headers, ...rows.map(row => headers.map(header => row[header]))]); }