effect-qb 0.19.0 → 0.20.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 (92) hide show
  1. package/README.md +7 -1
  2. package/dist/index.js +1990 -679
  3. package/dist/mysql.js +1490 -617
  4. package/dist/postgres/metadata.js +1334 -263
  5. package/dist/postgres.js +3376 -2307
  6. package/dist/sqlite.js +1573 -628
  7. package/dist/standard.js +1984 -673
  8. package/package.json +2 -4
  9. package/src/internal/coercion/rules.ts +13 -1
  10. package/src/internal/column-state.d.ts +3 -3
  11. package/src/internal/column-state.ts +13 -12
  12. package/src/internal/column.ts +8 -8
  13. package/src/internal/datatypes/define.ts +5 -0
  14. package/src/internal/datatypes/lookup.ts +67 -18
  15. package/src/internal/datatypes/matrix.ts +903 -0
  16. package/src/internal/datatypes/shape.ts +2 -0
  17. package/src/internal/dialect-renderers/mysql.ts +6 -4
  18. package/src/internal/dialect-renderers/postgres.ts +6 -4
  19. package/src/internal/dialect-renderers/sqlite.ts +6 -4
  20. package/src/internal/dialect.ts +1 -1
  21. package/src/internal/executor.ts +56 -43
  22. package/src/internal/json/path-access.ts +351 -0
  23. package/src/internal/query.d.ts +1 -1
  24. package/src/internal/query.ts +1 -1
  25. package/src/internal/runtime/driver-value-mapping.ts +3 -3
  26. package/src/internal/runtime/schema.ts +28 -38
  27. package/src/internal/runtime/value.ts +20 -23
  28. package/src/internal/scalar.d.ts +1 -1
  29. package/src/internal/scalar.ts +2 -1
  30. package/src/internal/schema-derivation.d.ts +7 -7
  31. package/src/internal/schema-derivation.ts +11 -11
  32. package/src/internal/standard-dsl.ts +121 -28
  33. package/src/internal/table.ts +451 -120
  34. package/src/mysql/column.ts +6 -6
  35. package/src/mysql/datatypes/index.ts +1 -0
  36. package/src/mysql/datatypes/spec.ts +6 -176
  37. package/src/mysql/errors/normalize.ts +0 -1
  38. package/src/mysql/executor.ts +4 -6
  39. package/src/mysql/function/temporal.ts +1 -1
  40. package/src/mysql/internal/dsl.ts +116 -16
  41. package/src/mysql/json.ts +1 -33
  42. package/src/mysql/renderer.ts +13 -6
  43. package/src/mysql/type.ts +60 -0
  44. package/src/mysql.ts +3 -1
  45. package/src/postgres/check.ts +1 -0
  46. package/src/postgres/column.ts +11 -11
  47. package/src/postgres/datatypes/index.ts +1 -0
  48. package/src/postgres/datatypes/spec.ts +6 -260
  49. package/src/postgres/errors/normalize.ts +0 -1
  50. package/src/postgres/executor.ts +4 -6
  51. package/src/postgres/foreign-key.ts +24 -0
  52. package/src/postgres/function/temporal.ts +1 -1
  53. package/src/postgres/index.ts +1 -0
  54. package/src/postgres/internal/dsl.ts +122 -21
  55. package/src/postgres/json-extension.ts +7 -0
  56. package/src/postgres/json.ts +726 -173
  57. package/src/postgres/jsonb.ts +0 -1
  58. package/src/postgres/primary-key.ts +24 -0
  59. package/src/postgres/renderer.ts +13 -6
  60. package/src/postgres/schema-management.ts +1 -6
  61. package/src/postgres/schema.ts +16 -8
  62. package/src/postgres/table.ts +111 -113
  63. package/src/postgres/type.ts +86 -4
  64. package/src/postgres/unique.ts +32 -0
  65. package/src/postgres.ts +12 -6
  66. package/src/sqlite/column.ts +6 -6
  67. package/src/sqlite/datatypes/index.ts +1 -0
  68. package/src/sqlite/datatypes/spec.ts +6 -94
  69. package/src/sqlite/errors/normalize.ts +0 -1
  70. package/src/sqlite/executor.ts +4 -6
  71. package/src/sqlite/function/temporal.ts +1 -1
  72. package/src/sqlite/internal/dsl.ts +100 -5
  73. package/src/sqlite/json.ts +1 -32
  74. package/src/sqlite/renderer.ts +13 -6
  75. package/src/sqlite/type.ts +40 -0
  76. package/src/sqlite.ts +3 -1
  77. package/src/standard/cast.ts +113 -0
  78. package/src/standard/check.ts +17 -0
  79. package/src/standard/column.ts +10 -10
  80. package/src/standard/datatypes/index.ts +2 -2
  81. package/src/standard/datatypes/spec.ts +10 -96
  82. package/src/standard/foreign-key.ts +37 -0
  83. package/src/standard/function/temporal.ts +1 -1
  84. package/src/standard/index.ts +17 -0
  85. package/src/standard/json.ts +883 -0
  86. package/src/standard/primary-key.ts +17 -0
  87. package/src/standard/renderer.ts +31 -3
  88. package/src/standard/table.ts +25 -21
  89. package/src/standard/unique.ts +17 -0
  90. package/src/standard.ts +14 -0
  91. package/src/internal/table.d.ts +0 -174
  92. package/src/postgres/cast.ts +0 -45
