effect-qb 0.17.0 → 0.19.0

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 (103) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +3053 -2505
  4. package/dist/postgres/metadata.js +1366 -1250
  5. package/dist/postgres.js +2020 -2719
  6. package/dist/sqlite.js +3226 -2732
  7. package/dist/standard.js +8019 -0
  8. package/package.json +10 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +4 -36
  18. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +548 -359
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +654 -399
  20. package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +501 -345
  21. package/src/internal/dialect.ts +35 -0
  22. package/src/internal/dsl-mutation-runtime.ts +12 -162
  23. package/src/internal/dsl-plan-runtime.ts +10 -138
  24. package/src/internal/dsl-query-runtime.ts +5 -79
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
  26. package/src/internal/executor.ts +10 -6
  27. package/src/internal/grouping-key.ts +87 -20
  28. package/src/internal/implication-runtime.ts +1 -1
  29. package/src/internal/predicate/runtime.ts +3 -0
  30. package/src/internal/query.d.ts +38 -11
  31. package/src/internal/query.ts +64 -25
  32. package/src/internal/renderer.ts +26 -14
  33. package/src/internal/runtime/normalize.ts +12 -5
  34. package/src/internal/scalar.ts +6 -1
  35. package/src/internal/schema-derivation.d.ts +12 -61
  36. package/src/internal/schema-derivation.ts +90 -38
  37. package/src/internal/schema-expression.ts +2 -2
  38. package/src/internal/sql-expression-renderer.ts +19 -0
  39. package/src/internal/standard-dsl.ts +6885 -0
  40. package/src/internal/table-options.ts +126 -66
  41. package/src/internal/table.d.ts +33 -32
  42. package/src/internal/table.ts +406 -155
  43. package/src/mysql/column-extension.ts +3 -0
  44. package/src/mysql/column.ts +10 -11
  45. package/src/mysql/datatypes/index.ts +3 -2
  46. package/src/mysql/executor.ts +7 -5
  47. package/src/mysql/internal/dialect.ts +9 -4
  48. package/src/mysql/internal/dsl.ts +219 -155
  49. package/src/mysql/internal/renderer.ts +6 -2
  50. package/src/mysql/json.ts +37 -0
  51. package/src/mysql/query-extension.ts +16 -0
  52. package/src/mysql/renderer.ts +31 -4
  53. package/src/mysql.ts +4 -12
  54. package/src/postgres/column-extension.ts +28 -0
  55. package/src/postgres/column.ts +5 -11
  56. package/src/postgres/datatypes/index.d.ts +2 -1
  57. package/src/postgres/datatypes/index.ts +3 -2
  58. package/src/postgres/executor.ts +7 -5
  59. package/src/postgres/function/core.ts +1 -3
  60. package/src/postgres/function/index.ts +1 -17
  61. package/src/postgres/internal/dialect.ts +9 -4
  62. package/src/postgres/internal/dsl.ts +208 -160
  63. package/src/postgres/internal/renderer.ts +6 -2
  64. package/src/postgres/internal/schema-ddl.ts +22 -10
  65. package/src/postgres/internal/schema-model.ts +238 -7
  66. package/src/postgres/json.ts +43 -7
  67. package/src/postgres/jsonb.ts +38 -0
  68. package/src/postgres/query-extension.ts +2 -0
  69. package/src/postgres/renderer.ts +31 -4
  70. package/src/postgres/schema-management.ts +17 -12
  71. package/src/postgres/schema.ts +98 -15
  72. package/src/postgres/table.ts +193 -524
  73. package/src/postgres/type.ts +8 -7
  74. package/src/postgres.ts +9 -11
  75. package/src/sqlite/column-extension.ts +3 -0
  76. package/src/sqlite/column.ts +10 -11
  77. package/src/sqlite/datatypes/index.ts +3 -2
  78. package/src/sqlite/executor.ts +7 -5
  79. package/src/sqlite/internal/dialect.ts +9 -4
  80. package/src/sqlite/internal/dsl.ts +208 -155
  81. package/src/sqlite/internal/renderer.ts +6 -2
  82. package/src/sqlite/json.ts +37 -0
  83. package/src/sqlite/query-extension.ts +2 -0
  84. package/src/sqlite/renderer.ts +31 -4
  85. package/src/sqlite.ts +4 -12
  86. package/src/standard/column.ts +163 -0
  87. package/src/standard/datatypes/index.ts +83 -0
  88. package/src/standard/datatypes/spec.ts +98 -0
  89. package/src/standard/dialect.ts +40 -0
  90. package/src/standard/function/aggregate.ts +2 -0
  91. package/src/standard/function/core.ts +2 -0
  92. package/src/standard/function/index.ts +18 -0
  93. package/src/standard/function/string.ts +2 -0
  94. package/src/standard/function/temporal.ts +78 -0
  95. package/src/standard/function/window.ts +2 -0
  96. package/src/standard/internal/renderer.ts +45 -0
  97. package/src/standard/query.ts +152 -0
  98. package/src/standard/renderer.ts +21 -0
  99. package/src/standard/table.ts +147 -0
  100. package/src/standard.ts +18 -0
  101. package/src/internal/aggregation-validation.ts +0 -57
  102. package/src/mysql/table.ts +0 -183
  103. package/src/sqlite/table.ts +0 -183
