effect-qb 0.16.0 → 4.0.0-beta.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/README.md +7 -0
  2. package/dist/mysql.js +1858 -715
  3. package/dist/postgres/metadata.js +2036 -172
  4. package/dist/postgres.js +8011 -6849
  5. package/dist/sqlite.js +8433 -0
  6. package/package.json +7 -4
  7. package/src/internal/column-state.d.ts +3 -3
  8. package/src/internal/column-state.ts +3 -3
  9. package/src/internal/column.ts +8 -8
  10. package/src/internal/derived-table.ts +29 -3
  11. package/src/internal/dialect.ts +3 -1
  12. package/src/internal/dsl-mutation-runtime.ts +173 -4
  13. package/src/internal/dsl-plan-runtime.ts +165 -20
  14. package/src/internal/dsl-query-runtime.ts +60 -6
  15. package/src/internal/dsl-transaction-ddl-runtime.ts +72 -2
  16. package/src/internal/executor.ts +100 -43
  17. package/src/internal/expression-ast.ts +3 -2
  18. package/src/internal/grouping-key.ts +141 -1
  19. package/src/internal/implication-runtime.ts +2 -1
  20. package/src/internal/json/types.ts +155 -40
  21. package/src/internal/predicate/context.ts +14 -1
  22. package/src/internal/predicate/key.ts +19 -2
  23. package/src/internal/predicate/runtime.ts +27 -3
  24. package/src/internal/query.d.ts +1 -1
  25. package/src/internal/query.ts +253 -31
  26. package/src/internal/renderer.ts +35 -2
  27. package/src/internal/runtime/driver-value-mapping.ts +60 -2
  28. package/src/internal/runtime/normalize.ts +62 -38
  29. package/src/internal/runtime/schema.ts +32 -40
  30. package/src/internal/runtime/value.ts +159 -39
  31. package/src/internal/scalar.d.ts +1 -1
  32. package/src/internal/scalar.ts +1 -1
  33. package/src/internal/schema-derivation.d.ts +12 -61
  34. package/src/internal/schema-derivation.ts +95 -43
  35. package/src/internal/table-options.ts +108 -1
  36. package/src/internal/table.d.ts +29 -22
  37. package/src/internal/table.ts +260 -53
  38. package/src/mysql/column.ts +24 -8
  39. package/src/mysql/datatypes/index.ts +21 -0
  40. package/src/mysql/errors/catalog.ts +5 -5
  41. package/src/mysql/errors/normalize.ts +2 -2
  42. package/src/mysql/executor.ts +4 -4
  43. package/src/mysql/function/temporal.ts +1 -1
  44. package/src/mysql/internal/dsl.ts +759 -235
  45. package/src/mysql/internal/renderer.ts +2 -1
  46. package/src/mysql/internal/sql-expression-renderer.ts +486 -130
  47. package/src/mysql/query.ts +9 -2
  48. package/src/mysql/table.ts +64 -35
  49. package/src/postgres/column.ts +14 -12
  50. package/src/postgres/errors/normalize.ts +2 -2
  51. package/src/postgres/executor.ts +52 -9
  52. package/src/postgres/function/core.ts +19 -1
  53. package/src/postgres/function/temporal.ts +1 -1
  54. package/src/postgres/internal/dsl.ts +705 -256
  55. package/src/postgres/internal/renderer.ts +2 -1
  56. package/src/postgres/internal/schema-ddl.ts +2 -1
  57. package/src/postgres/internal/schema-model.ts +6 -3
  58. package/src/postgres/internal/sql-expression-renderer.ts +420 -91
  59. package/src/postgres/json.ts +57 -17
  60. package/src/postgres/query.ts +9 -2
  61. package/src/postgres/schema-management.ts +92 -6
  62. package/src/postgres/schema.ts +1 -1
  63. package/src/postgres/table.ts +203 -75
  64. package/src/sqlite/column.ts +128 -0
  65. package/src/sqlite/datatypes/index.ts +79 -0
  66. package/src/sqlite/datatypes/spec.ts +98 -0
  67. package/src/sqlite/errors/catalog.ts +103 -0
  68. package/src/sqlite/errors/fields.ts +19 -0
  69. package/src/sqlite/errors/index.ts +19 -0
  70. package/src/sqlite/errors/normalize.ts +229 -0
  71. package/src/sqlite/errors/requirements.ts +71 -0
  72. package/src/sqlite/errors/types.ts +29 -0
  73. package/src/sqlite/executor.ts +227 -0
  74. package/src/sqlite/function/aggregate.ts +2 -0
  75. package/src/sqlite/function/core.ts +2 -0
  76. package/src/sqlite/function/index.ts +19 -0
  77. package/src/sqlite/function/string.ts +2 -0
  78. package/src/sqlite/function/temporal.ts +100 -0
  79. package/src/sqlite/function/window.ts +2 -0
  80. package/src/sqlite/internal/dialect.ts +37 -0
  81. package/src/sqlite/internal/dsl.ts +6927 -0
  82. package/src/sqlite/internal/renderer.ts +47 -0
  83. package/src/sqlite/internal/sql-expression-renderer.ts +1821 -0
  84. package/src/sqlite/json.ts +2 -0
  85. package/src/sqlite/query.ts +196 -0
  86. package/src/sqlite/renderer.ts +24 -0
  87. package/src/sqlite/table.ts +175 -0
  88. package/src/sqlite.ts +22 -0
