(values: unknown[])
| 133 | * JSON is never inferred automatically. |
| 134 | */ |
| 135 | export function inferColumnType(values: unknown[]): Exclude<CsvColumnType, 'json'> { |
| 136 | const nonEmpty = values.filter((v) => v !== null && v !== undefined && v !== '') |
| 137 | if (nonEmpty.length === 0) return 'string' |
| 138 | |
| 139 | const allNumber = nonEmpty.every((v) => { |
| 140 | const n = Number(v) |
| 141 | return !Number.isNaN(n) && String(v).trim() !== '' |
| 142 | }) |
| 143 | if (allNumber) return 'number' |
| 144 | |
| 145 | const allBoolean = nonEmpty.every((v) => { |
| 146 | const s = String(v).toLowerCase() |
| 147 | return s === 'true' || s === 'false' |
| 148 | }) |
| 149 | if (allBoolean) return 'boolean' |
| 150 | |
| 151 | const isoDatePattern = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2})?)?/ |
| 152 | const allDate = nonEmpty.every((v) => { |
| 153 | const s = String(v) |
| 154 | return isoDatePattern.test(s) && !Number.isNaN(Date.parse(s)) |
| 155 | }) |
| 156 | if (allDate) return 'date' |
| 157 | |
| 158 | return 'string' |
| 159 | } |
| 160 | |
| 161 | /** |
| 162 | * Sanitizes a raw header into a valid column/table name. Strips disallowed |
no test coverage detected