@@ -1,203 +1,24 @@
1
- import type * as Schema from "effect/Schema"
2
-
3
- import type * as Expression from "../internal/scalar.js"
4
- import { ColumnTypeId, type AnyColumnDefinition } from "../internal/column-state.js"
5
1
  import * as BaseTable from "../internal/table.js"
6
2
  import type { TableOptionSpec } from "../internal/table-options.js"
7
3
 
8
- type Dialect = "postgres"
9
-
10
- type DialectColumn = AnyColumnDefinition & {
11
- readonly [ColumnTypeId]: {
12
- readonly dbType: Expression.DbType.Any & { readonly dialect: Dialect }
13
- }
14
- }
15
-
16
- type DialectFieldMap = Record<string, DialectColumn>
17
-
18
- type InlinePrimaryKeyKeys<Fields extends DialectFieldMap> = Extract<{
19
- [K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never
20
- }[keyof Fields], string>
21
-
22
- export type TableDefinition<
23
- Name extends string,
24
- Fields extends DialectFieldMap,
25
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
26
- Kind extends "schema" | "alias" = "schema",
27
- SchemaName extends string | undefined = "public"
28
- > = BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
29
-
30
- export type TableClassStatic<
31
- Name extends string,
32
- Fields extends DialectFieldMap,
33
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
34
- SchemaName extends string | undefined = "public"
35
- > = BaseTable.TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName>
36
-
37
- export type AnyTable = BaseTable.AnyTable
38
-
39
- type FieldsOfTable<Table> = Table extends BaseTable.TableDefinition<any, infer Fields extends DialectFieldMap, any, any, any>
40
- ? Fields
41
- : Table extends BaseTable.TableClassStatic<any, infer Fields extends DialectFieldMap, any, any>
42
- ? Fields
43
- : never
44
-
45
- type ColumnNamesOfTable<Table> = Extract<keyof FieldsOfTable<Table>, string>
46
-
47
- type PrimaryKeyOfTable<Table> = Table extends BaseTable.TableDefinition<any, any, infer PrimaryKeyColumns extends string, any, any>
48
- ? PrimaryKeyColumns
49
- : Table extends BaseTable.TableClassStatic<any, any, infer PrimaryKeyColumns extends string, any>
50
- ? PrimaryKeyColumns
51
- : never
52
-
53
- type SchemaNameOfTable<Table> = Table extends BaseTable.TableDefinition<any, any, any, any, infer SchemaName>
54
- ? SchemaName
55
- : Table extends BaseTable.TableClassStatic<any, any, any, infer SchemaName>
56
- ? SchemaName
57
- : never
58
-
59
- type ApplySchemaTableOptions<
60
- Name extends string,
61
- Fields extends DialectFieldMap,
62
- PrimaryKeyColumns extends keyof Fields & string,
63
- SchemaName extends string,
64
- Options extends BaseTable.DeclaredTableOptions
65
- > = BaseTable.ApplyDeclaredOptions<
66
- BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
67
- Options
68
- > extends BaseTable.TableDefinition<any, any, infer AppliedPrimaryKeyColumns extends keyof Fields & string, "schema", any>
69
- ? TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName>
70
- : TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
71
-
72
- export type TableSchemaNamespace<SchemaName extends string> = {
73
- readonly schemaName: SchemaName
74
- readonly table: <
75
- Name extends string,
76
- Fields extends DialectFieldMap,
77
- const Options extends BaseTable.DeclaredTableOptions,
78
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
79
- >(
80
- name: Name,
81
- fields: Fields,
82
- ...options: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
83
- ) => ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
84
- }
85
-
86
- export type TableOption = BaseTable.TableOption
87
- export type DdlExpressionLike = BaseTable.DdlExpressionLike
88
- export type IndexKey = BaseTable.IndexKeySpec
89
- export type ReferentialAction = BaseTable.ReferentialAction
90
-
91
- type SchemaTable = {
92
- readonly columns: Record<string, unknown>
93
- }
94
-
95
- type TableExpressionFactory<Table extends SchemaTable> = (
96
- columns: Table["columns"]
97
- ) => DdlExpressionLike
98
-
99
- type TableScopedOptionBuilder<
100
- Table extends SchemaTable,
101
- Spec extends import("../internal/table-options.js").TableOptionSpec = import("../internal/table-options.js").TableOptionSpec
102
- > = {
103
- (table: Table): Table
104
- readonly option: Spec
105
- }
106
-
107
- export const TypeId = BaseTable.TypeId
108
- export const OptionsSymbol = BaseTable.OptionsSymbol
109
- export const options = BaseTable.options
110
-
111
- export const make = <
112
- Name extends string,
113
- Fields extends DialectFieldMap,
114
- SchemaName extends string | undefined = "public"
115
- >(
116
- name: Name,
117
- fields: Fields,
118
- schemaName: SchemaName = "public" as SchemaName
119
- ): TableDefinition<Name, Fields> =>
120
- BaseTable.make(name, fields, schemaName) as TableDefinition<Name, Fields>
4
+ export type {
5
+ DdlExpressionLike,
6
+ IndexKeySpec as IndexKey,
7
+ ReferentialAction,
8
+ TableOption
9
+ } from "../internal/table.js"
121
10
 
122
- export const schema = <SchemaName extends string>(
123
- schemaName: SchemaName
124
- ): TableSchemaNamespace<SchemaName> => {
125
- const table = <
126
- Name extends string,
127
- Fields extends DialectFieldMap,
128
- const Options extends BaseTable.DeclaredTableOptions,
129
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
130
- >(
131
- name: Name,
132
- fields: Fields,
133
- ...declaredOptions: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
134
- ) =>
135
- (BaseTable.schema(schemaName).table as (
136
- name: Name,
137
- fields: Fields,
138
- ...options: BaseTable.DeclaredTableOptions
139
- ) => BaseTable.TableDefinition<any, any, any, "schema", any>)(
140
- name,
141
- fields,
142
- ...declaredOptions
143
- ) as ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
144
- return {
145
- schemaName,
146
- table
147
- } as unknown as TableSchemaNamespace<SchemaName>
148
- }
11
+ type NamedSpec = Extract<TableOptionSpec, { readonly name?: string }>
12
+ type PrimaryKeySpec = Extract<TableOptionSpec, { readonly kind: "primaryKey" }>
13
+ type UniqueSpec = Extract<TableOptionSpec, { readonly kind: "unique" }>
14
+ type IndexSpec = Extract<TableOptionSpec, { readonly kind: "index" }>
15
+ type ForeignKeySpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
16
+ type CheckSpec = Extract<TableOptionSpec, { readonly kind: "check" }>
149
17
 
150
- export const alias = <
151
- Table extends AnyTable,
152
- AliasName extends string
153
- >(
154
- table: Table,
155
- aliasName: AliasName
156
- ): TableDefinition<
157
- AliasName,
158
- FieldsOfTable<Table>,
159
- PrimaryKeyOfTable<Table>,
160
- "alias",
161
- SchemaNameOfTable<Table>
162
- > =>
163
- BaseTable.alias(table as any, aliasName) as TableDefinition<
164
- AliasName,
165
- FieldsOfTable<Table>,
166
- PrimaryKeyOfTable<Table>,
167
- "alias",
168
- SchemaNameOfTable<Table>
169
- >
18
+ type NonEmptyStringArrayInput<Values extends readonly string[]> =
19
+ [Extract<Values[number], "">] extends [never] ? unknown : never
170
20
 
171
- export const Class = <Self = never, SchemaName extends string | undefined = "public">(
172
- name: string,
173
- schemaName: SchemaName = "public" as SchemaName
174
- ) => {
175
- const base = BaseTable.Class<Self, SchemaName>(name, schemaName)
176
- return base as unknown as <
177
- Fields extends DialectFieldMap
178
- >(fields: Fields) => [Self] extends [never]
179
- ? BaseTable.MissingSelfGeneric
180
- : TableClassStatic<typeof name, Fields, InlinePrimaryKeyKeys<Fields>, SchemaName>
181
- }
182
-
183
- export const option = BaseTable.option
184
-
185
- type RichPrimaryKeyInput<Columns extends string | readonly string[]> = {
186
- readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
187
- readonly name?: string
188
- readonly deferrable?: boolean
189
- readonly initiallyDeferred?: boolean
190
- }
191
-
192
- type RichUniqueInput<Columns extends string | readonly string[]> = {
193
- readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
194
- readonly name?: string
195
- readonly nullsNotDistinct?: boolean
196
- readonly deferrable?: boolean
197
- readonly initiallyDeferred?: boolean
198
- }
199
-
200
- type RichIndexKeyInput =
21
+ type IndexKeyInput =
201
22
  | {
202
23
  readonly column: string
203
24
  readonly order?: "asc" | "desc"
@@ -206,158 +27,65 @@ type RichIndexKeyInput =
206
27
  readonly collation?: string
207
28
  }
208
29
  | {
209
- readonly expression: DdlExpressionLike
30
+ readonly expression: BaseTable.DdlExpressionLike
210
31
  readonly order?: "asc" | "desc"
211
32
  readonly nulls?: "first" | "last"
212
33
  readonly operatorClass?: string
213
34
  readonly collation?: string
214
35
  }
215
36
 
216
- type RichIndexDetails = {
217
- readonly name?: string
218
- readonly unique?: boolean
219
- readonly method?: string
220
- readonly include?: readonly string[]
221
- readonly predicate?: DdlExpressionLike
222
- }
223
-
224
- type RichIndexInput<Columns extends string | readonly string[] = string | readonly string[]> = RichIndexDetails & (
225
- | {
226
- readonly columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
227
- readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
228
- }
229
- | {
230
- readonly columns?: Columns & BaseTable.NonEmptyColumnInput<Columns>
231
- readonly keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
232
- }
233
- )
234
-
235
- type PrimaryKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "primaryKey" }>
236
- type UniqueOptionSpec = Extract<TableOptionSpec, { readonly kind: "unique" }>
237
- type IndexOptionSpec = Extract<TableOptionSpec, { readonly kind: "index" }>
238
- type ForeignKeyOptionSpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
239
-
240
- type RichPrimaryKeyOptionSpec<Columns extends string | readonly string[]> = PrimaryKeyOptionSpec & {
241
- readonly kind: "primaryKey"
242
- readonly columns: BaseTable.NormalizeColumns<Columns>
243
- }
244
-
245
- type RichUniqueOptionSpec<Columns extends string | readonly string[]> = UniqueOptionSpec & {
246
- readonly kind: "unique"
247
- readonly columns: BaseTable.NormalizeColumns<Columns>
248
- }
249
-
250
- type KnownTargetColumnsInput<
251
- TargetTable extends AnyTable,
252
- Columns extends string | readonly string[]
253
- > = BaseTable.NormalizeColumns<Columns> extends infer NormalizedColumns extends readonly string[]
254
- ? string extends NormalizedColumns[number]
255
- ? unknown
256
- : Exclude<NormalizedColumns[number], ColumnNamesOfTable<TargetTable>> extends never
257
- ? unknown
258
- : never
37
+ type EmptyIndexKeyColumn<Key> = Key extends { readonly column: infer Column extends string }
38
+ ? BaseTable.NonEmptyStringInput<Column> extends never ? Key : never
259
39
  : never
