22
33const fs = require ( 'node:fs' )
44
5+ const { parse : parseCsv } = require ( 'csv-parse/sync' )
6+
57const log = require ( '../../log' )
68const { ExperimentsClient, API_BASE_PATH } = require ( './client' )
79const { Dataset, DatasetRecord } = require ( './dataset' )
@@ -24,49 +26,6 @@ async function retryWithBackoff (attempt, { maxTotalMs = 30_000, baseDelayMs = 2
2426 }
2527}
2628
27- function parseCsv ( content , delimiter ) {
28- const rows = [ ]
29- let field = ''
30- let row = [ ]
31- let inQuotes = false
32-
33- for ( let i = 0 ; i < content . length ; i ++ ) {
34- const char = content [ i ]
35- if ( inQuotes ) {
36- if ( char === '"' ) {
37- if ( content [ i + 1 ] === '"' ) {
38- field += '"'
39- i ++
40- } else {
41- inQuotes = false
42- }
43- } else {
44- field += char
45- }
46- } else if ( char === '"' ) {
47- inQuotes = true
48- } else if ( char === delimiter ) {
49- row . push ( field )
50- field = ''
51- } else if ( char === '\n' || char === '\r' ) {
52- row . push ( field )
53- field = ''
54- rows . push ( row )
55- row = [ ]
56- if ( char === '\r' && content [ i + 1 ] === '\n' ) i ++
57- } else {
58- field += char
59- }
60- }
61-
62- if ( field !== '' || row . length > 0 ) {
63- row . push ( field )
64- rows . push ( row )
65- }
66-
67- return rows
68- }
69-
7029function assertColumns ( name , columns , allowEmpty = true ) {
7130 if ( ! Array . isArray ( columns ) || ( ! allowEmpty && columns . length === 0 ) ) {
7231 throw new Error ( `${ name } must be a ${ allowEmpty ? '' : 'non-empty ' } array of column names` )
@@ -106,7 +65,11 @@ function recordsFromCsv (csvPath, options) {
10665 const content = fs . readFileSync ( csvPath , 'utf8' )
10766 if ( content . trim ( ) . length === 0 ) throw new Error ( 'CSV file appears to be empty or header is missing' )
10867
109- const rows = parseCsv ( content , csvDelimiter )
68+ const rows = parseCsv ( content , {
69+ delimiter : csvDelimiter ,
70+ bom : true ,
71+ relaxColumnCount : true ,
72+ } )
11073 const header = rows . shift ( )
11174 if ( ! header || header . every ( column => column === '' ) ) {
11275 throw new Error ( 'CSV file appears to be empty or header is missing' )
0 commit comments