@@ -1,8 +1,7 @@
1
- import type * as Schema from "effect/Schema"
2
-
3
1
  import type * as Expression from "../internal/scalar.js"
4
2
  import { ColumnTypeId, type AnyColumnDefinition } from "../internal/column-state.js"
5
3
  import * as BaseTable from "../internal/table.js"
4
+ import type { TableOptionSpec } from "../internal/table-options.js"
6
5
 
7
6
  type Dialect = "postgres"
8
7
 
@@ -33,25 +32,44 @@ export type TableClassStatic<
33
32
  SchemaName extends string | undefined = "public"
34
33
  > = BaseTable.TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName>
35
34
 
36
- export type AnyTable = BaseTable.AnyTable
35
+ export type AnyTable = BaseTable.AnyTable<Dialect>
37
36
 
38
- type FieldsOfTable<Table> = Table extends BaseTable.TableDefinition<any, infer Fields extends DialectFieldMap, any, any, any>
37
+ type FieldsOfTable<Table extends BaseTable.AnyTable> = Table[typeof BaseTable.TypeId]["fields"] extends infer Fields extends DialectFieldMap
39
38
  ? Fields
40
- : Table extends BaseTable.TableClassStatic<any, infer Fields extends DialectFieldMap, any, any>
41
- ? Fields
42
- : never
43
-
44
- type PrimaryKeyOfTable<Table> = Table extends BaseTable.TableDefinition<any, any, infer PrimaryKeyColumns extends string, any, any>
45
- ? PrimaryKeyColumns
46
- : Table extends BaseTable.TableClassStatic<any, any, infer PrimaryKeyColumns extends string, any>
47
- ? PrimaryKeyColumns
48
- : never
49
-
50
- type SchemaNameOfTable<Table> = Table extends BaseTable.TableDefinition<any, any, any, any, infer SchemaName>
51
- ? SchemaName
52
- : Table extends BaseTable.TableClassStatic<any, any, any, infer SchemaName>
53
- ? SchemaName
54
- : never
39
+ : never
40
+
41
+ type ColumnNamesOfTable<Table extends BaseTable.AnyTable> = Extract<keyof FieldsOfTable<Table>, string>
42
+
43
+ type PrimaryKeyOfTable<Table extends BaseTable.AnyTable> = Table[typeof BaseTable.TypeId]["primaryKey"][number]
44
+
45
+ type SchemaNameOfTable<Table extends BaseTable.AnyTable> = Table[typeof BaseTable.TypeId]["schemaName"]
46
+
47
+ type ApplySchemaTableOptions<
48
+ Name extends string,
49
+ Fields extends DialectFieldMap,
50
+ PrimaryKeyColumns extends keyof Fields & string,
51
+ SchemaName extends string,
52
+ Options extends BaseTable.DeclaredTableOptions
53
+ > = BaseTable.ApplyDeclaredOptions<
54
+ BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
55
+ Options
56
+ > extends BaseTable.TableDefinition<any, any, infer AppliedPrimaryKeyColumns extends keyof Fields & string, "schema", any>
57
+ ? TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName>
58
+ : TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
59
+
60
+ export type TableSchemaNamespace<SchemaName extends string> = {
61
+ readonly schemaName: SchemaName
62
+ readonly table: <
63
+ Name extends string,
64
+ Fields extends DialectFieldMap,
65
+ const Options extends BaseTable.DeclaredTableOptions,
66
+ PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
67
+ >(
68
+ name: Name,
69
+ fields: Fields,
70
+ ...options: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
71
+ ) => ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
72
+ }
55
73
 
