effect-qb 0.16.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 (128) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +4036 -2418
  4. package/dist/postgres/metadata.js +2536 -625
  5. package/dist/postgres.js +8248 -7857
  6. package/dist/sqlite.js +8854 -0
  7. package/dist/standard.js +8019 -0
  8. package/package.json +15 -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 +7 -13
  18. package/src/internal/dialect-renderers/mysql.ts +2046 -0
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
  20. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
  21. package/src/internal/dialect.ts +37 -0
  22. package/src/internal/dsl-mutation-runtime.ts +29 -10
  23. package/src/internal/dsl-plan-runtime.ts +41 -24
  24. package/src/internal/dsl-query-runtime.ts +11 -31
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
  26. package/src/internal/executor.ts +57 -15
  27. package/src/internal/expression-ast.ts +3 -2
  28. package/src/internal/grouping-key.ts +216 -9
  29. package/src/internal/implication-runtime.ts +3 -2
  30. package/src/internal/json/types.ts +155 -40
  31. package/src/internal/predicate/context.ts +14 -1
  32. package/src/internal/predicate/key.ts +19 -2
  33. package/src/internal/predicate/runtime.ts +30 -3
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +315 -54
  36. package/src/internal/renderer.ts +51 -6
  37. package/src/internal/runtime/driver-value-mapping.ts +58 -0
  38. package/src/internal/runtime/normalize.ts +74 -43
  39. package/src/internal/runtime/schema.ts +5 -3
  40. package/src/internal/runtime/value.ts +153 -30
  41. package/src/internal/scalar.ts +6 -1
  42. package/src/internal/schema-derivation.d.ts +12 -61
  43. package/src/internal/schema-derivation.ts +90 -38
  44. package/src/internal/schema-expression.ts +2 -2
  45. package/src/internal/sql-expression-renderer.ts +19 -0
  46. package/src/internal/standard-dsl.ts +6885 -0
  47. package/src/internal/table-options.ts +229 -62
  48. package/src/internal/table.d.ts +33 -32
  49. package/src/internal/table.ts +469 -160
  50. package/src/mysql/column-extension.ts +3 -0
  51. package/src/mysql/column.ts +27 -12
  52. package/src/mysql/datatypes/index.ts +24 -2
  53. package/src/mysql/errors/catalog.ts +5 -5
  54. package/src/mysql/errors/normalize.ts +2 -2
  55. package/src/mysql/executor.ts +7 -5
  56. package/src/mysql/internal/dialect.ts +9 -4
  57. package/src/mysql/internal/dsl.ts +906 -324
  58. package/src/mysql/internal/renderer.ts +7 -2
  59. package/src/mysql/json.ts +37 -0
  60. package/src/mysql/query-extension.ts +16 -0
  61. package/src/mysql/query.ts +9 -2
  62. package/src/mysql/renderer.ts +31 -4
  63. package/src/mysql.ts +4 -12
  64. package/src/postgres/column-extension.ts +28 -0
  65. package/src/postgres/column.ts +9 -13
  66. package/src/postgres/datatypes/index.d.ts +2 -1
  67. package/src/postgres/datatypes/index.ts +3 -2
  68. package/src/postgres/errors/normalize.ts +2 -2
  69. package/src/postgres/executor.ts +55 -10
  70. package/src/postgres/function/core.ts +20 -4
  71. package/src/postgres/function/index.ts +1 -17
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +850 -359
  74. package/src/postgres/internal/renderer.ts +7 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -9
  76. package/src/postgres/internal/schema-model.ts +244 -10
  77. package/src/postgres/json.ts +100 -24
  78. package/src/postgres/jsonb.ts +38 -0
  79. package/src/postgres/query-extension.ts +2 -0
  80. package/src/postgres/query.ts +9 -2
  81. package/src/postgres/renderer.ts +31 -4
  82. package/src/postgres/schema-management.ts +108 -16
  83. package/src/postgres/schema.ts +98 -15
  84. package/src/postgres/table.ts +203 -398
  85. package/src/postgres/type.ts +8 -7
  86. package/src/postgres.ts +9 -11
  87. package/src/sqlite/column-extension.ts +3 -0
  88. package/src/sqlite/column.ts +127 -0
  89. package/src/sqlite/datatypes/index.ts +80 -0
  90. package/src/sqlite/datatypes/spec.ts +98 -0
  91. package/src/sqlite/errors/catalog.ts +103 -0
  92. package/src/sqlite/errors/fields.ts +19 -0
  93. package/src/sqlite/errors/index.ts +19 -0
  94. package/src/sqlite/errors/normalize.ts +229 -0
  95. package/src/sqlite/errors/requirements.ts +71 -0
  96. package/src/sqlite/errors/types.ts +29 -0
  97. package/src/sqlite/executor.ts +229 -0
  98. package/src/sqlite/function/aggregate.ts +2 -0
  99. package/src/sqlite/function/core.ts +2 -0
  100. package/src/sqlite/function/index.ts +19 -0
  101. package/src/sqlite/function/string.ts +2 -0
  102. package/src/sqlite/function/temporal.ts +100 -0
  103. package/src/sqlite/function/window.ts +2 -0
  104. package/src/sqlite/internal/dialect.ts +42 -0
  105. package/src/sqlite/internal/dsl.ts +6979 -0
  106. package/src/sqlite/internal/renderer.ts +51 -0
  107. package/src/sqlite/json.ts +39 -0
  108. package/src/sqlite/query-extension.ts +2 -0
  109. package/src/sqlite/query.ts +196 -0
  110. package/src/sqlite/renderer.ts +51 -0
  111. package/src/sqlite.ts +14 -0
  112. package/src/standard/column.ts +163 -0
  113. package/src/standard/datatypes/index.ts +83 -0
  114. package/src/standard/datatypes/spec.ts +98 -0
  115. package/src/standard/dialect.ts +40 -0
  116. package/src/standard/function/aggregate.ts +2 -0
  117. package/src/standard/function/core.ts +2 -0
  118. package/src/standard/function/index.ts +18 -0
  119. package/src/standard/function/string.ts +2 -0
  120. package/src/standard/function/temporal.ts +78 -0
  121. package/src/standard/function/window.ts +2 -0
  122. package/src/standard/internal/renderer.ts +45 -0
  123. package/src/standard/query.ts +152 -0
  124. package/src/standard/renderer.ts +21 -0
  125. package/src/standard/table.ts +147 -0
  126. package/src/standard.ts +18 -0
  127. package/src/internal/aggregation-validation.ts +0 -57
  128. package/src/mysql/table.ts +0 -157
