(data: string | CSLReference[] | null | undefined)
| 221 | * Deduplicates by id when parsing JSONL. |
| 222 | */ |
| 223 | export function parseReferences(data: string | CSLReference[] | null | undefined): CSLReference[] | null { |
| 224 | if (!data) return null |
| 225 | if (Array.isArray(data)) return data |
| 226 | |
| 227 | const trimmed = data.trim() |
| 228 | if (!trimmed) return null |
| 229 | |
| 230 | // Try JSON array first (starts with '[') |
| 231 | if (trimmed.startsWith('[')) { |
| 232 | try { |
| 233 | return JSON.parse(trimmed) as CSLReference[] |
| 234 | } catch { |
| 235 | return null |
| 236 | } |
| 237 | } |
| 238 | |
| 239 | // Try JSONL format (one JSON object per line, starts with '{') |
| 240 | if (trimmed.startsWith('{')) { |
| 241 | const refs: CSLReference[] = [] |
| 242 | const seen = new Set<string>() |
| 243 | |
| 244 | for (const line of trimmed.split('\n')) { |
| 245 | const stripped = line.trim() |
| 246 | if (!stripped) continue |
| 247 | try { |
| 248 | const ref = JSON.parse(stripped) as CSLReference |
| 249 | // Dedupe by id |
| 250 | if (ref.id && !seen.has(ref.id)) { |
| 251 | refs.push(ref) |
| 252 | seen.add(ref.id) |
| 253 | } |
| 254 | } catch { |
| 255 | // Skip malformed lines |
| 256 | continue |
| 257 | } |
| 258 | } |
| 259 | return refs.length > 0 ? refs : null |
| 260 | } |
| 261 | |
| 262 | return null |
| 263 | } |
no outgoing calls
no test coverage detected
searching dependent graphs…