@@ -7,7 +7,6 @@ export const index = jsonb.index
7
7
  export const wildcard = jsonb.wildcard
8
8
  export const slice = jsonb.slice
9
9
  export const descend = jsonb.descend
10
- export const path = jsonb.path
11
10
  export const get = jsonb.get
12
11
  export const access = jsonb.access
13
12
  export const traverse = jsonb.traverse
@@ -0,0 +1,24 @@
1
+ import * as BaseTable from "../internal/table.js"
2
+ import type { TableOptionSpec } from "../internal/table-options.js"
3
+
4
+ type PrimaryKeySpec = Extract<TableOptionSpec, { readonly kind: "primaryKey" }>
5
+
6
+ export const deferrable = <Spec extends PrimaryKeySpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
7
+ option: BaseTable.TableOption<Spec, TableContext>
8
+ ): BaseTable.TableOption<Spec & { readonly deferrable: true }, TableContext> =>
9
+ BaseTable.mapOption(option, (spec) => ({
10
+ ...spec,
11
+ deferrable: true
12
+ } as Spec & { readonly deferrable: true }))
13
+
14
+ export const initiallyDeferred = <Spec extends PrimaryKeySpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
15
+ option: BaseTable.TableOption<Spec, TableContext>
16
+ ): BaseTable.TableOption<Spec & {
17
+ readonly deferrable: true
18
+ readonly initiallyDeferred: true
19
+ }, TableContext> =>
20
+ BaseTable.mapOption(option, (spec) => ({
21
+ ...spec,
22
+ deferrable: true,
23
+ initiallyDeferred: true
24
+ } as Spec & { readonly deferrable: true; readonly initiallyDeferred: true }))
@@ -20,6 +20,9 @@ export type ValueMappings = Expression.DriverValueMappingsFor<PostgresDatatypeKi
20
20
 
21
21
  export interface MakeOptions {
22
22
  readonly valueMappings?: ValueMappings
23
+ }
24
+
25
+ interface RendererState extends MakeOptions {
23
26
  readonly casing?: Casing.Options
24
27
  }
25
28
 
@@ -33,19 +36,23 @@ const RendererProto = {
33
36
  }
34
37
 
35
38
  /** Creates the built-in Postgres renderer. */
