import type { NestedKeyOf } from "#core:utils/types"; interface StringifyOptions { /** The columns to include in the resulting CSV. */ columns: readonly NestedKeyOf[]; /** Content of the first row */ titleRow?: readonly string[]; } function getNested(obj: T, key: NestedKeyOf) { const path: (keyof object)[] = key.split(".") as (keyof unknown)[]; let res = obj[path.shift() as keyof T]; for (const node of path) { if (res === null) { break; } res = res[node]; } return res; } export const csv = { stringify: (objs: T[], options?: StringifyOptions) => { const columns = options.columns; const content = objs .map((obj) => { return columns .map((col) => { return (getNested(obj, col) ?? "") .toString() .replace(/,/g, ",") .replace(/\n/g, " "); }) .join(","); }) .join("\n"); if (!options.titleRow) { return content; } const firstRow = options.titleRow.map((s) => s.replace(/,/g, ",")).join(","); return `${firstRow}\n${content}`; }, };