@@ -14,13 +14,15 @@ import { normalizeColumn } from '@/app/api/table/utils'
1414
1515const logger = createLogger ( 'TableImportCSV' )
1616
17+ const MAX_CSV_FILE_SIZE = 50 * 1024 * 1024
1718const MAX_BATCH_SIZE = 1000
1819const SCHEMA_SAMPLE_SIZE = 100
1920
2021type ColumnType = 'string' | 'number' | 'boolean' | 'date'
2122
2223async function parseCsvBuffer (
23- buffer : Buffer
24+ buffer : Buffer ,
25+ delimiter = ','
2426) : Promise < { headers : string [ ] ; rows : Record < string , unknown > [ ] } > {
2527 const { parse } = await import ( 'csv-parse/sync' )
2628 const parsed = parse ( buffer . toString ( 'utf-8' ) , {
@@ -31,6 +33,7 @@ async function parseCsvBuffer(
3133 relax_quotes : true ,
3234 skip_records_with_error : true ,
3335 cast : false ,
36+ delimiter,
3437 } ) as Record < string , unknown > [ ]
3538
3639 if ( parsed . length === 0 ) {
@@ -121,8 +124,10 @@ function coerceValue(value: unknown, colType: ColumnType): string | number | boo
121124 const s = String ( value ) . toLowerCase ( )
122125 return s === 'true'
123126 }
124- case 'date' :
125- return new Date ( String ( value ) ) . toISOString ( )
127+ case 'date' : {
128+ const d = new Date ( String ( value ) )
129+ return Number . isNaN ( d . getTime ( ) ) ? String ( value ) : d . toISOString ( )
130+ }
126131 default :
127132 return String ( value )
128133 }
@@ -164,6 +169,13 @@ export async function POST(request: NextRequest) {
164169 return NextResponse . json ( { error : 'CSV file is required' } , { status : 400 } )
165170 }
166171
172+ if ( file . size > MAX_CSV_FILE_SIZE ) {
173+ return NextResponse . json (
174+ { error : `File exceeds maximum allowed size of ${ MAX_CSV_FILE_SIZE / ( 1024 * 1024 ) } MB` } ,
175+ { status : 400 }
176+ )
177+ }
178+
167179 if ( ! workspaceId ) {
168180 return NextResponse . json ( { error : 'Workspace ID is required' } , { status : 400 } )
169181 }
@@ -179,7 +191,8 @@ export async function POST(request: NextRequest) {
179191 }
180192
181193 const buffer = Buffer . from ( await file . arrayBuffer ( ) )
182- const { headers, rows } = await parseCsvBuffer ( buffer )
194+ const delimiter = ext === 'tsv' ? '\t' : ','
195+ const { headers, rows } = await parseCsvBuffer ( buffer , delimiter )
183196
184197 const columns = inferSchema ( headers , rows )
185198 const headerToColumn = new Map ( headers . map ( ( h , i ) => [ h , columns [ i ] . name ] ) )
0 commit comments