36
- export const make = (options: MakeOptions = {}): Renderer => {
37
- const renderer = CoreRenderer.makeTrusted("postgres", (plan) => renderPostgresPlan(plan, options))
39
+ const makeWithState = (state: RendererState = {}): Renderer => {
40
+ const renderer = CoreRenderer.makeTrusted("postgres", (plan) => renderPostgresPlan(plan, state))
38
41
  return Object.assign(Object.create(RendererProto), renderer, {
39
42
  [Casing.TypeId]: {
40
- casing: options.casing
43
+ casing: state.casing
41
44
  },
42
45
  withCasing: (override: Casing.Options) =>
43
- make({
44
- ...options,
45
- casing: Casing.merge(options.casing, override)
46
+ makeWithState({
47
+ ...state,
48
+ casing: Casing.merge(state.casing, override)
46
49
  })
47
50
  }) as Renderer
48
51
  }
49
52
 
53
+ /** Creates the built-in Postgres renderer. */
54
+ export const make = (options: MakeOptions = {}): Renderer =>
55
+ makeWithState({ valueMappings: options.valueMappings })
56
+
50
57
  /** Shared built-in Postgres renderer instance. */
51
58
  export const postgres = make()
@@ -138,13 +138,8 @@ const EnumProto = {
138
138
  }
139
139
  },
140
140
  column(this: EnumDefinition) {
141
- const [first, ...rest] = this.values
142
- const values: readonly [Schema.Schema.Any, ...Schema.Schema.Any[]] = [
143
- Schema.Literal(first),
144
- ...rest.map((value) => Schema.Literal(value))
145
- ]
146
141
  return makeColumnDefinition(
147
- values.length === 1 ? values[0]! : Schema.Union(...values),
142
+ Schema.Literals(this.values),
148
143
  {
149
144
  dbType: this.type(),
150
145
  nullable: false,
@@ -27,14 +27,21 @@ type ApplySchemaTableOptions<
27
27
  > = BaseTable.ApplyDeclaredOptions<
28
28
  BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
29
29
  Options
30
- > extends BaseTable.TableDefinition<any, any, infer AppliedPrimaryKeyColumns extends keyof Fields & string, "schema", any>
31
- ? BaseTable.TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName>
30
+ > extends BaseTable.TableDefinition<
31
+ any,
32
+ any,
33
+ infer AppliedPrimaryKeyColumns extends keyof Fields & string,
34
+ "schema",
35
+ any,
36
+ infer AppliedConflictArbiters extends BaseTable.ConflictArbiter
37
+ >
38
+ ? BaseTable.TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName, AppliedConflictArbiters>
32
39
  : BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
33
40
 
34
41
  type ValidatePostgresSchemaTable<
35
- Table extends BaseTable.TableDefinition<any, any, any, any, any>
36
- > = Table extends BaseTable.TableDefinition<any, infer Fields extends TableFieldMap, any, any, any>
37
- ? BaseTable.TableDefinition<any, Fields & ValidatePostgresSchemaFields<Fields>, any, any, any>
42
+ Table extends BaseTable.TableDefinition<any, any, any, any, any, any>
43
+ > = Table extends BaseTable.TableDefinition<any, infer Fields extends TableFieldMap, any, any, any, any>
44
+ ? BaseTable.TableDefinition<any, Fields & ValidatePostgresSchemaFields<Fields>, any, any, any, any>
38
45
  : never
39
46
 
40
47
  export type SchemaNamespace<SchemaName extends string> = Pipeable & {
@@ -62,13 +69,14 @@ export type SchemaNamespace<SchemaName extends string> = Pipeable & {
62
69
  name: BaseTable.NonEmptyStringInput<Name>
63
70
  ) => SequenceDefinition<Name, SchemaName>
64
71
  readonly withSchema: <
65
- Table extends BaseTable.TableDefinition<any, any, any, any, any>
72
+ Table extends BaseTable.TableDefinition<any, any, any, any, any, any>
66
73
  >(table: Table & ValidatePostgresSchemaTable<Table>) => BaseTable.TableDefinition<
67
74
  Table[typeof BaseTable.TypeId]["name"],
68
75
  Table[typeof BaseTable.TypeId]["fields"],
69
76
  Table[typeof BaseTable.TypeId]["primaryKey"][number],
70
77
  Table[typeof BaseTable.TypeId]["kind"],
71
- SchemaName
78
+ SchemaName,
79
+ Table[typeof BaseTable.TypeId]["conflictArbiters"][number]
72
80
  >
73
81
  readonly [Casing.TypeId]: Casing.State
74
82
  readonly withCasing: (options: Casing.Options) => SchemaNamespace<SchemaName>
@@ -107,7 +115,7 @@ export const make = <SchemaName extends string>(
107
115
  name: BaseTable.NonEmptyStringInput<Name>
108
116
  ) => sequence(Casing.applyCategory(options.casing, "sequences", name), physicalSchemaName) as SequenceDefinition<Name, SchemaName>
109
117
  namespace.withSchema = <
110
- Table extends BaseTable.TableDefinition<any, any, any, any, any>
118
+ Table extends BaseTable.TableDefinition<any, any, any, any, any, any>
111
119
  >(table: Table & ValidatePostgresSchemaTable<Table>) => BaseTable.withSchema(table, schemaName, options.casing)
112
120
  namespace[Casing.TypeId] = {
113
121
  casing: options.casing
@@ -15,28 +15,20 @@ type IndexSpec = Extract<TableOptionSpec, { readonly kind: "index" }>
15
15
  type ForeignKeySpec = Extract<TableOptionSpec, { readonly kind: "foreignKey" }>
16
16
  type CheckSpec = Extract<TableOptionSpec, { readonly kind: "check" }>
17
17
 
18
- type NonEmptyStringArrayInput<Values extends readonly string[]> =
19
- [Extract<Values[number], "">] extends [never] ? unknown : never
20
-
21
- type IndexKeyInput =
18
+ type IndexKeyOptions = {
19
+ readonly order?: "asc" | "desc"
20
+ readonly nulls?: "first" | "last"
21
+ readonly operatorClass?: string
22
+ readonly collation?: string
23
+ }
24
+
25
+ type IndexKeyInput<Table extends BaseTable.SchemaTableDefinition = BaseTable.SchemaTableDefinition> =
22
26
  | {
23
- readonly column: string
24
- readonly order?: "asc" | "desc"
25
- readonly nulls?: "first" | "last"
26
- readonly operatorClass?: string
27
- readonly collation?: string
28
- }
27
+ readonly column: BaseTable.TableColumn<Table>
28
+ } & IndexKeyOptions
29
29
  | {
30
30
  readonly expression: BaseTable.DdlExpressionLike
31
- readonly order?: "asc" | "desc"
32
- readonly nulls?: "first" | "last"
33
- readonly operatorClass?: string
34
- readonly collation?: string
35
- }
36
-
37
- type EmptyIndexKeyColumn<Key> = Key extends { readonly column: infer Column extends string }
38
- ? BaseTable.NonEmptyStringInput<Column> extends never ? Key : never
39
- : never
31
+ } & IndexKeyOptions
40
32
 
41
33
  type EmptyIndexKeyOperatorClass<Key> = Key extends { readonly operatorClass: infer OperatorClass extends string }
42
34
  ? BaseTable.NonEmptyStringInput<OperatorClass> extends never ? Key : never
@@ -47,7 +39,6 @@ type EmptyIndexKeyCollation<Key> = Key extends { readonly collation: infer Colla
47
39
  : never
48
40
 
49
41
  type InvalidIndexKeyMetadata<Key> =
50
- | EmptyIndexKeyColumn<Key>
51
42
  | EmptyIndexKeyOperatorClass<Key>
52
43
  | EmptyIndexKeyCollation<Key>
53
44
 
@@ -63,10 +54,10 @@ type NormalizedIndexKey<Key> = Key extends { readonly expression: infer Expressi
63
54
  readonly operatorClass: Key extends { readonly operatorClass: infer OperatorClass extends string } ? OperatorClass : undefined
64
55
  readonly collation: Key extends { readonly collation: infer Collation extends string } ? Collation : undefined
65
56
  }
66
- : Key extends { readonly column: infer Column extends string }
57
+ : Key extends { readonly column: infer Column extends BaseTable.AnyColumnSelection }
67
58
  ? {
68
59
  readonly kind: "column"
69
- readonly column: Column
60
+ readonly column: BaseTable.SelectedColumns<Column>[number]
70
61
  readonly order: Key extends { readonly order: infer Order extends "asc" | "desc" } ? Order : undefined
71
62
  readonly nulls: Key extends { readonly nulls: infer Nulls extends "first" | "last" } ? Nulls : undefined
72
63
  readonly operatorClass: Key extends { readonly operatorClass: infer OperatorClass extends string } ? OperatorClass : undefined
@@ -74,15 +65,6 @@ type NormalizedIndexKey<Key> = Key extends { readonly expression: infer Expressi
74
65
  }
75
66
  : never
76
67
 
77
- type NormalizedIndexKeys<Keys extends readonly [IndexKeyInput, ...IndexKeyInput[]]> = {
78
- readonly [Index in keyof Keys]: NormalizedIndexKey<Keys[Index]>
79
- } & readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
80
-
81
- const mapOption = <Next extends TableOptionSpec>(
82
- next: Next
83
- ): BaseTable.TableOption<Next> =>
84
- BaseTable.option(next)
85
-
86
68
  const normalizeIndexKey = (key: IndexKeyInput): BaseTable.IndexKeySpec =>
87
69
  "expression" in key
88
70
  ? {
@@ -95,7 +77,7 @@ const normalizeIndexKey = (key: IndexKeyInput): BaseTable.IndexKeySpec =>
95
77
  }
96
78
  : {
97
79
  kind: "column",
98
- column: key.column,
80
+ column: BaseTable.selectedColumnList(key.column)[0]!,
99
81
  order: key.order,
100
82
  nulls: key.nulls,
101
83
  operatorClass: key.operatorClass,
@@ -106,131 +88,147 @@ const normalizeIndexKey = (key: IndexKeyInput): BaseTable.IndexKeySpec =>
106
88
  export const named = <const Name extends string>(
107
89
  name: BaseTable.NonEmptyStringInput<Name>
108
90
  ) =>
109
- <Spec extends NamedSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly name: Name }> =>
110
- mapOption({
111
- ...option.option,
91
+ <Spec extends NamedSpec, TableContext extends BaseTable.SchemaTableDefinition>(
92
+ option: BaseTable.TableOption<Spec, TableContext>
93
+ ): BaseTable.TableOption<Spec & { readonly name: Name }, TableContext> =>
94
+ BaseTable.mapOption(option, (spec) => ({
95
+ ...spec,
112
96
  name
113
- } as Spec & { readonly name: Name })
97
+ } as Spec & { readonly name: Name }))
114
98
 
115
99
  /** Marks a standard primary key, unique, or foreign-key option as deferrable. */
116
100
  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,
101
+ Spec extends PrimaryKeySpec | UniqueSpec | ForeignKeySpec,
102
+ TableContext extends BaseTable.SchemaTableDefinition
103
+ >(option: BaseTable.TableOption<Spec, TableContext>): BaseTable.TableOption<Spec & { readonly deferrable: true }, TableContext> =>
104
+ BaseTable.mapOption(option, (spec) => ({
105
+ ...spec,
121
106
  deferrable: true
122
- } as Spec & { readonly deferrable: true })
107
+ } as Spec & { readonly deferrable: true }))
123
108
 
124
109
  /** Marks a deferrable standard primary key, unique, or foreign-key option as initially deferred. */
125
110
  export const initiallyDeferred = <
126
- Spec extends PrimaryKeySpec | UniqueSpec | ForeignKeySpec
127
- >(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
111
+ Spec extends PrimaryKeySpec | UniqueSpec | ForeignKeySpec,
112
+ TableContext extends BaseTable.SchemaTableDefinition
113
+ >(option: BaseTable.TableOption<Spec, TableContext>): BaseTable.TableOption<Spec & {
128
114
  readonly deferrable: true
129
115
  readonly initiallyDeferred: true
130
- }> =>
131
- mapOption({
132
- ...option.option,
116
+ }, TableContext> =>
117
+ BaseTable.mapOption(option, (spec) => ({
118
+ ...spec,
133
119
  deferrable: true,
134
120
  initiallyDeferred: true
135
- } as Spec & { readonly deferrable: true; readonly initiallyDeferred: true })
121
+ } as Spec & { readonly deferrable: true; readonly initiallyDeferred: true }))
136
122
 
137
123
  /** 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,
124
+ export const nullsNotDistinct = <Spec extends UniqueSpec, TableContext extends BaseTable.SchemaTableDefinition>(
125
+ option: BaseTable.TableOption<Spec, TableContext>
126
+ ): BaseTable.TableOption<Spec & { readonly nullsNotDistinct: true }, TableContext> =>
127
+ BaseTable.mapOption(option, (spec) => ({
128
+ ...spec,
143
129
  nullsNotDistinct: true
144
- } as Spec & { readonly nullsNotDistinct: true })
130
+ } as Spec & { readonly nullsNotDistinct: true }))
145
131
 
146
132
  /** 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,
133
+ export const uniqueIndex = <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
134
+ option: BaseTable.TableOption<Spec, TableContext>
135
+ ): BaseTable.TableOption<Spec & { readonly unique: true }, TableContext> =>
136
+ BaseTable.mapOption(option, (spec) => ({
137
+ ...spec,
152
138
  unique: true
153
- } as Spec & { readonly unique: true })
139
+ } as Spec & { readonly unique: true }))
154
140
 
155
141
  /** Adds a Postgres index method to a standard index option. */
156
142
  export const using = <const Method extends string>(
157
143
  method: BaseTable.NonEmptyStringInput<Method>
158
144
  ) =>
159
- <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly method: Method }> =>
160
- mapOption({
161
- ...option.option,
145
+ <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
146
+ option: BaseTable.TableOption<Spec, TableContext>
147
+ ): BaseTable.TableOption<Spec & { readonly method: Method }, TableContext> =>
148
+ BaseTable.mapOption(option, (spec) => ({
149
+ ...spec,
162
150
  method
163
- } as Spec & { readonly method: Method })
151
+ } as Spec & { readonly method: Method }))
164
152
 
165
153
  /** Adds Postgres INCLUDE columns to a standard index option. */
166
- export const include = <const Include extends readonly string[]>(
167
- include: Include & NonEmptyStringArrayInput<Include>
154
+ export const include = <
155
+ Selection extends BaseTable.AnyColumnSelection
156
+ >(
157
+ columns: (table: any) => Selection
168
158
  ) =>
169
- <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly include: Include }> =>
170
- mapOption({
159
+ <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
160
+ option: BaseTable.TableOption<Spec, TableContext>
161
+ ): BaseTable.TableOption<Spec & { readonly include: BaseTable.SelectedColumns<Selection> }, TableContext> =>
162
+ BaseTable.optionFromTable({
171
163
  ...option.option,
172
- include
173
- } as Spec & { readonly include: Include })
164
+ include: [] as unknown as BaseTable.SelectedColumns<Selection>
165
+ } as Spec & { readonly include: BaseTable.SelectedColumns<Selection> }, (table) => ({
166
+ ...BaseTable.resolveOption(option, table as TableContext),
167
+ include: BaseTable.selectedColumnList(columns(table))
168
+ } as Spec & { readonly include: BaseTable.SelectedColumns<Selection> }))
174
169
 
175
170
  /** Adds a Postgres partial-index predicate to a standard index option. */
176
171
  export const where = <Predicate extends BaseTable.DdlExpressionLike>(
177
172
  predicate: Predicate
178
173
  ) =>
179
- <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & { readonly predicate: Predicate }> =>
180
- mapOption({
181
- ...option.option,
174
+ <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
175
+ option: BaseTable.TableOption<Spec, TableContext>
176
+ ): BaseTable.TableOption<Spec & { readonly predicate: Predicate }, TableContext> =>
177
+ BaseTable.mapOption(option, (spec) => ({
178
+ ...spec,
182
179
  predicate
183
- } as Spec & { readonly predicate: Predicate })
180
+ } as Spec & { readonly predicate: Predicate }))
184
181
 
185
182
  /** Replaces standard index columns with a single Postgres index key. */
186
- export const key = <const Key extends IndexKeyInput>(
187
- key: Key & NonEmptyIndexKeyInput<Key>
183
+ export const key = <
184
+ Column extends BaseTable.TableColumn<BaseTable.SchemaTableDefinition>,
185
+ const Options extends IndexKeyOptions = {}
186
+ >(
187
+ column: (table: any) => Column,
188
+ options?: Options & NonEmptyIndexKeyInput<Options>
188
189
  ) =>
189
- <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
190
- readonly keys: readonly [NormalizedIndexKey<Key>]
191
- }> =>
192
- mapOption({
190
+ <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
191
+ option: BaseTable.TableOption<Spec, TableContext>
192
+ ): BaseTable.TableOption<Spec & {
193
+ readonly keys: readonly [NormalizedIndexKey<{ readonly column: Column } & Options>]
194
+ }, TableContext> =>
195
+ BaseTable.optionFromTable({
193
196
  ...option.option,
194
197
  columns: undefined,
195
- keys: [normalizeIndexKey(key)]
196
- } as unknown as Spec & { readonly keys: readonly [NormalizedIndexKey<Key>] })
198
+ keys: [] as unknown as readonly [NormalizedIndexKey<{ readonly column: Column } & Options>]
199
+ } as unknown as Spec & { readonly keys: readonly [NormalizedIndexKey<{ readonly column: Column } & Options>] }, (table) => ({
200
+ ...BaseTable.resolveOption(option, table as TableContext),
201
+ columns: undefined,
202
+ keys: [normalizeIndexKey({ column: column(table), ...options })]
203
+ } as unknown as Spec & { readonly keys: readonly [NormalizedIndexKey<{ readonly column: Column } & Options>] }))
197
204
 