@@ -1,145 +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
-
7
- type Dialect = "postgres"
8
-
9
- type DialectColumn = AnyColumnDefinition & {
10
- readonly [ColumnTypeId]: {
11
- readonly dbType: Expression.DbType.Any & { readonly dialect: Dialect }
12
- }
13
- }
14
-
15
- type DialectFieldMap = Record<string, DialectColumn>
16
-
17
- type InlinePrimaryKeyKeys<Fields extends DialectFieldMap> = Extract<{
18
- [K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never
19
- }[keyof Fields], string>
20
-
21
- export type TableDefinition<
22
- Name extends string,
23
- Fields extends DialectFieldMap,
24
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
25
- Kind extends "schema" | "alias" = "schema",
26
- SchemaName extends string | undefined = "public"
27
- > = BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, Kind, SchemaName>
28
-
29
- export type TableClassStatic<
30
- Name extends string,
31
- Fields extends DialectFieldMap,
32
- PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>,
33
- SchemaName extends string | undefined = "public"
34
- > = BaseTable.TableClassStatic<Name, Fields, PrimaryKeyColumns, SchemaName>
35
-
36
- export type AnyTable = BaseTable.AnyTable
37
-
38
- type FieldsOfTable<Table> = Table extends BaseTable.TableDefinition<any, infer Fields extends DialectFieldMap, any, any, any>
39
- ? 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
55
-
56
- export type TableOption = BaseTable.TableOption
57
- export type DdlExpressionLike = BaseTable.DdlExpressionLike
58
- export type IndexKey = BaseTable.IndexKeySpec
59
- export type ReferentialAction = BaseTable.ReferentialAction
60
-
61
- type SchemaTable = {
62
- readonly columns: Record<string, unknown>
63
- }
64
-
65
- type TableExpressionFactory<Table extends SchemaTable> = (
66
- columns: Table["columns"]
67
- ) => DdlExpressionLike
68
-
69
- type TableScopedOptionBuilder<
70
- Table extends SchemaTable,
71
- Spec extends import("../internal/table-options.js").TableOptionSpec = import("../internal/table-options.js").TableOptionSpec
72
- > = {
73
- (table: Table): Table
74
- readonly option: Spec
75
- }
76
-
77
- export const TypeId = BaseTable.TypeId
78
- export const OptionsSymbol = BaseTable.OptionsSymbol
79
- export const options = BaseTable.options
80
-
81
- export const make = <
82
- Name extends string,
83
- Fields extends DialectFieldMap,
84
- SchemaName extends string | undefined = "public"
85
- >(
86
- name: Name,
87
- fields: Fields,
88
- schemaName: SchemaName = "public" as SchemaName
89
- ): TableDefinition<Name, Fields> =>
90
- BaseTable.make(name, fields, schemaName) as TableDefinition<Name, Fields>
91
-
92
- export const alias = <
93
- Table extends AnyTable,
94
- AliasName extends string
95
- >(
96
- table: Table,
97
- aliasName: AliasName
98
- ): TableDefinition<
99
- AliasName,
100
- FieldsOfTable<Table>,
101
- PrimaryKeyOfTable<Table>,
102
- "alias",
103
- SchemaNameOfTable<Table>
104
- > =>
105
- BaseTable.alias(table as any, aliasName) as TableDefinition<
106
- AliasName,
107
- FieldsOfTable<Table>,
108
- PrimaryKeyOfTable<Table>,
109
- "alias",
110
- SchemaNameOfTable<Table>
111
- >
112
-
113
- export const Class = <Self = never, SchemaName extends string | undefined = "public">(
114
- name: string,
115
- schemaName: SchemaName = "public" as SchemaName
116
- ) => {
117
- const base = BaseTable.Class<Self, SchemaName>(name, schemaName)
118
- return base as unknown as <
119
- Fields extends DialectFieldMap
120
- >(fields: Fields) => [Self] extends [never]
121
- ? BaseTable.MissingSelfGeneric
122
- : TableClassStatic<typeof name, Fields, InlinePrimaryKeyKeys<Fields>, SchemaName>
123
- }
124
-
125
- export const option = BaseTable.option
126
-
127
- type RichPrimaryKeyInput<Columns extends string | readonly string[]> = {
128
- readonly columns: Columns
129
- readonly name?: string
130
- readonly deferrable?: boolean
131
- readonly initiallyDeferred?: boolean
132
- }
133
-
134
- type RichUniqueInput<Columns extends string | readonly string[]> = {
135
- readonly columns: Columns
136
- readonly name?: string
137
- readonly nullsNotDistinct?: boolean
138
- readonly deferrable?: boolean
139
- readonly initiallyDeferred?: boolean
140
- }
141
-
142
- type RichIndexKeyInput =
2
+ import type { TableOptionSpec } from "../internal/table-options.js"
3
+
4
+ export type {
5
+ DdlExpressionLike,
6
+ IndexKeySpec as IndexKey,
7
+ ReferentialAction,
8
+ TableOption
9
+ } from "../internal/table.js"
10
+
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" }>
17
+
18
+ type NonEmptyStringArrayInput<Values extends readonly string[]> =
19
+ [Extract<Values[number], "">] extends [never] ? unknown : never
20
+
21
+ type IndexKeyInput =
143
22
  | {
144
23
  readonly column: string
145
24
  readonly order?: "asc" | "desc"
@@ -148,71 +27,65 @@ type RichIndexKeyInput =
148
27
  readonly collation?: string
149
28
  }
150
29
  | {
151
- readonly expression: DdlExpressionLike
30
+ readonly expression: BaseTable.DdlExpressionLike
152
31
  readonly order?: "asc" | "desc"
153
32
  readonly nulls?: "first" | "last"
154
33
  readonly operatorClass?: string
155
34
  readonly collation?: string
156
35
  }
157
36
 
158
- type RichIndexInput<Columns extends string | readonly string[] = string | readonly string[]> = {
159
- readonly columns?: Columns
160
- readonly keys?: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
161
- readonly name?: string
162
- readonly unique?: boolean
163
- readonly method?: string
164
- readonly include?: readonly string[]
165
- readonly predicate?: DdlExpressionLike
166
- }
167
-
168
- type RichForeignKeyInput<
169
- LocalColumns extends string | readonly string[],
170
- TargetTable extends AnyTable,
171
- TargetColumns extends string | readonly string[]
172
- > = {
173
- readonly columns: LocalColumns
174
- readonly target: () => TargetTable
175
- readonly referencedColumns: TargetColumns
176
- readonly name?: string
177
- readonly onUpdate?: ReferentialAction
178
- readonly onDelete?: ReferentialAction
179
- readonly deferrable?: boolean
180
- readonly initiallyDeferred?: boolean
181
- }
182
-
183
- type RichCheckInput<Name extends string = string> = {
184
- readonly name: Name
185
- readonly predicate: DdlExpressionLike
186
- readonly noInherit?: boolean
187
- }
188
-
189
- const isObject = (value: unknown): value is Record<string, unknown> =>
190
- typeof value === "object" && value !== null && !Array.isArray(value)
191
-
192
- const isTableExpressionFactory = (value: unknown): value is TableExpressionFactory<SchemaTable> =>
193
- typeof value === "function"
37
+ type EmptyIndexKeyColumn<Key> = Key extends { readonly column: infer Column extends string }
38
+ ? BaseTable.NonEmptyStringInput<Column> extends never ? Key : never
39
+ : never
40
+
41
+ type EmptyIndexKeyOperatorClass<Key> = Key extends { readonly operatorClass: infer OperatorClass extends string }
42
+ ? BaseTable.NonEmptyStringInput<OperatorClass> extends never ? Key : never
43
+ : never
44
+
45
+ type EmptyIndexKeyCollation<Key> = Key extends { readonly collation: infer Collation extends string }
46
+ ? BaseTable.NonEmptyStringInput<Collation> extends never ? Key : never
47
+ : never
48
+
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
194
76
 
195
- const makeTableScopedOption = <
196
- Table extends SchemaTable,
197
- Spec extends import("../internal/table-options.js").TableOptionSpec
198
- >(
199
- placeholder: Spec,
200
- resolve: (table: Table) => Spec
201
- ): TableScopedOptionBuilder<Table, Spec> => {
202
- const builder = ((table: Table) =>
203
- BaseTable.option(resolve(table))(table as never)) as unknown as TableScopedOptionBuilder<Table, Spec>
204
- ;(builder as { option: Spec }).option = placeholder
205
- return builder
206
- }
77
+ type NormalizedIndexKeys<Keys extends readonly [IndexKeyInput, ...IndexKeyInput[]]> = {
78
+ readonly [Index in keyof Keys]: NormalizedIndexKey<Keys[Index]>
79
+ } & readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
207
80
 
208
- const normalizeColumns = (columns: string | readonly string[]): readonly [string, ...string[]] =>
209
- (Array.isArray(columns) ? [...columns] : [columns]) as unknown as readonly [string, ...string[]]
81
+ const mapOption = <Next extends TableOptionSpec>(
82
+ next: Next
83
+ ): BaseTable.TableOption<Next> =>
84
+ BaseTable.option(next)
210
85
 
211
- const normalizeIndexKeys = (
212
- keys: readonly [RichIndexKeyInput, ...RichIndexKeyInput[]]
213
- ): readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]] =>
214
- keys.map((key) => "expression" in key
215
- ? {
86
+ const normalizeIndexKey = (key: IndexKeyInput): BaseTable.IndexKeySpec =>
87
+ "expression" in key
88
+ ? {
216
89
  kind: "expression",
217
90
  expression: key.expression,
218
91
  order: key.order,
@@ -227,205 +100,137 @@ const normalizeIndexKeys = (
227
100
  nulls: key.nulls,
228
101
  operatorClass: key.operatorClass,
229
102
  collation: key.collation
230
- }) as unknown as readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
231
-
232
- export const primaryKey: {
233
- <const Columns extends string | readonly string[]>(
234
- columns: Columns
235
- ): BaseTable.TableOption<{
236
- readonly kind: "primaryKey"
237
- readonly columns: BaseTable.NormalizeColumns<Columns>
238
- }>
239
- <const Columns extends string | readonly string[]>(
240
- spec: RichPrimaryKeyInput<Columns>
241
- ): BaseTable.TableOption
242
- } = ((input: unknown) =>
243
- isObject(input) && "columns" in input
244
- ? BaseTable.option({
245
- kind: "primaryKey",
246
- columns: normalizeColumns((input as RichPrimaryKeyInput<string | readonly string[]>).columns),
247
- name: (input as RichPrimaryKeyInput<string | readonly string[]>).name,
248
- deferrable: (input as RichPrimaryKeyInput<string | readonly string[]>).deferrable,
249
- initiallyDeferred: (input as RichPrimaryKeyInput<string | readonly string[]>).initiallyDeferred
250
- })
251
- : BaseTable.primaryKey(input as string | readonly string[])) as never
252
-
253
- export const unique: {
254
- <const Columns extends string | readonly string[]>(
255
- columns: Columns
256
- ): BaseTable.TableOption<{
257
- readonly kind: "unique"
258
- readonly columns: BaseTable.NormalizeColumns<Columns>
259
- }>
260
- <const Columns extends string | readonly string[]>(
261
- spec: RichUniqueInput<Columns>
262
- ): BaseTable.TableOption
263
- } = ((input: unknown) =>
264
- isObject(input) && "columns" in input && ("name" in input || "nullsNotDistinct" in input || "deferrable" in input || "initiallyDeferred" in input)
265
- ? BaseTable.option({
266
- kind: "unique",
267
- columns: normalizeColumns((input as RichUniqueInput<string | readonly string[]>).columns),
268
- name: (input as RichUniqueInput<string | readonly string[]>).name,
269
- nullsNotDistinct: (input as RichUniqueInput<string | readonly string[]>).nullsNotDistinct,
270
- deferrable: (input as RichUniqueInput<string | readonly string[]>).deferrable,
271
- initiallyDeferred: (input as RichUniqueInput<string | readonly string[]>).initiallyDeferred
272
- })
273
- : BaseTable.unique(input as string | readonly string[])) as never
274
-
275
- export const index: {
276
- <const Columns extends string | readonly string[]>(
277
- columns: Columns
278
- ): BaseTable.TableOption<{
279
- readonly kind: "index"
280
- readonly columns: BaseTable.NormalizeColumns<Columns>
281
- }>
282
- <Table extends SchemaTable, const Columns extends string | readonly string[]>(
283
- spec: Omit<RichIndexInput<Columns>, "predicate"> & {
284
- 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
299
- } = ((input: unknown) =>
300
- isObject(input) && ("keys" in input || "name" in input || "unique" in input || "method" in input || "include" in input || "predicate" in input)
301
- ? (() => {
302
- const spec = input as RichIndexInput<string | readonly string[]> & {
303
- readonly predicate?: DdlExpressionLike | TableExpressionFactory<SchemaTable>
304
- }
305
- const predicate = spec.predicate
306
- const placeholder = {
307
- kind: "index" as const,
308
- columns: spec.columns === undefined
309
- ? undefined
310
- : normalizeColumns(spec.columns),
311
- keys: spec.keys === undefined
312
- ? undefined
313
- : normalizeIndexKeys(spec.keys),
314
- name: spec.name,
315
- unique: spec.unique,
316
- method: spec.method,
317
- include: spec.include,
318
- predicate: predicate as unknown as DdlExpressionLike
319
- }
320
- return isTableExpressionFactory(predicate)
321
- ? makeTableScopedOption(placeholder, (table) => ({
322
- ...placeholder,
323
- predicate: predicate(table.columns)
324
- }))
325
- : BaseTable.option({
326
- ...placeholder,
327
- predicate
328
- })
329
- })()
330
- : BaseTable.index(input as string | readonly string[])) as never
331
- export const foreignKey = <
332
- const LocalColumns extends string | readonly string[],
333
- TargetTable extends AnyTable,
334
- const TargetColumns extends string | readonly string[]
335
- >(
336
- columnsOrSpec: LocalColumns | RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>,
337
- target?: () => TargetTable,
338
- referencedColumns?: TargetColumns
339
- ): BaseTable.TableOption =>
340
- isObject(columnsOrSpec) && "columns" in columnsOrSpec && "target" in columnsOrSpec
341
- ? (() => {
342
- const spec = columnsOrSpec as RichForeignKeyInput<LocalColumns, TargetTable, TargetColumns>
343
- const targetTable = spec.target() as BaseTable.AnyTable
344
- const targetState = targetTable[BaseTable.TypeId]
345
- 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
- })
360
- })()
361
- : BaseTable.foreignKey(
362
- columnsOrSpec as LocalColumns,
363
- target as () => BaseTable.AnyTable,
364
- referencedColumns as TargetColumns
365
- )
366
-
367
- export const check: {
368
- <Name extends string>(name: Name, predicate: DdlExpressionLike): BaseTable.TableOption
369
- <Name extends string, Table extends SchemaTable>(
370
- name: Name,
371
- predicate: TableExpressionFactory<Table>
372
- ): TableScopedOptionBuilder<Table, {
373
- readonly kind: "check"
374
- readonly name: Name
375
- readonly predicate: DdlExpressionLike
376
- }>
377
- <Name extends string, Table extends SchemaTable>(
378
- spec: Omit<RichCheckInput<Name>, "predicate"> & {
379
- readonly predicate: TableExpressionFactory<Table>
380
- }
381
- ): TableScopedOptionBuilder<Table, {
382
- readonly kind: "check"
383
- readonly name: Name
384
- readonly predicate: DdlExpressionLike
385
- readonly noInherit?: boolean
386
- }>
387
- <Name extends string>(spec: RichCheckInput<Name>): BaseTable.TableOption
388
- } = ((nameOrSpec: string | RichCheckInput, predicate?: DdlExpressionLike) =>
389
- isObject(nameOrSpec)
390
- ? (() => {
391
- const spec = nameOrSpec as RichCheckInput & {
392
- readonly predicate: DdlExpressionLike | TableExpressionFactory<SchemaTable>
393
- }
394
- const specPredicate = spec.predicate
395
- const placeholder = {
396
- kind: "check" as const,
397
- name: spec.name,
398
- predicate: specPredicate as unknown as DdlExpressionLike,
399
- noInherit: spec.noInherit
400
- }
401
- return isTableExpressionFactory(specPredicate)
402
- ? makeTableScopedOption(placeholder, (table) => ({
403
- ...placeholder,
404
- predicate: specPredicate(table.columns)
405
- }))
406
- : BaseTable.option({
407
- ...placeholder,
408
- predicate: specPredicate
409
- })
410
- })()
411
- : (() => {
412
- const predicateOrFactory = predicate as DdlExpressionLike | TableExpressionFactory<SchemaTable>
413
- const placeholder = {
414
- kind: "check" as const,
415
- name: nameOrSpec,
416
- predicate: predicateOrFactory as unknown as DdlExpressionLike
417
- }
418
- return isTableExpressionFactory(predicateOrFactory)
419
- ? makeTableScopedOption(placeholder, (table) => ({
420
- ...placeholder,
421
- predicate: predicateOrFactory(table.columns)
422
- }))
423
- : BaseTable.option({
424
- ...placeholder,
425
- predicate: predicateOrFactory
426
- })
427
- })()) as never
103
+ }
428
104
 
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>
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 })
@@ -1,4 +1,5 @@
1
1
  import type * as Expression from "../internal/scalar.js"