56
74
  export type TableOption = BaseTable.TableOption
57
75
  export type DdlExpressionLike = BaseTable.DdlExpressionLike
@@ -89,6 +107,34 @@ export const make = <
89
107
  ): TableDefinition<Name, Fields> =>
90
108
  BaseTable.make(name, fields, schemaName) as TableDefinition<Name, Fields>
91
109
 
110
+ export const schema = <SchemaName extends string>(
111
+ schemaName: SchemaName
112
+ ): TableSchemaNamespace<SchemaName> => {
113
+ const table = <
114
+ Name extends string,
115
+ Fields extends DialectFieldMap,
116
+ const Options extends BaseTable.DeclaredTableOptions,
117
+ PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
118
+ >(
119
+ name: Name,
120
+ fields: Fields,
121
+ ...declaredOptions: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
122
+ ) =>
123
+ (BaseTable.schema(schemaName).table as (
124
+ name: Name,
125
+ fields: Fields,
126
+ ...options: BaseTable.DeclaredTableOptions
127
+ ) => BaseTable.TableDefinition<any, any, any, "schema", any>)(
128
+ name,
129
+ fields,
130
+ ...declaredOptions
131
+ ) as ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
132
+ return {
133
+ schemaName,
134
+ table
135
+ } as unknown as TableSchemaNamespace<SchemaName>
136
+ }
137
+
92
138
  export const alias = <
93
139
  Table extends AnyTable,
94
140
  AliasName extends string
@@ -125,14 +171,14 @@ export const Class = <Self = never, SchemaName extends string | undefined = "pub
125
171
  export const option = BaseTable.option
126
172
 
127
173
  type RichPrimaryKeyInput<Columns extends string | readonly string[]> = {
128
- readonly columns: Columns
174
+ readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
129
175
  readonly name?: string
130
176
  readonly deferrable?: boolean
131
177
  readonly initiallyDeferred?: boolean
132
178
  }
133
179
 
134
180
  type RichUniqueInput<Columns extends string | readonly string[]> = {
135
- readonly columns: Columns
181
+ readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
136
182
  readonly name?: string
137
183
  readonly nullsNotDistinct?: boolean
138
184
  readonly deferrable?: boolean
@@ -155,9 +201,7 @@ type RichIndexKeyInput =
155
201
  readonly collation?: string
156
202
  }
157
203
 
