(rows: Record<string, unknown>[])
| 95 | } |
| 96 | |
| 97 | export function convertRowsToCsv(rows: Record<string, unknown>[]): string { |
| 98 | if (rows.length === 0) return '' |
| 99 | |
| 100 | const headerSet = new Set<string>() |
| 101 | for (const row of rows) { |
| 102 | for (const key of Object.keys(row)) { |
| 103 | headerSet.add(key) |
| 104 | } |
| 105 | } |
| 106 | const headers = [...headerSet] |
| 107 | |
| 108 | const lines = [headers.map(escapeCsvValue).join(',')] |
| 109 | for (const row of rows) { |
| 110 | lines.push(headers.map((h) => escapeCsvValue(row[h])).join(',')) |
| 111 | } |
| 112 | return lines.join('\n') |
| 113 | } |
| 114 | |
| 115 | export function normalizeOutputWorkspaceFileName(outputPath: string): string { |
| 116 | const segments = decodeVfsPathSegments(outputPath.trim().replace(/^\/+|\/+$/g, '')) |
no test coverage detected