260
40
 
261
- type RichIndexColumnOption<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
262
- ? { readonly columns: BaseTable.NormalizeColumns<Columns> }
263
- : {}
41
+ type EmptyIndexKeyOperatorClass<Key> = Key extends { readonly operatorClass: infer OperatorClass extends string }
42
+ ? BaseTable.NonEmptyStringInput<OperatorClass> extends never ? Key : never
43
+ : never
264
44
 
265
- type RichIndexIncludeOption<Spec> = Spec extends { readonly include: infer Include extends readonly string[] }
266
- ? { readonly include: Include }
267
- : {}
45
+ type EmptyIndexKeyCollation<Key> = Key extends { readonly collation: infer Collation extends string }
46
+ ? BaseTable.NonEmptyStringInput<Collation> extends never ? Key : never
47
+ : never
268
48
 
269
- type RichIndexKeySpec<Key> = Key extends { readonly column: infer Column extends string }
270
- ? BaseTable.IndexKeySpec & { readonly kind: "column"; readonly column: Column }
271
- : BaseTable.IndexKeySpec & { readonly kind: "expression" }
49
+ type InvalidIndexKeyMetadata<Key> =
50
+ | EmptyIndexKeyColumn<Key>
51
+ | EmptyIndexKeyOperatorClass<Key>
52
+ | EmptyIndexKeyCollation<Key>
53
+
54
+ type NonEmptyIndexKeyInput<Key> =
55
+ [InvalidIndexKeyMetadata<Key>] extends [never] ? unknown : never
56
+
57
+ type NormalizedIndexKey<Key> = Key extends { readonly expression: infer Expression extends BaseTable.DdlExpressionLike }
58
+ ? {
59
+ readonly kind: "expression"
60
+ readonly expression: Expression
61
+ readonly order: Key extends { readonly order: infer Order extends "asc" | "desc" } ? Order : undefined
62
+ readonly nulls: Key extends { readonly nulls: infer Nulls extends "first" | "last" } ? Nulls : undefined
63
+ readonly operatorClass: Key extends { readonly operatorClass: infer OperatorClass extends string } ? OperatorClass : undefined
64
+ readonly collation: Key extends { readonly collation: infer Collation extends string } ? Collation : undefined
65
+ }
66
+ : Key extends { readonly column: infer Column extends string }
67
+ ? {
68
+ readonly kind: "column"
69
+ readonly column: Column
70
+ readonly order: Key extends { readonly order: infer Order extends "asc" | "desc" } ? Order : undefined
71
+ readonly nulls: Key extends { readonly nulls: infer Nulls extends "first" | "last" } ? Nulls : undefined
72
+ readonly operatorClass: Key extends { readonly operatorClass: infer OperatorClass extends string } ? OperatorClass : undefined
73
+ readonly collation: Key extends { readonly collation: infer Collation extends string } ? Collation : undefined
74
+ }
75
+ : never
272
76
 
