// Minimal RFC4180 CSV parser and helpers. const fs = require('fs'); function parseCSV(text) { if (text.charCodeAt(0) === 0xFEFF) text = text.slice(1); const rows = []; let row = [], f = '', q = false; for (let i = 0; i < text.length; i++) { const c = text[i]; if (q) { if (c === '"') { if (text[i+1] === '"') { f += '"'; i++; } else q = false; } else f += c; } else if (c === '"') q = true; else if (c === ',') { row.push(f); f = ''; } else if (c === '\n') { row.push(f.replace(/\r$/, '')); rows.push(row); row = []; f = ''; } else f += c; } if (f !== '' || row.length) { row.push(f); rows.push(row); } return rows; } function readCSV(p) { return parseCSV(fs.readFileSync(p, 'utf8')); } function num(s) { if (s == null) return null; s = String(s).replace(/[,\s]/g, ''); if (s === '' || s === '.') return null; const v = Number(s); return isNaN(v) ? null : v; } function toCSV(rows) { return rows.map(r => r.map(v => { v = v == null ? '' : String(v); return /[",\n]/.test(v) ? '"' + v.replace(/"/g, '""') + '"' : v; }).join(',')).join('\n') + '\n'; } module.exports = { parseCSV, readCSV, num, toCSV };