198
205
  /** 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
- }
206
+ export const keys = (
207
+ keys: (table: any) => readonly [IndexKeyInput, ...IndexKeyInput[]]
203
208
  ) =>
204
- <Spec extends IndexSpec>(option: BaseTable.TableOption<Spec>): BaseTable.TableOption<Spec & {
205
- readonly keys: NormalizedIndexKeys<Keys>
206
- }> =>
207
- mapOption({
209
+ <Spec extends IndexSpec, TableContext extends BaseTable.SchemaTableDefinition>(
210
+ option: BaseTable.TableOption<Spec, TableContext>
211
+ ): BaseTable.TableOption<Spec & {
212
+ readonly keys: readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
213
+ }, TableContext> =>
214
+ BaseTable.optionFromTable({
208
215
  ...option.option,
209
216
  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 })
217
+ keys: [] as unknown as readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]]
218
+ } as Spec & { readonly keys: readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]] }, (table) => {
219
+ const resolvedKeys = keys(table)
220
+ return {
221
+ ...BaseTable.resolveOption(option, table as TableContext),
222
+ columns: undefined,
223
+ keys: [normalizeIndexKey(resolvedKeys[0]), ...resolvedKeys.slice(1).map(normalizeIndexKey)]
224
+ } as Spec & { readonly keys: readonly [BaseTable.IndexKeySpec, ...BaseTable.IndexKeySpec[]] }
225
+ })
228
226
 
229
227
  /** 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,
228
+ export const noInherit = <Spec extends CheckSpec, TableContext extends BaseTable.SchemaTableDefinition>(
229
+ option: BaseTable.TableOption<Spec, TableContext>
230
+ ): BaseTable.TableOption<Spec & { readonly noInherit: true }, TableContext> =>
231
+ BaseTable.mapOption(option, (spec) => ({
232
+ ...spec,
235
233
  noInherit: true
236
- } as Spec & { readonly noInherit: true })
234
+ } as Spec & { readonly noInherit: true }))
@@ -1,9 +1,15 @@
1
1
  import type * as Expression from "../internal/scalar.js"
2
2
  import type { NonEmptyStringInput } from "../internal/table-options.js"
3
+ import {
4
+ pickDatatypeConstructors,
5
+ postgresSpecificDatatypeKeys,
6
+ type PostgresSpecificDatatypeKey
7
+ } from "../internal/datatypes/matrix.js"
3
8
  import { postgresDatatypes } from "./datatypes/index.js"
4
- import { type as postgresType } from "./internal/dsl.js"
5
9
 
6
- type PostgresTypeNamespace = typeof postgresDatatypes & {
10
+ type PostgresSpecificDatatypes = Pick<typeof postgresDatatypes, PostgresSpecificDatatypeKey>
11
+
12
+ type PostgresTypeNamespace = PostgresSpecificDatatypes & {
7
13
  readonly array: <Element extends Expression.DbType.Any>(
8
14
  element: Element
9
15
  ) => Expression.DbType.Array<"postgres", Element, `${Element["kind"]}[]`>
@@ -24,7 +30,6 @@ type PostgresTypeNamespace = typeof postgresDatatypes & {
24
30
  base: Base
25
31
  ) => Expression.DbType.Domain<"postgres", Base, Kind>
26
32
  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
33
  readonly custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => Expression.DbType.Base<"postgres", Kind>
29
34
  readonly driverValueMapping: <Db extends Expression.DbType.Any>(
30
35
  dbType: Db,
@@ -32,5 +37,82 @@ type PostgresTypeNamespace = typeof postgresDatatypes & {
32
37
  ) => Db
33
38
  }
34
39
 
40
+ const array = <Element extends Expression.DbType.Any>(
41
+ element: Element
42
+ ): Expression.DbType.Array<"postgres", Element, `${Element["kind"]}[]`> => ({
43
+ dialect: "postgres",
44
+ kind: `${element.kind}[]`,
45
+ element
46
+ })
47
+
48
+ const range = <Kind extends string, Subtype extends Expression.DbType.Any>(
49
+ kind: NonEmptyStringInput<Kind>,
50
+ subtype: Subtype
51
+ ): Expression.DbType.Range<"postgres", Subtype, Kind> => ({
52
+ dialect: "postgres",
53
+ kind: kind as Kind,
54
+ subtype
55
+ })
56
+
57
+ const multirange = <Kind extends string, Subtype extends Expression.DbType.Any>(
58
+ kind: NonEmptyStringInput<Kind>,
59
+ subtype: Subtype
60
+ ): Expression.DbType.Multirange<"postgres", Subtype, Kind> => ({
61
+ dialect: "postgres",
62
+ kind: kind as Kind,
63
+ subtype
64
+ })
65
+
66
+ const record = <Kind extends string, Fields extends Record<string, Expression.DbType.Any>>(
67
+ kind: NonEmptyStringInput<Kind>,
68
+ fields: Fields
69
+ ): Expression.DbType.Composite<"postgres", Fields, Kind> => ({
70
+ dialect: "postgres",
71
+ kind: kind as Kind,
72
+ fields
73
+ })
74
+
75
+ const domain = <Kind extends string, Base extends Expression.DbType.Any>(
76
+ kind: NonEmptyStringInput<Kind>,
77
+ base: Base
78
+ ): Expression.DbType.Domain<"postgres", Base, Kind> => ({
79
+ dialect: "postgres",
80
+ kind: kind as Kind,
81
+ base
82
+ })
83
+
84
+ const enum_ = <Kind extends string>(
85
+ kind: NonEmptyStringInput<Kind>
86
+ ): Expression.DbType.Enum<"postgres", Kind> => ({
87
+ dialect: "postgres",
88
+ kind: kind as Kind,
89
+ variant: "enum"
90
+ })
91
+
92
+ const custom = <Kind extends string>(
93
+ kind: NonEmptyStringInput<Kind>
94
+ ): Expression.DbType.Base<"postgres", Kind> => ({
95
+ dialect: "postgres",
96
+ kind: kind as Kind
97
+ })
98
+
99
+ const driverValueMapping = <Db extends Expression.DbType.Any>(
100
+ dbType: Db,
101
+ mapping: Expression.DriverValueMapping
102
+ ): Db => ({
103
+ ...dbType,
104
+ driverValueMapping: mapping
105
+ })
106
+
35
107
  /** Postgres database-type constructors for casts and typed column references. */