158
- type RichIndexInput<Columns extends string | readonly string[] = string | readonly string[]> = {
159
- readonly columns?: Columns
160
- readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
204
+ type RichIndexDetails = {
161
205
  readonly name?: string
162
206
  readonly unique?: boolean
163
207
  readonly method?: string
@@ -165,14 +209,98 @@ type RichIndexInput<Columns extends string | readonly string[] = string | readon
165
209
  readonly predicate?: DdlExpressionLike
166
210
  }
167
211
 
212
+ type RichIndexInput<Columns extends string | readonly string[] = string | readonly string[]> = RichIndexDetails & (
213
+ | {
214
+ readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
215
+ readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
216
+ }
217
+ | {
218
+ readonly columns?: Columns & BaseTable.NonEmptyColumnInput<Columns>
219
+ readonly keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
220
+ }
221
+ )
222
+
223
+ type PrimaryKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "primaryKey" }>
224
+ type UniqueOptionSpec = Extract<TableOptionSpec, { readonly kind: "unique" }>
225
+ type IndexOptionSpec = Extract<TableOptionSpec, { readonly kind: "index" }>
226
+ type ForeignKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
227
+
228
+ type RichPrimaryKeyOptionSpec<Columns extends string | readonly string[]> = PrimaryKeyOptionSpec & {
229
+ readonly kind: "primaryKey"
230
+ readonly columns: BaseTable.NormalizeColumns<Columns>
231
+ }
232
+
233
+ type RichUniqueOptionSpec<Columns extends string | readonly string[]> = UniqueOptionSpec & {
234
+ readonly kind: "unique"
235
+ readonly columns: BaseTable.NormalizeColumns<Columns>
236
+ }
237
+
238
+ type KnownTargetColumnsInput<
239
+ TargetTable extends AnyTable,
240
+ Columns extends string | readonly string[]
241
+ > = BaseTable.NormalizeColumns<Columns> extends infer NormalizedColumns extends readonly string[]
242
+ ? string extends NormalizedColumns[number]
243
+ ? unknown
244
+ : Exclude<NormalizedColumns[number], ColumnNamesOfTable<TargetTable>> extends never
245
+ ? unknown
246
+ : never
247
+ : never
248
+
249
+ type RichIndexColumnOption<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
250
+ ? { readonly columns: BaseTable.NormalizeColumns<Columns> }
251
+ : {}
252
+
253
+ type RichIndexIncludeOption<Spec> = Spec extends { readonly include: infer Include extends readonly string[] }
254
+ ? { readonly include: Include }
255
+ : {}
256
+
257
+ type RichIndexKeySpec<Key> = Key extends { readonly column: infer Column extends string }
258
+ ? BaseTable.IndexKeySpec & { readonly kind: "column"; readonly column: Column }
259
+ : BaseTable.IndexKeySpec & { readonly kind: "expression" }
260
+
261
+ type RichIndexKeys<Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]> = {
262
+ readonly [K in keyof Keys]: Keys[K] extends RichIndexKeyInput ? RichIndexKeySpec<Keys[K]> : never
263
+ } & readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
264
+
265
+ type RichIndexKeysOption<Spec> = Spec extends { readonly keys: infer Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]] }
266
+ ? { readonly keys: RichIndexKeys<Keys> }
267
+ : {}
268
+
269
+ type RichIndexColumnsConstraint<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
270
+ ? BaseTable.NonEmptyColumnInput<Columns> extends never ? never : unknown
271
+ : unknown
272
+
273
+ type RichIndexOptionSpec<Spec> = IndexOptionSpec & {
274
+ readonly kind: "index"
275
+ readonly name?: string
276
+ readonly unique?: boolean
277
+ readonly method?: string
278
+ readonly predicate?: DdlExpressionLike
279
+ } & RichIndexColumnOption<Spec> & RichIndexIncludeOption<Spec> & RichIndexKeysOption<Spec>
280
+
281
+ type RichForeignKeyOptionSpec<
282
+ LocalColumns extends string | readonly string[],
283
+ TargetTable extends AnyTable,
284
+ TargetColumns extends string | readonly string[]
285
+ > = ForeignKeyOptionSpec & {
286
+ readonly kind: "foreignKey"
287
+ readonly columns: BaseTable.NormalizeColumns<LocalColumns>
288
+ readonly references: () => {
289
+ readonly tableName: string
290
+ readonly schemaName?: string
291
+ readonly columns: BaseTable.NormalizeColumns<TargetColumns>
292
+ readonly knownColumns: readonly ColumnNamesOfTable<TargetTable>[]
293
+ }
294
+ }
295
+
168
296
  type RichForeignKeyInput<
169
297
  LocalColumns extends string | readonly string[],
170
298
  TargetTable extends AnyTable,
171
299
  TargetColumns extends string | readonly string[]
172
300
  > = {
173
- readonly columns: LocalColumns
301
+ readonly columns: LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>
174
302
  readonly target: () => TargetTable
175
- readonly referencedColumns: TargetColumns
303
+ readonly referencedColumns: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
176
304
  readonly name?: string
177
305
  readonly onUpdate?: ReferentialAction
178
306
  readonly onDelete?: ReferentialAction
@@ -205,8 +333,13 @@ const makeTableScopedOption = <
205
333
  return builder
206
334
  }
207
335
 
208
- const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] =>
209
- (Array.isArray(columns) ? [...columns] : [columns]) as unknown as readonly [string, ...string[]]
336
+ const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] => {
337
+ const normalized = Array.isArray(columns) ? [...columns] : [columns]
338
+ if (normalized.length === 0) {
339
+ throw new Error("Table options require at least one column")
340
+ }
341
+ return normalized as unknown as readonly [string, ...string[]]
342
+ }
210
343
 
