JSON ↔ CSV

Both directions, with nested keys flattened and quoting done properly — including commas and line breaks inside fields.

How the edge cases are handled. Nested objects become dotted columns (address.city); arrays become indexed ones (tags.0). Columns are the union of every key seen across all rows, so a field missing from one record does not shift the others. Fields containing a comma, a quote or a newline are quoted and their quotes doubled, per RFC 4180 — the rule most hand-rolled exporters get wrong, which is what produces spreadsheets that look fine until one address has a comma in it.