2
+ import type { NonEmptyStringInput } from "../internal/table-options.js"
2
3
  import { postgresDatatypes } from "./datatypes/index.js"
3
4
  import { type as postgresType } from "./internal/dsl.js"
4
5
 
@@ -7,24 +8,24 @@ type PostgresTypeNamespace = typeof postgresDatatypes & {
7
8
  element: Element
8
9
  ) => Expression.DbType.Array<"postgres", Element, `${Element["kind"]}[]`>
9
10
  readonly range: <Kind extends string, Subtype extends Expression.DbType.Any>(
10
- kind: Kind,
11
+ kind: NonEmptyStringInput<Kind>,
11
12
  subtype: Subtype
12
13
  ) => Expression.DbType.Range<"postgres", Subtype, Kind>
13
14
  readonly multirange: <Kind extends string, Subtype extends Expression.DbType.Any>(
14
- kind: Kind,
15
+ kind: NonEmptyStringInput<Kind>,
15
16
  subtype: Subtype
16
17
  ) => Expression.DbType.Multirange<"postgres", Subtype, Kind>
17
18
  readonly record: <Kind extends string, Fields extends Record<string, Expression.DbType.Any>>(
18
- kind: Kind,
19
+ kind: NonEmptyStringInput<Kind>,
19
20
  fields: Fields
20
21
  ) => Expression.DbType.Composite<"postgres", Fields, Kind>
21
22
  readonly domain: <Kind extends string, Base extends Expression.DbType.Any>(
22
- kind: Kind,
23
+ kind: NonEmptyStringInput<Kind>,
23
24
  base: Base
24
25
  ) => Expression.DbType.Domain<"postgres", Base, Kind>
25
- readonly enum: <Kind extends string>(kind: Kind) => Expression.DbType.Enum<"postgres", Kind>
26
- readonly set: <Kind extends string>(kind: Kind) => Expression.DbType.Set<"postgres", Kind>
27
- readonly custom: <Kind extends string>(kind: Kind) => Expression.DbType.Base<"postgres", Kind>
26
+ readonly enum: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Enum<"postgres", Kind>
27
+ readonly set: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Set<"postgres", Kind>
28
+ readonly custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Base<"postgres", Kind>
28
29
  readonly driverValueMapping: <Db extends Expression.DbType.Any>(
29
30
  dbType: Db,
30
31
  mapping: Expression.DriverValueMapping