273
- type RichIndexKeys<Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]> = {
274
- readonly [K in keyof Keys]: Keys[K] extends RichIndexKeyInput ? RichIndexKeySpec<Keys[K]> : never
77
+ type NormalizedIndexKeys<Keys extends readonly [IndexKeyInput, ...IndexKeyInput[]]> = {
78
+ readonly [Index in keyof Keys]: NormalizedIndexKey<Keys[Index]>
275
79
  } & readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
276
80
 
277
- type RichIndexKeysOption<Spec> = Spec extends { readonly keys: infer Keys extends readonly [RichIndexKeyInput, ...RichIndexKeyInput[]] }
278
- ? { readonly keys: RichIndexKeys<Keys> }
279
- : {}
280
-
281
- type RichIndexColumnsConstraint<Spec> = Spec extends { readonly columns: infer Columns extends string | readonly string[] }
282
- ? BaseTable.NonEmptyColumnInput<Columns> extends never ? never : unknown
283
- : unknown
284
-
285
- type RichIndexOptionSpec<Spec> = IndexOptionSpec & {
286
- readonly kind: "index"
287
- readonly name?: string
288
- readonly unique?: boolean
289
- readonly method?: string
290
- readonly predicate?: DdlExpressionLike
291
- } & RichIndexColumnOption<Spec> & RichIndexIncludeOption<Spec> & RichIndexKeysOption<Spec>
292
-
293
- type RichForeignKeyOptionSpec<
294
- LocalColumns extends string | readonly string[],
295
- TargetTable extends AnyTable,
296
- TargetColumns extends string | readonly string[]
297
- > = ForeignKeyOptionSpec & {
298
- readonly kind: "foreignKey"
299
- readonly columns: BaseTable.NormalizeColumns<LocalColumns>
300
- readonly references: () => {
301
- readonly tableName: string
302
- readonly schemaName?: string
303
- readonly columns: BaseTable.NormalizeColumns<TargetColumns>
304
- readonly knownColumns: readonly ColumnNamesOfTable<TargetTable>[]
305
- }
306
- }
81
+ const mapOption = <Next extends TableOptionSpec>(
82
+ next: Next
83
+ ): BaseTable.TableOption<Next> =>
84
+ BaseTable.option(next)
307
85
 
308
- type RichForeignKeyInput<
309
- LocalColumns extends string | readonly string[],
310
- TargetTable extends AnyTable,
311
- TargetColumns extends string | readonly string[]
312
- > = {
313
- readonly columns: LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>
314
- readonly target: () => TargetTable
315
- readonly referencedColumns: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
316
- readonly name?: string
317
- readonly onUpdate?: ReferentialAction
318
- readonly onDelete?: ReferentialAction
319
- readonly deferrable?: boolean
320
- readonly initiallyDeferred?: boolean
321
- }
322
-
323
- type RichCheckInput<Name extends string = string> = {
324
- readonly name: Name
325
- readonly predicate: DdlExpressionLike
326
- readonly noInherit?: boolean
327
- }
328
-
329
- const isObject = (value: unknown): value is Record<string, unknown> =>
330
- typeof value === "object" && value !== null && !Array.isArray(value)
331
-
332
- const isTableExpressionFactory = (value: unknown): value is TableExpressionFactory<SchemaTable> =>
333
- typeof value === "function"
334
-
335
- const makeTableScopedOption = <
336
- Table extends SchemaTable,
337
- Spec extends import("../internal/table-options.js").TableOptionSpec
338
- >(
339
- placeholder: Spec,
340
- resolve: (table: Table) => Spec
341
- ): TableScopedOptionBuilder<Table, Spec> => {
342
- const builder = ((table: Table) =>
343
- BaseTable.option(resolve(table))(table as never)) as unknown as TableScopedOptionBuilder<Table, Spec>
344
- ;(builder as { option: Spec }).option = placeholder
345
- return builder
346
- }
347
-
348
- const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] => {
349
- const normalized = Array.isArray(columns) ? [...columns] : [columns]
350
- if (normalized.length === 0) {
351
- throw new Error("Table options require at least one column")
352
- }
353
- return normalized as unknown as readonly [string, ...string[]]
354
- }
355
-
356
- const normalizeIndexKeys = (
357
- keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
358
- ): readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]] =>
359
- keys.map((key) => "expression" in key
360
- ? {
86
+ const normalizeIndexKey = (key: IndexKeyInput): BaseTable.IndexKeySpec =>
87
+ "expression" in key
88
+ ? {
361
89
  kind: "expression",
362
90
  expression: key.expression,
363
91
  order: key.order,
@@ -372,196 +100,137 @@ const normalizeIndexKeys = (
372
100
  nulls: key.nulls,
373
101
  operatorClass: key.operatorClass,
374
102
  collation: key.collation
375
- }) as unknown as readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
376
-
377
- export const primaryKey: {
378
- <const Columns extends string | readonly string[]>(
379
- columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
380
- ): BaseTable.TableOption<{
381
- readonly kind: "primaryKey"
382
- readonly columns: BaseTable.NormalizeColumns<Columns>
383
- }>
384
- <const Columns extends string | readonly string[]>(
385
- spec: RichPrimaryKeyInput<Columns>
386
- ): BaseTable.TableOption<RichPrimaryKeyOptionSpec<Columns>>
387
- } = ((input: unknown) =>
388
- isObject(input) && "columns" in input
389
- ? BaseTable.option({
390
- kind: "primaryKey",
391
- columns: normalizeColumns((input as RichPrimaryKeyInput<string | readonly string[]>).columns),
392
- name: (input as RichPrimaryKeyInput<string | readonly string[]>).name,
393
- deferrable: (input as RichPrimaryKeyInput<string | readonly string[]>).deferrable,
394
- initiallyDeferred: (input as RichPrimaryKeyInput<string | readonly string[]>).initiallyDeferred
395
- })
396
- : BaseTable.primaryKey(input as string | readonly string[])) as never
397
-
398
- export const unique: {
399
- <const Columns extends string | readonly string[]>(
400
- columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
401
- ): BaseTable.TableOption<{
402
- readonly kind: "unique"
403
- readonly columns: BaseTable.NormalizeColumns<Columns>
404
- }>
405
- <const Columns extends string | readonly string[]>(
406
- spec: RichUniqueInput<Columns>
407
- ): BaseTable.TableOption<RichUniqueOptionSpec<Columns>>
408
- } = ((input: unknown) =>
409
- isObject(input) && "columns" in input && ("name" in input || "nullsNotDistinct" in input || "deferrable" in input || "initiallyDeferred" in input)
410
- ? BaseTable.option({
411
- kind: "unique",
412
- columns: normalizeColumns((input as RichUniqueInput<string | readonly string[]>).columns),
413
- name: (input as RichUniqueInput<string | readonly string[]>).name,
414
- nullsNotDistinct: (input as RichUniqueInput<string | readonly string[]>).nullsNotDistinct,
415
- deferrable: (input as RichUniqueInput<string | readonly string[]>).deferrable,
416
- initiallyDeferred: (input as RichUniqueInput<string | readonly string[]>).initiallyDeferred
417
- })
418
- : BaseTable.unique(input as string | readonly string[])) as never
419
-
420
- export const index: {
421
- <const Columns extends string | readonly string[]>(
422
- columns: Columns & BaseTable.NonEmptyColumnInput<Columns>
423
- ): BaseTable.TableOption<{
424
- readonly kind: "index"
425
- readonly columns: BaseTable.NormalizeColumns<Columns>
426
- }>
427
- <Table extends SchemaTable, const Columns extends string | readonly string[], const Spec extends Omit<RichIndexInput<Columns>, "predicate"> & {
428
- readonly predicate: TableExpressionFactory<Table>
429
- }>(
430
- spec: Spec & RichIndexColumnsConstraint<Spec>
431
- ): TableScopedOptionBuilder<Table, RichIndexOptionSpec<Spec>>
432
- <const Columns extends string | readonly string[], const Spec extends RichIndexInput<Columns>>(
433
- spec: Spec & RichIndexColumnsConstraint<Spec>
434
- ): BaseTable.TableOption<RichIndexOptionSpec<Spec>>
435
- } = ((input: unknown) =>
436
- isObject(input) && ("columns" in input || "keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
437
- ? (() => {
438
- const spec = input as RichIndexInput<string | readonly string[]> & {
439
- readonly predicate?: DdlExpressionLike | TableExpressionFactory<SchemaTable>
440
- }
441
- const predicate = spec.predicate
442
- const placeholder = {
443
- kind: "index" as const,
444
- columns: spec.columns === undefined
445
- ? undefined
446
- : normalizeColumns(spec.columns),
447
- keys: spec.keys === undefined
448
- ? undefined
449
- : normalizeIndexKeys(spec.keys),
450
- name: spec.name,
451
- unique: spec.unique,
452
- method: spec.method,
453
- include: spec.include,
454
- predicate: predicate as unknown as DdlExpressionLike
455
- }
456
- return isTableExpressionFactory(predicate)
457
- ? makeTableScopedOption(placeholder, (table) => ({
458
- ...placeholder,
459
- predicate: predicate(table.columns)
460
- }))
461
- : BaseTable.option({
462
- ...placeholder,
463
- predicate
464
- })
465
- })()
466
- : BaseTable.index(input as string | readonly string[])) as never
467
- export const foreignKey = <
468
- const LocalColumns extends string | readonly string[],
469
- TargetTable extends AnyTable,
470
- const TargetColumns extends string | readonly string[]
471
- >(
472
- columnsOrSpec: (LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>) | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
473
- target?: () => TargetTable,
474
- referencedColumns?: TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
475
- ): BaseTable.TableOption<RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>> =>
476
- isObject(columnsOrSpec) && "columns" in columnsOrSpec && "target" in columnsOrSpec
477
- ? (() => {
478
- const spec = columnsOrSpec as RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>
479
- const targetTable = spec.target()
480
- const targetState = targetTable[BaseTable.TypeId]
481
- return BaseTable.option({
482
- kind: "foreignKey",
483
- columns: normalizeColumns(spec.columns) as BaseTable.NormalizeColumns<LocalColumns>,
484
- name: spec.name,
485
- references: () => ({
486
- tableName: targetState.baseName,
487
- schemaName: targetState.schemaName,
488
- columns: normalizeColumns(spec.referencedColumns) as BaseTable.NormalizeColumns<TargetColumns>,
489
- knownColumns: Object.keys(targetState.fields) as unknown as readonly ColumnNamesOfTable<TargetTable>[]
490
- }),
491
- onUpdate: spec.onUpdate,
492
- onDelete: spec.onDelete,
493
- deferrable: spec.deferrable,
494
- initiallyDeferred: spec.initiallyDeferred
495
- } as RichForeignKeyOptionSpec<LocalColumns, TargetTable, TargetColumns>)
496
- })()
497
- : BaseTable.foreignKey<LocalColumns, TargetTable, TargetColumns>(
498
- columnsOrSpec as LocalColumns & BaseTable.NonEmptyColumnInput<LocalColumns>,
499
- target as () => TargetTable,
500
- referencedColumns as TargetColumns & BaseTable.NonEmptyColumnInput<TargetColumns> & BaseTable.MatchingColumnArityInput<LocalColumns, TargetColumns> & KnownTargetColumnsInput<NoInfer<TargetTable>, TargetColumns>
501
- )
502
-
503
- export const check: {
504
- <Name extends string>(name: Name, predicate: DdlExpressionLike): BaseTable.TableOption
505
- <Name extends string, Table extends SchemaTable>(
506
- name: Name,
507
- predicate: TableExpressionFactory<Table>
508
- ): TableScopedOptionBuilder<Table, {
509
- readonly kind: "check"
510
- readonly name: Name
511
- readonly predicate: DdlExpressionLike
512
- }>
513
- <Name extends string, Table extends SchemaTable>(
514
- spec: Omit<RichCheckInput<Name>, "predicate"> & {
515
- readonly predicate: TableExpressionFactory<Table>
516
- }
517
- ): TableScopedOptionBuilder<Table, {
518
- readonly kind: "check"
519
- readonly name: Name
520
- readonly predicate: DdlExpressionLike
521
- readonly noInherit?: boolean
522
- }>
523
- <Name extends string>(spec: RichCheckInput<Name>): BaseTable.TableOption
524
- } = ((nameOrSpec: string | RichCheckInput, predicate?: DdlExpressionLike) =>
525
- isObject(nameOrSpec)
526
- ? (() => {
527
- const spec = nameOrSpec as RichCheckInput & {
528
- readonly predicate: DdlExpressionLike | TableExpressionFactory<SchemaTable>
529
- }
530
- const specPredicate = spec.predicate
531
- const placeholder = {
532
- kind: "check" as const,
533
- name: spec.name,
534
- predicate: specPredicate as unknown as DdlExpressionLike,
535
- noInherit: spec.noInherit
536
- }
537
- return isTableExpressionFactory(specPredicate)
538
- ? makeTableScopedOption(placeholder, (table) => ({
539
- ...placeholder,
540
- predicate: specPredicate(table.columns)
541
- }))
542
- : BaseTable.option({
543
- ...placeholder,
544
- predicate: specPredicate
545
- })
546
- })()
547
- : (() => {
548
- const predicateOrFactory = predicate as DdlExpressionLike | TableExpressionFactory<SchemaTable>
549
- const placeholder = {
550
- kind: "check" as const,
551
- name: nameOrSpec,
552
- predicate: predicateOrFactory as unknown as DdlExpressionLike
553
- }
554
- return isTableExpressionFactory(predicateOrFactory)
555
- ? makeTableScopedOption(placeholder, (table) => ({
556
- ...placeholder,
557
- predicate: predicateOrFactory(table.columns)
558
- }))
559
- : BaseTable.option({
560
- ...placeholder,
561
- predicate: predicateOrFactory
562
- })
563
- })()) as never
103
+ }
564
104
 
565
- export type SelectOf<Table extends { readonly schemas: { readonly select: Schema.Schema<any> } }> = BaseTable.SelectOf<Table>
566
- export type InsertOf<Table extends { readonly schemas: { readonly insert: Schema.Schema<any> } }> = BaseTable.InsertOf<Table>
567
- export type UpdateOf<Table extends { readonly schemas: { readonly update: Schema.Schema<any> } }> = BaseTable.UpdateOf<Table>
105
+ /** Adds a Postgres constraint or index name to a standard table option. */
106
+ export const named = <const Name extends string>(
107
+ name: BaseTable.NonEmptyStringInput<Name>
108
+ ) =>
109
+ <Spec extends NamedSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly name: Name }> =>
110
+ mapOption({
111
+ ...option.option,
112
+ name
113
+ } as Spec & { readonly name: Name })
114
+
115
+ /** Marks a standard primary key, unique, or foreign-key option as deferrable. */
116
+ export const deferrable = <
117
+ Spec extends PrimaryKeySpec | UniqueSpec | ForeignKeySpec
118
+ >(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly deferrable: true }> =>
119
+ mapOption({
120
+ ...option.option,
121
+ deferrable: true
122
+ } as Spec & { readonly deferrable: true })
123
+
124
+ /** Marks a deferrable standard primary key, unique, or foreign-key option as initially deferred. */
125
+ export const initiallyDeferred = <
126
+ Spec extends PrimaryKeySpec | UniqueSpec | ForeignKeySpec
127
+ >(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
128
+ readonly deferrable: true
129
+ readonly initiallyDeferred: true
130
+ }> =>
131
+ mapOption({
132
+ ...option.option,
133
+ deferrable: true,
134
+ initiallyDeferred: true
135
+ } as Spec & { readonly deferrable: true; readonly initiallyDeferred: true })
136
+
137
+ /** Adds Postgres NULLS NOT DISTINCT to a standard unique option. */
138
+ export const nullsNotDistinct = <Spec extends UniqueSpec>(
139
+ option: BaseTable.TableOption<Spec>
140
+ ): BaseTable.TableOption<Spec & { readonly nullsNotDistinct: true }> =>
141
+ mapOption({
142
+ ...option.option,
143
+ nullsNotDistinct: true
144
+ } as Spec & { readonly nullsNotDistinct: true })
145
+
146
+ /** Marks a standard index option as a Postgres unique index. */
147
+ export const uniqueIndex = <Spec extends IndexSpec>(
148
+ option: BaseTable.TableOption<Spec>
149
+ ): BaseTable.TableOption<Spec & { readonly unique: true }> =>
150
+ mapOption({
151
+ ...option.option,
152
+ unique: true
153
+ } as Spec & { readonly unique: true })
154
+
155
+ /** Adds a Postgres index method to a standard index option. */
156
+ export const using = <const Method extends string>(
157
+ method: BaseTable.NonEmptyStringInput<Method>
158
+ ) =>
159
+ <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly method: Method }> =>
160
+ mapOption({
161
+ ...option.option,
162
+ method
163
+ } as Spec & { readonly method: Method })
164
+
165
+ /** Adds Postgres INCLUDE columns to a standard index option. */
166
+ export const include = <const Include extends readonly string[]>(
167
+ include: Include & NonEmptyStringArrayInput<Include>
168
+ ) =>
169
+ <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly include: Include }> =>
170
+ mapOption({
171
+ ...option.option,
172
+ include
173
+ } as Spec & { readonly include: Include })
174
+
175
+ /** Adds a Postgres partial-index predicate to a standard index option. */
176
+ export const where = <Predicate extends BaseTable.DdlExpressionLike>(
177
+ predicate: Predicate
178
+ ) =>
179
+ <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly predicate: Predicate }> =>
180
+ mapOption({
181
+ ...option.option,
182
+ predicate
183
+ } as Spec & { readonly predicate: Predicate })
184
+
185
+ /** Replaces standard index columns with a single Postgres index key. */
186
+ export const key = <const Key extends IndexKeyInput>(
187
+ key: Key & NonEmptyIndexKeyInput<Key>
188
+ ) =>
189
+ <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
190
+ readonly keys: readonly [NormalizedIndexKey<Key>]
191
+ }> =>
192
+ mapOption({
193
+ ...option.option,
194
+ columns: undefined,
195
+ keys: [normalizeIndexKey(key)]
196
+ } as unknown as Spec & { readonly keys: readonly [NormalizedIndexKey<Key>] })
197
+
198
+ /** Replaces standard index columns with Postgres index keys. */
199
+ export const keys = <const Keys extends readonly [IndexKeyInput, ...IndexKeyInput[]]>(
200
+ keys: Keys & {
201
+ readonly [Index in keyof Keys]: Keys[Index] & NonEmptyIndexKeyInput<Keys[Index]>
202
+ }
203
+ ) =>
204
+ <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
205
+ readonly keys: NormalizedIndexKeys<Keys>
206
+ }> =>
207
+ mapOption({
208
+ ...option.option,
209
+ columns: undefined,
210
+ keys: [normalizeIndexKey(keys[0]), ...keys.slice(1).map(normalizeIndexKey)]
211
+ } as Spec & { readonly keys: NormalizedIndexKeys<Keys> })
212
+
213
+ /** Adds an ON DELETE action to a standard foreign-key option. */
214
+ export const onDelete = (action: BaseTable.ReferentialAction) =>
215
+ <Spec extends ForeignKeySpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly onDelete: BaseTable.ReferentialAction }> =>
216
+ mapOption({
217
+ ...option.option,
218
+ onDelete: action
219
+ } as Spec & { readonly onDelete: BaseTable.ReferentialAction })
220
+
221
+ /** Adds an ON UPDATE action to a standard foreign-key option. */
222
+ export const onUpdate = (action: BaseTable.ReferentialAction) =>
223
+ <Spec extends ForeignKeySpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly onUpdate: BaseTable.ReferentialAction }> =>
224
+ mapOption({
225
+ ...option.option,
226
+ onUpdate: action
227
+ } as Spec & { readonly onUpdate: BaseTable.ReferentialAction })
228
+
229
+ /** Adds Postgres NO INHERIT to a standard check option. */
230
+ export const noInherit = <Spec extends CheckSpec>(
231
+ option: BaseTable.TableOption<Spec>
232
+ ): BaseTable.TableOption<Spec & { readonly noInherit: true }> =>
233
+ mapOption({
234
+ ...option.option,
235
+ noInherit: true
236
+ } as Spec & { readonly noInherit: true })