diff --git a/apps/sim/lib/table/import.test.ts b/apps/sim/lib/table/import.test.ts index fb95491bd0d..812d2b59ad3 100644 --- a/apps/sim/lib/table/import.test.ts +++ b/apps/sim/lib/table/import.test.ts @@ -63,6 +63,17 @@ describe('import', () => { ) expect(columns.map((c) => c.name)).toEqual(['a_b', 'a_b_2', 'a_b_3']) }) + + it('keeps codes with a leading zero as text so the zero survives', () => { + const { columns } = inferSchemaFromCsv( + ['zip', 'ratio'], + [ + { zip: '02134', ratio: '0.5' }, + { zip: '10001', ratio: '0' }, + ] + ) + expect(columns.map((c) => c.type)).toEqual(['string', 'number']) + }) }) describe('coerceValue', () => { diff --git a/apps/sim/lib/table/import.ts b/apps/sim/lib/table/import.ts index 6fac1af2913..9ff3d1b76b4 100644 --- a/apps/sim/lib/table/import.ts +++ b/apps/sim/lib/table/import.ts @@ -388,9 +388,11 @@ export function inferColumnType(values: unknown[]): InferredCsvColumnType { const nonEmpty = values.filter((v) => v !== null && v !== undefined && v !== '') if (nonEmpty.length === 0) return 'string' + // A leading zero before another digit marks a code (ZIP, phone, SKU), not a + // quantity: storing it as a number would drop the zero for good. const allNumber = nonEmpty.every((v) => { - const n = Number(v) - return !Number.isNaN(n) && String(v).trim() !== '' + const s = String(v).trim() + return s !== '' && !Number.isNaN(Number(s)) && !/^[+-]?0\d/.test(s) }) if (allNumber) return 'number'