36
- export const type: PostgresTypeNamespace = postgresType
108
+ export const type: PostgresTypeNamespace = {
109
+ ...pickDatatypeConstructors(postgresDatatypes, postgresSpecificDatatypeKeys),
110
+ array,
111
+ range,
112
+ multirange,
113
+ record,
114
+ domain,
115
+ enum: enum_,
116
+ custom,
117
+ driverValueMapping
118
+ }
@@ -0,0 +1,32 @@
1
+ import * as BaseTable from "../internal/table.js"
2
+ import type { TableOptionSpec } from "../internal/table-options.js"
3
+
4
+ type UniqueSpec = Extract<TableOptionSpec, { readonly kind: "unique" }>
5
+
6
+ export const deferrable = <Spec extends UniqueSpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
7
+ option: BaseTable.TableOption<Spec, TableContext>
8
+ ): BaseTable.TableOption<Spec & { readonly deferrable: true }, TableContext> =>
9
+ BaseTable.mapOption(option, (spec) => ({
10
+ ...spec,
11
+ deferrable: true
12
+ } as Spec & { readonly deferrable: true }))
13
+
14
+ export const initiallyDeferred = <Spec extends UniqueSpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
15
+ option: BaseTable.TableOption<Spec, TableContext>
16
+ ): BaseTable.TableOption<Spec & {
17
+ readonly deferrable: true
18
+ readonly initiallyDeferred: true
19
+ }, TableContext> =>
20
+ BaseTable.mapOption(option, (spec) => ({
21
+ ...spec,
22
+ deferrable: true,
23
+ initiallyDeferred: true
24
+ } as Spec & { readonly deferrable: true; readonly initiallyDeferred: true }))
25
+
26
+ export const nullsNotDistinct = <Spec extends UniqueSpec, TableContext extends BaseTable.TableDefinition<any, any, any, "schema", any>>(
27
+ option: BaseTable.TableOption<Spec, TableContext>
28
+ ): BaseTable.TableOption<Spec & { readonly nullsNotDistinct: true }, TableContext> =>
29
+ BaseTable.mapOption(option, (spec) => ({
30
+ ...spec,
31
+ nullsNotDistinct: true
32
+ } as Spec & { readonly nullsNotDistinct: true }))
package/src/postgres.ts CHANGED
@@ -4,12 +4,10 @@ export * as Column from "./postgres/column-extension.js"
4
4
  export * as Datatypes from "./postgres/datatypes/index.js"
