Skip to content

Commit fddd521

Browse files
committed
fix(tables): keep TTL import coercion lightweight
1 parent 3adfbb6 commit fddd521

4 files changed

Lines changed: 28 additions & 15 deletions

File tree

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { parseTtlEpochSeconds } from '@/lib/table/column-types/ttl'
2+
import type { ColumnType } from '@/lib/table/column-types/types'
3+
import type { NormalizeDateCellOptions } from '@/lib/table/dates'
4+
import type { JsonValue } from '@/lib/table/types'
5+
6+
type ImportValue = Exclude<JsonValue, Date>
7+
type ImportCoercer = (value: unknown, options?: NormalizeDateCellOptions) => ImportValue
8+
9+
const IMPORT_COERCERS: Partial<Record<ColumnType, ImportCoercer>> = {
10+
ttl: (value, options) => parseTtlEpochSeconds(value, options) ?? String(value),
11+
}
12+
13+
/** Applies lightweight type-specific CSV coercion without loading the full column registry. */
14+
export function coerceColumnTypeImportValue(
15+
type: ColumnType,
16+
value: unknown,
17+
options?: NormalizeDateCellOptions
18+
): ImportValue | undefined {
19+
return IMPORT_COERCERS[type]?.(value, options)
20+
}

apps/sim/lib/table/column-types/ttl.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,6 @@ export const ttlColumnType: ColumnTypeDefinition = {
8383
return seconds === null ? { ok: false } : { ok: true, value: seconds }
8484
},
8585

86-
coerceForImport(value, context) {
87-
return parseTtlEpochSeconds(value, context) ?? String(value)
88-
},
89-
9086
valueForConversion(value, target: ColumnDefinition) {
9187
if (target.type !== 'date') return value
9288
return epochSecondsToIso(value) ?? value

apps/sim/lib/table/column-types/types.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,6 @@ export interface ColumnTypeDefinition {
167167
context?: NormalizeDateCellOptions
168168
): CoerceResult
169169

170-
/** Import-only normalization when invalid raw text must survive for row-level validation. */
171-
coerceForImport?(value: unknown, context?: NormalizeDateCellOptions): Exclude<JsonValue, Date>
172-
173170
/** Source-owned normalization applied before checking or rewriting a type conversion. */
174171
valueForConversion?(value: JsonValue, target: ColumnDefinition): JsonValue
175172

apps/sim/lib/table/import.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
import type { Options as CsvParseOptions } from 'csv-parse'
1515
import { OrchestrationError } from '@/lib/core/orchestration/types'
1616
import { getColumnId } from '@/lib/table/column-keys'
17-
import { type ColumnType, columnTypeById } from '@/lib/table/column-types'
17+
import type { ColumnType } from '@/lib/table/column-types'
18+
import { coerceColumnTypeImportValue } from '@/lib/table/column-types/import-coercion'
1819
import { parseCurrencyInput } from '@/lib/table/currency'
1920
import { type NormalizeDateCellOptions, normalizeDateCellValue } from '@/lib/table/dates'
2021
import type { ColumnDefinition, RowData, TableSchema } from '@/lib/table/types'
@@ -468,11 +469,10 @@ export function inferSchemaFromCsv(
468469
* back to the original string when unparseable so that schema validation can
469470
* reject it with context rather than silently inserting `null`.
470471
*
471-
* Deliberately not routed through the registry's ordinary `coerce`: that
472-
* contract is "coerced or rejected", while an import needs invalid raw text to
473-
* survive so row-level validation can name it. Types with special import
474-
* behavior own it through `coerceForImport`; the remaining legacy import
475-
* semantics stay here until they can move without changing error behavior.
472+
* Deliberately not routed through the column-type registry: its contract is
473+
* "coerced or rejected", while an import needs invalid raw text to survive so
474+
* row-level validation can name it. Type-specific import behavior uses a
475+
* lightweight capability map so CSV clients do not load the full registry.
476476
*/
477477
export function coerceValue(
478478
value: unknown,
@@ -481,8 +481,8 @@ export function coerceValue(
481481
): string | number | boolean | null | Record<string, unknown> | unknown[] {
482482
if (value === null || value === undefined || value === '') return null
483483

484-
const importValue = columnTypeById(colType).coerceForImport?.(value, options)
485-
if (importValue !== undefined) return importValue
484+
const typeSpecificValue = coerceColumnTypeImportValue(colType, value, options)
485+
if (typeSpecificValue !== undefined) return typeSpecificValue
486486

487487
switch (colType) {
488488
case 'number': {

0 commit comments

Comments
 (0)