211
344
  const normalizeIndexKeys = (
212
345
  keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
@@ -231,14 +364,14 @@ const normalizeIndexKeys = (
231
364
 
232
365
  export const primaryKey: {
233
366
  <const Columns extends string | readonly string[]>(
234
- columns: Columns
367
+ columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
235
368
  ): BaseTable.TableOption<{
236
369
  readonly kind: "primaryKey"
237
370
  readonly columns: BaseTable.NormalizeColumns<Columns>
238
371
  }>
239
372
  <const Columns extends string | readonly string[]>(
240
373
  spec: RichPrimaryKeyInput<Columns>
241
- ): BaseTable.TableOption
374
+ ): BaseTable.TableOption<RichPrimaryKeyOptionSpec<Columns>>
242
375
  } = ((input: unknown) =>
243
376
  isObject(input) && "columns" in input
244
377
  ? BaseTable.option({
@@ -252,14 +385,14 @@ export const primaryKey: {
252
385
 
253
386
  export const unique: {
254
387
  <const Columns extends string | readonly string[]>(
255
- columns: Columns
388
+ columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
256
389
  ): BaseTable.TableOption<{
257
390
  readonly kind: "unique"
258
391
  readonly columns: BaseTable.NormalizeColumns<Columns>
259
392
  }>
260
393
  <const Columns extends string | readonly string[]>(
261
394
  spec: RichUniqueInput<Columns>
262
- ): BaseTable.TableOption
395
+ ): BaseTable.TableOption<RichUniqueOptionSpec<Columns>>
263
396
  } = ((input: unknown) =>
264
397
  isObject(input) && "columns" in input && ("name" in input || "nullsNotDistinct" in input || "deferrable" in input || "initiallyDeferred" in input)
265
398
  ? BaseTable.option({
@@ -274,30 +407,21 @@ export const unique: {
274
407
 
275
408
  export const index: {
276
409
  <const Columns extends string | readonly string[]>(
277
- columns: Columns
410
+ columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
278
411
  ): BaseTable.TableOption<{
279
412
  readonly kind: "index"
280
413
  readonly columns: BaseTable.NormalizeColumns<Columns>
281
414
  }>
282
- <Table extends SchemaTable, const Columns extends string | readonly string[]>(
283
- spec: Omit<RichIndexInput<Columns>, "predicate"> & {
415
+ <Table extends SchemaTable, const Columns extends string | readonly string[], const Spec extends Omit<RichIndexInput<Columns>, "predicate"> & {
284
416
  readonly predicate: TableExpressionFactory<Table>
285
- }
286
- ): TableScopedOptionBuilder<Table, {
287
- readonly kind: "index"
288
- readonly columns?: BaseTable.NormalizeColumns<Columns>
289
- readonly keys?: readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
290
- readonly name?: string
291
- readonly unique?: boolean
292
- readonly method?: string
293
- readonly include?: readonly string[]
294
- readonly predicate?: DdlExpressionLike
295
- }>
296
- <const Columns extends string | readonly string[]>(
297
- spec: RichIndexInput<Columns>
298
- ): BaseTable.TableOption
417
+ }>(
418
+ spec: Spec & RichIndexColumnsConstraint<Spec>
419
+ ): TableScopedOptionBuilder<Table, RichIndexOptionSpec<Spec>>
420
+ <const Columns extends string | readonly string[], const Spec extends RichIndexInput<Columns>>(
421
+ spec: Spec & RichIndexColumnsConstraint<Spec>
422
+ ): BaseTable.TableOption<RichIndexOptionSpec<Spec>>
299
423
  } = ((input: unknown) =>
300
- isObject(input) && ("keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
424
+ isObject(input) && ("columns" in input || "keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
301
425
  ? (() => {
302
426
  const spec = input as RichIndexInput<string | readonly string[]> & {
303
427
  readonly predicate?: DdlExpressionLike | TableExpressionFactory<SchemaTable>
@@ -333,35 +457,35 @@ export const foreignKey = <
333
457
  TargetTable extends AnyTable,
334
458
  const TargetColumns extends string | readonly string[]
335
459
  >(
336
- columnsOrSpec: LocalColumns | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
460
+ columnsOrSpec: (LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>) | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
337
461
  target?: () => TargetTable,
338
- referencedColumns?: TargetColumns
339
- ): BaseTable.TableOption =>
462
+ referencedColumns?: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
463
+ ): BaseTable.TableOption<RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>> =>
340
464
  isObject(columnsOrSpec) && "columns" in columnsOrSpec && "target" in columnsOrSpec
341
465
  ? (() => {
342
466
  const spec = columnsOrSpec as RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>
343
- const targetTable = spec.target() as BaseTable.AnyTable
467
+ const targetTable = spec.target()
344
468
  const targetState = targetTable[BaseTable.TypeId]
345
469
  return BaseTable.option({
346
- kind: "foreignKey",
347
- columns: normalizeColumns(spec.columns),
348
- name: spec.name,
349
- references: () => ({
350
- tableName: targetState.baseName,
351
- schemaName: targetState.schemaName,
352
- columns: normalizeColumns(spec.referencedColumns),
353
- knownColumns: Object.keys(targetState.fields)
354
- }),
355
- onUpdate: spec.onUpdate,
356
- onDelete: spec.onDelete,
357
- deferrable: spec.deferrable,
358
- initiallyDeferred: spec.initiallyDeferred
359
- })
470
+ kind: "foreignKey",
471
+ columns: normalizeColumns(spec.columns) as BaseTable.NormalizeColumns<LocalColumns>,
472
+ name: spec.name,
473
+ references: () => ({
474
+ tableName: targetState.baseName,
475
+ schemaName: targetState.schemaName,
476
+ columns: normalizeColumns(spec.referencedColumns) as BaseTable.NormalizeColumns<TargetColumns>,
477
+ knownColumns: Object.keys(targetState.fields) as unknown as readonly ColumnNamesOfTable<TargetTable>[]
478
+ }),
479
+ onUpdate: spec.onUpdate,
480
+ onDelete: spec.onDelete,
481
+ deferrable: spec.deferrable,
482
+ initiallyDeferred: spec.initiallyDeferred
483
+ } as RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>)
360
484
  })()
361
- : BaseTable.foreignKey(
362
- columnsOrSpec as LocalColumns,
363
- target as () => BaseTable.AnyTable,
364
- referencedColumns as TargetColumns
485
+ : BaseTable.foreignKey<LocalColumns, TargetTable, TargetColumns>(
486
+ columnsOrSpec as LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>,
487
+ target as () => TargetTable,
488
+ referencedColumns as TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
365
489
  )
366
490
 
367
491
  export const check: {
@@ -426,6 +550,10 @@ export const check: {
426
550
  })
427
551
  })()) as never
428
552
 
429
- export type SelectOf<Table extends { readonly schemas: { readonly select: Schema.Schema<any> } }> = BaseTable.SelectOf<Table>
430
- export type InsertOf<Table extends { readonly schemas: { readonly insert: Schema.Schema<any> } }> = BaseTable.InsertOf<Table>
431
- export type UpdateOf<Table extends { readonly schemas: { readonly update: Schema.Schema<any> } }> = BaseTable.UpdateOf<Table>
553
+ export const selectSchema = BaseTable.selectSchema
554
+ export const insertSchema = BaseTable.insertSchema
555
+ export const updateSchema = BaseTable.updateSchema
556
+
557
+ export type SelectOf<Table extends AnyTable> = BaseTable.SelectOf<Table>
558
+ export type InsertOf<Table extends AnyTable> = BaseTable.InsertOf<Table>
559
+ export type UpdateOf<Table extends AnyTable> = BaseTable.UpdateOf<Table>
@@ -0,0 +1,128 @@
1
+ import * as Schema from "effect/Schema"
2
+
3
+ import * as BaseColumn from "../internal/column.js"
4
+ import { makeColumnDefinition, type AnyColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
5
+ import type * as Expression from "../internal/scalar.js"
6
+ import {
7
+ DecimalStringSchema,
8
+ LocalDateStringSchema,
9
+ LocalDateTimeStringSchema,
10
+ LocalTimeStringSchema,
11
+ type DecimalString,
12
+ type LocalDateString,
13
+ type LocalDateTimeString,
14
+ type LocalTimeString
15
+ } from "../internal/runtime/value.js"
16
+ import { sqliteDatatypes } from "./datatypes/index.js"
17
+
18
+ const enrichDbType = <Db extends Expression.DbType.Any>(dbType: Db): Db => {
19
+ const candidate = (sqliteDatatypes as unknown as Record<string, (() => Expression.DbType.Any) | undefined>)[dbType.kind]
20
+ return typeof candidate === "function"
21
+ ? { ...candidate(), ...dbType } as Db
22
+ : dbType
23
+ }
24
+
25
+ const primitive = <Type, Db extends Expression.DbType.Any>(
26
+ schema: Schema.Schema<Type>,
27
+ dbType: Db
28
+ ): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
29
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
30
+ dbType,
31
+ nullable: false,
32
+ hasDefault: false,
33
+ generated: false,
34
+ primaryKey: false,
35
+ unique: false,
36
+ references: undefined
37
+ })
38
+
39
+ const renderNumericDdlType = (
40
+ kind: string,
41
+ options?: BaseColumn.NumericOptions
42
+ ): string | undefined => {
43
+ if (options === undefined || options.precision === undefined) {
44
+ return undefined
45
+ }
46
+ return options.scale === undefined
47
+ ? `${kind}(${options.precision})`
48
+ : `${kind}(${options.precision},${options.scale})`
49
+ }
50
+
51
+ export const custom = <SchemaType extends Schema.Top, Db extends Expression.DbType.Any>(
52
+ schema: SchemaType,
53
+ dbType: Db
54
+ ) =>
55
+ makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
56
+ dbType: enrichDbType(dbType),
57
+ nullable: false,
58
+ hasDefault: false,
59
+ generated: false,
60
+ primaryKey: false,
61
+ unique: false,
62
+ references: undefined,
63
+ ddlType: undefined,
64
+ identity: undefined
65
+ })
66
+
67
+ export const uuid = () => primitive(Schema.String.check(Schema.isUUID()), sqliteDatatypes.uuid())
68
+ export const text = () => primitive(Schema.String, sqliteDatatypes.text())
69
+ export const int = () => primitive(Schema.Int, sqliteDatatypes.int())
70
+ export const number = (options?: BaseColumn.NumericOptions) =>
71
+ makeColumnDefinition(DecimalStringSchema, {
72
+ dbType: sqliteDatatypes.decimal(),
73
+ nullable: false,
74
+ hasDefault: false,
75
+ generated: false,
76
+ primaryKey: false,
77
+ unique: false,
78
+ references: undefined,
79
+ ddlType: renderNumericDdlType("decimal", options),
80
+ identity: undefined
81
+ })
82
+ export const boolean = () => primitive(Schema.Boolean, sqliteDatatypes.boolean())
83
+ export const date = () => primitive(LocalDateStringSchema, sqliteDatatypes.date())
84
+ export const time = () => primitive(LocalTimeStringSchema, sqliteDatatypes.time())
85
+ export const datetime = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.datetime())
86
+ export const timestamp = () => primitive(LocalDateTimeStringSchema, sqliteDatatypes.timestamp())
87
+ export const json = <SchemaType extends Schema.Top>(schema: SchemaType) =>
88
+ makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>>, {
89
+ dbType: { ...sqliteDatatypes.json(), variant: "json" } as Expression.DbType.Json<"sqlite", "json">,
90
+ nullable: false,
91
+ hasDefault: false,
92
+ generated: false,
93
+ primaryKey: false,
94
+ unique: false,
95
+ references: undefined,
96
+ ddlType: undefined,
97
+ identity: undefined
98
+ })
99
+
100
+ export const nullable = BaseColumn.nullable
101
+ export const brand = BaseColumn.brand
102
+ export const primaryKey = BaseColumn.primaryKey
103
+ type UniqueColumn<Column extends AnyColumnDefinition> = ReturnType<typeof BaseColumn.unique<Column>>
104
+
105
+ type SqliteUniqueOptions = {
106
+ readonly name?: string
107
+ readonly nullsNotDistinct?: never
108
+ readonly deferrable?: never
109
+ readonly initiallyDeferred?: never
110
+ }
111
+
112
+ type UniqueModifier = {
113
+ <Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column>
114
+ readonly options: <const Options extends SqliteUniqueOptions>(
115
+ options: Options
116
+ ) => <Column extends AnyColumnDefinition>(column: Column) => UniqueColumn<Column>
117
+ }
118
+
119
+ export const unique = BaseColumn.unique as UniqueModifier
120
+ const default_ = BaseColumn.default_
121
+ export const generated = BaseColumn.generated
122
+ export const driverValueMapping = BaseColumn.driverValueMapping
123
+ export const references = BaseColumn.references
124
+ export const schema = BaseColumn.schema
125
+ export { default_ as default }
126
+
127
+ export type Any = BaseColumn.Any
128
+ export type AnyBound = BaseColumn.AnyBound
@@ -0,0 +1,79 @@
1
+ import type { DatatypeModule } from "../../internal/datatypes/define.js"
2
+ import type * as Expression from "../../internal/scalar.js"
3
+ import { sqliteDatatypeFamilies, sqliteDatatypeKinds } from "./spec.js"
4
+
5
+ const withMetadata = <Kind extends keyof typeof sqliteDatatypeKinds & string>(
6
+ kind: Kind
7
+ ): Expression.DbType.Base<"sqlite", Kind> => {
8
+ const kindSpec = sqliteDatatypeKinds[kind]
9
+ const familySpec = sqliteDatatypeFamilies[kindSpec.family as keyof typeof sqliteDatatypeFamilies]
10
+ return {
11
+ dialect: "sqlite",
12
+ kind,
13
+ family: kindSpec.family,
14
+ runtime: kindSpec.runtime,
15
+ compareGroup: familySpec?.compareGroup,
16
+ castTargets: familySpec?.castTargets,
17
+ traits: familySpec?.traits
18
+ }
19
+ }
20
+
21
+ const sqliteDatatypeModule = {
22
+ custom: (kind: string) => ({
23
+ dialect: "sqlite",
24
+ kind
25
+ }),
26
+ uuid: () => ({
27
+ dialect: "sqlite",
28
+ kind: "uuid",
29
+ family: "uuid",
30
+ runtime: "string",
31
+ compareGroup: "uuid",
32
+ castTargets: ["uuid", "char", "varchar", "text"],
33
+ traits: {
34
+ textual: true
35
+ }
36
+ })
37
+ } as Record<string, (...args: readonly any[]) => Expression.DbType.Base<"sqlite", string>>
38
+
39
+ for (const kind of Object.keys(sqliteDatatypeKinds)) {
40
+ sqliteDatatypeModule[kind] = () => withMetadata(kind as keyof typeof sqliteDatatypeKinds & string)
41
+ }
42
+
43
+ type SqliteUuidWitness = Expression.DbType.Base<"sqlite", "uuid"> & {
44
+ readonly family: "uuid"
45
+ readonly runtime: "string"
46
+ readonly compareGroup: "uuid"
47
+ readonly castTargets: readonly ["uuid", "char", "varchar", "text"]
48
+ readonly traits: {
49
+ readonly textual: true
50
+ }
51
+ }
52
+
53
+ type SqliteJsonWitness = Expression.DbType.Base<"sqlite", "json"> & {
54
+ readonly family: "json"
55
+ readonly runtime: "json"
56
+ readonly compareGroup: "json"
57
+ readonly castTargets: readonly ["json", "text"]
58
+ readonly driverValueMapping: {
59
+ readonly toDriver: (value: unknown) => unknown
60
+ }
61
+ }
62
+
63
+ sqliteDatatypeModule.json = () => ({
64
+ ...withMetadata("json"),
65
+ driverValueMapping: {
66
+ toDriver: (value: unknown) => JSON.stringify(value)
67
+ }
68
+ }) as SqliteJsonWitness
69
+
70
+ export const sqliteDatatypes = sqliteDatatypeModule as DatatypeModule<
71
+ "sqlite",
72
+ typeof sqliteDatatypeKinds,
73
+ typeof sqliteDatatypeFamilies
74
+ > & {
75
+ readonly uuid: () => SqliteUuidWitness
76
+ readonly json: () => SqliteJsonWitness
77
+ }
78
+
79
+ export type SqliteDatatypeModule = typeof sqliteDatatypes