5
5
  /** Postgres SQLSTATE catalog and error normalization helpers. */
6
6
  export * as Errors from "./postgres/errors/index.js"
7
- /** Postgres cast helpers. */
8
- export { cast as Cast } from "./postgres/cast.js"
9
7
  /** Postgres-specific SQL function expressions. Portable functions are exported from the root package. */
10
8
  export * as Function from "./postgres/function/index.js"
11
- /** Postgres-specialized JSON expression helpers. */
12
- export * as Json from "./postgres/json.js"
9
+ /** Postgres-specific JSON expression helpers. Portable JSON helpers are exported from the root package. */
10
+ export * as Json from "./postgres/json-extension.js"
13
11
  /** Postgres jsonb-only expression helpers. */
14
12
  export * as Jsonb from "./postgres/jsonb.js"
15
13
  /** Postgres-specialized typed query execution contracts. */
@@ -28,7 +26,15 @@ export type { SchemaNamespace } from "./postgres/schema.js"
28
26
  /** Postgres enum and sequence definition helpers. */
29
27
  export { enumType as enum, sequence } from "./postgres/schema-management.js"
30
28
  export type { EnumDefinition, SequenceDefinition } from "./postgres/schema-management.js"
31
- /** Postgres-specific table-option extensions. Portable tables are exported from `effect-qb`. */
32
- export * as Table from "./postgres/table.js"
29
+ /** Postgres-specific primary-key option modifiers. */
30
+ export * as PrimaryKey from "./postgres/primary-key.js"
31
+ /** Postgres-specific unique-constraint option modifiers. */
32
+ export * as Unique from "./postgres/unique.js"
33
+ /** Postgres-specific index option modifiers. */
34
+ export * as Index from "./postgres/index.js"
35
+ /** Postgres-specific foreign-key option modifiers. */
36
+ export * as ForeignKey from "./postgres/foreign-key.js"
37
+ /** Postgres-specific check-constraint option modifiers. */
38
+ export * as Check from "./postgres/check.js"
33
39
  /** Postgres-specialized built-in renderer entrypoint. */
34
40
  export * as Renderer from "./postgres/renderer.js"