File size: 1,377 Bytes
d17ebe3
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// Lightweight CSV parsing helpers used by the app.
// Exports:
// - parseCSVLine(line): parse a single CSV line into array of values (handles quoted fields)
// - parseCsvContent(text): parse CSV text into { headers: string[], rows: Array<object> }

export function parseCSVLine(line) {
  const res = []
  let cur = ''
  let inQuotes = false
  for (let i = 0; i < line.length; i++) {
    const ch = line[i]
    if (inQuotes) {
      if (ch === '"') {
        if (i + 1 < line.length && line[i + 1] === '"') { cur += '"'; i++ } else { inQuotes = false }
      } else { cur += ch }
    } else {
      if (ch === ',') { res.push(cur); cur = '' }
      else if (ch === '"') { inQuotes = true }
      else { cur += ch }
    }
  }
  res.push(cur)
  return res
}

export function parseCsvContent(txt) {
  const lines = txt.split(/\r?\n/)
  let headerIdx = null
  for (let i = 0; i < lines.length; i++) if (lines[i].trim().length > 0) { headerIdx = i; break }
  if (headerIdx === null) return { headers: [], rows: [] }
  const headers = parseCSVLine(lines[headerIdx])
  const rows = []
  for (let i = headerIdx + 1; i < lines.length; i++) {
    const l = lines[i]
    if (!l || l.trim() === '') continue
    const vals = parseCSVLine(l)
    const obj = {}
    for (let j = 0; j < headers.length; j++) obj[headers[j]] = vals[j] ?? ''
    rows.push(obj)
  }
  return { headers, rows }
}