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.
- package/README.md +4 -0
- package/dist/index.js +8065 -0
- package/dist/mysql.js +4036 -2418
- package/dist/postgres/metadata.js +2536 -625
- package/dist/postgres.js +8248 -7857
- package/dist/sqlite.js +8854 -0
- package/dist/standard.js +8019 -0
- package/package.json +15 -3
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/column-state.ts +11 -6
- package/src/internal/column.ts +44 -7
- package/src/internal/datatypes/define.ts +2 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +14 -7
- package/src/internal/derived-table.ts +7 -13
- package/src/internal/dialect-renderers/mysql.ts +2046 -0
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
- package/src/internal/dialect.ts +37 -0
- package/src/internal/dsl-mutation-runtime.ts +29 -10
- package/src/internal/dsl-plan-runtime.ts +41 -24
- package/src/internal/dsl-query-runtime.ts +11 -31
- package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
- package/src/internal/executor.ts +57 -15
- package/src/internal/expression-ast.ts +3 -2
- package/src/internal/grouping-key.ts +216 -9
- package/src/internal/implication-runtime.ts +3 -2
- package/src/internal/json/types.ts +155 -40
- package/src/internal/predicate/context.ts +14 -1
- package/src/internal/predicate/key.ts +19 -2
- package/src/internal/predicate/runtime.ts +30 -3
- package/src/internal/query.d.ts +38 -11
- package/src/internal/query.ts +315 -54
- package/src/internal/renderer.ts +51 -6
- package/src/internal/runtime/driver-value-mapping.ts +58 -0
- package/src/internal/runtime/normalize.ts +74 -43
- package/src/internal/runtime/schema.ts +5 -3
- package/src/internal/runtime/value.ts +153 -30
- package/src/internal/scalar.ts +6 -1
- package/src/internal/schema-derivation.d.ts +12 -61
- package/src/internal/schema-derivation.ts +90 -38
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6885 -0
- package/src/internal/table-options.ts +229 -62
- package/src/internal/table.d.ts +33 -32
- package/src/internal/table.ts +469 -160
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +27 -12
- package/src/mysql/datatypes/index.ts +24 -2
- package/src/mysql/errors/catalog.ts +5 -5
- package/src/mysql/errors/normalize.ts +2 -2
- package/src/mysql/executor.ts +7 -5
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +906 -324
- package/src/mysql/internal/renderer.ts +7 -2
- package/src/mysql/json.ts +37 -0
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/query.ts +9 -2
- package/src/mysql/renderer.ts +31 -4
- package/src/mysql.ts +4 -12
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +9 -13
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +3 -2
- package/src/postgres/errors/normalize.ts +2 -2
- package/src/postgres/executor.ts +55 -10
- package/src/postgres/function/core.ts +20 -4
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +850 -359
- package/src/postgres/internal/renderer.ts +7 -2
- package/src/postgres/internal/schema-ddl.ts +22 -9
- package/src/postgres/internal/schema-model.ts +244 -10
- package/src/postgres/json.ts +100 -24
- package/src/postgres/jsonb.ts +38 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/query.ts +9 -2
- package/src/postgres/renderer.ts +31 -4
- package/src/postgres/schema-management.ts +108 -16
- package/src/postgres/schema.ts +98 -15
- package/src/postgres/table.ts +203 -398
- package/src/postgres/type.ts +8 -7
- package/src/postgres.ts +9 -11
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +127 -0
- package/src/sqlite/datatypes/index.ts +80 -0
- package/src/sqlite/datatypes/spec.ts +98 -0
- package/src/sqlite/errors/catalog.ts +103 -0
- package/src/sqlite/errors/fields.ts +19 -0
- package/src/sqlite/errors/index.ts +19 -0
- package/src/sqlite/errors/normalize.ts +229 -0
- package/src/sqlite/errors/requirements.ts +71 -0
- package/src/sqlite/errors/types.ts +29 -0
- package/src/sqlite/executor.ts +229 -0
- package/src/sqlite/function/aggregate.ts +2 -0
- package/src/sqlite/function/core.ts +2 -0
- package/src/sqlite/function/index.ts +19 -0
- package/src/sqlite/function/string.ts +2 -0
- package/src/sqlite/function/temporal.ts +100 -0
- package/src/sqlite/function/window.ts +2 -0
- package/src/sqlite/internal/dialect.ts +42 -0
- package/src/sqlite/internal/dsl.ts +6979 -0
- package/src/sqlite/internal/renderer.ts +51 -0
- package/src/sqlite/json.ts +39 -0
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/query.ts +196 -0
- package/src/sqlite/renderer.ts +51 -0
- package/src/sqlite.ts +14 -0
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +98 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/function/aggregate.ts +2 -0
- package/src/standard/function/core.ts +2 -0
- package/src/standard/function/index.ts +18 -0
- package/src/standard/function/string.ts +2 -0
- package/src/standard/function/temporal.ts +78 -0
- package/src/standard/function/window.ts +2 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +21 -0
- package/src/standard/table.ts +147 -0
- package/src/standard.ts +18 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/mysql/table.ts +0 -157
package/src/postgres/query.ts
CHANGED
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
type HavingPredicateInput,
|
|
17
17
|
type OrderDirection,
|
|
18
18
|
type OutputOfSelection,
|
|
19
|
-
type MutationInputOf,
|
|
20
19
|
type MutationTargetLike,
|
|
21
20
|
type NumericExpressionInput,
|
|
22
21
|
type PredicateInput,
|
|
@@ -137,9 +136,18 @@ export {
|
|
|
137
136
|
orderBy,
|
|
138
137
|
groupBy
|
|
139
138
|
} from "./internal/dsl.js"
|
|
139
|
+
import type * as Expression from "../internal/scalar.js"
|
|
140
140
|
export { postgresType as type }
|
|
141
141
|
export const generateSeries: PublicGenerateSeriesApi = dslGenerateSeries as PublicGenerateSeriesApi
|
|
142
142
|
|
|
143
|
+
type PostgresMutationValueInput<Value> =
|
|
144
|
+
| Value
|
|
145
|
+
| Expression.Scalar<Value, Expression.DbType.Any, Expression.Nullability, "postgres", Expression.ScalarKind, Expression.BindingId>
|
|
146
|
+
|
|
147
|
+
export type MutationInputOf<Shape> = {
|
|
148
|
+
readonly [K in keyof Shape]: PostgresMutationValueInput<Shape[K]>
|
|
149
|
+
}
|
|
150
|
+
|
|
143
151
|
type StructuredSource = AnyValuesSource | AnyUnnestSource | AnyTableFunctionSource
|
|
144
152
|
|
|
145
153
|
type StructuredFromApi = <CurrentSource extends StructuredSource>(
|
|
@@ -165,7 +173,6 @@ export type {
|
|
|
165
173
|
HavingPredicateInput,
|
|
166
174
|
OrderDirection,
|
|
167
175
|
OutputOfSelection,
|
|
168
|
-
MutationInputOf,
|
|
169
176
|
MutationTargetLike,
|
|
170
177
|
NumericExpressionInput,
|
|
171
178
|
PredicateInput,
|
package/src/postgres/renderer.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
2
|
+
|
|
1
3
|
import * as CoreRenderer from "../internal/renderer.js"
|
|
4
|
+
import * as Casing from "../internal/casing.js"
|
|
2
5
|
import type * as Expression from "../internal/scalar.js"
|
|
6
|
+
import type { PostgresDatatypeFamily, PostgresDatatypeKind } from "./datatypes/spec.js"
|
|
3
7
|
import { renderPostgresPlan } from "./internal/renderer.js"
|
|
4
8
|
|
|
5
9
|
/** Postgres-specialized rendered query shape. */
|
|
@@ -7,18 +11,41 @@ export type RenderedQuery<Row> = CoreRenderer.RenderedQuery<Row, "postgres">
|
|
|
7
11
|
/** Extracts the row type carried by a Postgres rendered query. */
|
|
8
12
|
export type RowOf<Value extends RenderedQuery<any>> = CoreRenderer.RowOf<Value>
|
|
9
13
|
/** Postgres-specialized renderer contract. */
|
|
10
|
-
export type Renderer = CoreRenderer.Renderer<"postgres">
|
|
14
|
+
export type Renderer = CoreRenderer.Renderer<"postgres"> & Pipeable & {
|
|
15
|
+
readonly [Casing.TypeId]: Casing.State
|
|
16
|
+
readonly withCasing: (options: Casing.Options) => Renderer
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type ValueMappings = Expression.DriverValueMappingsFor<PostgresDatatypeKind, PostgresDatatypeFamily>
|
|
11
20
|
|
|
12
21
|
export interface MakeOptions {
|
|
13
|
-
readonly valueMappings?:
|
|
22
|
+
readonly valueMappings?: ValueMappings
|
|
23
|
+
readonly casing?: Casing.Options
|
|
14
24
|
}
|
|
15
25
|
|
|
16
26
|
export { TypeId } from "../internal/renderer.js"
|
|
17
27
|
export type { Projection } from "../internal/renderer.js"
|
|
18
28
|
|
|
29
|
+
const RendererProto = {
|
|
30
|
+
pipe(this: Pipeable) {
|
|
31
|
+
return pipeArguments(this, arguments)
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
19
35
|
/** Creates the built-in Postgres renderer. */
|
|
20
|
-
export const make = (options: MakeOptions = {}): Renderer =>
|
|
21
|
-
CoreRenderer.
|
|
36
|
+
export const make = (options: MakeOptions = {}): Renderer => {
|
|
37
|
+
const renderer = CoreRenderer.makeTrusted("postgres", (plan) => renderPostgresPlan(plan, options))
|
|
38
|
+
return Object.assign(Object.create(RendererProto), renderer, {
|
|
39
|
+
[Casing.TypeId]: {
|
|
40
|
+
casing: options.casing
|
|
41
|
+
},
|
|
42
|
+
withCasing: (override: Casing.Options) =>
|
|
43
|
+
make({
|
|
44
|
+
...options,
|
|
45
|
+
casing: Casing.merge(options.casing, override)
|
|
46
|
+
})
|
|
47
|
+
}) as Renderer
|
|
48
|
+
}
|
|
22
49
|
|
|
23
50
|
/** Shared built-in Postgres renderer instance. */
|
|
24
51
|
export const postgres = make()
|
|
@@ -3,6 +3,7 @@ import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
|
3
3
|
|
|
4
4
|
import type * as Expression from "../internal/scalar.js"
|
|
5
5
|
import { makeColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
|
|
6
|
+
import type { NonEmptyStringInput } from "../internal/table-options.js"
|
|
6
7
|
|
|
7
8
|
export const EnumTypeId: unique symbol = Symbol.for("effect-qb/SchemaManagement/Enum")
|
|
8
9
|
export const SequenceTypeId: unique symbol = Symbol.for("effect-qb/SchemaManagement/Sequence")
|
|
@@ -16,6 +17,75 @@ type QualifiedName<
|
|
|
16
17
|
: `${SchemaName}.${Name}`
|
|
17
18
|
: Name
|
|
18
19
|
|
|
20
|
+
type LowerAlpha =
|
|
21
|
+
| "a"
|
|
22
|
+
| "b"
|
|
23
|
+
| "c"
|
|
24
|
+
| "d"
|
|
25
|
+
| "e"
|
|
26
|
+
| "f"
|
|
27
|
+
| "g"
|
|
28
|
+
| "h"
|
|
29
|
+
| "i"
|
|
30
|
+
| "j"
|
|
31
|
+
| "k"
|
|
32
|
+
| "l"
|
|
33
|
+
| "m"
|
|
34
|
+
| "n"
|
|
35
|
+
| "o"
|
|
36
|
+
| "p"
|
|
37
|
+
| "q"
|
|
38
|
+
| "r"
|
|
39
|
+
| "s"
|
|
40
|
+
| "t"
|
|
41
|
+
| "u"
|
|
42
|
+
| "v"
|
|
43
|
+
| "w"
|
|
44
|
+
| "x"
|
|
45
|
+
| "y"
|
|
46
|
+
| "z"
|
|
47
|
+
|
|
48
|
+
type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
|
49
|
+
type SafeIdentifierStart = LowerAlpha | "_"
|
|
50
|
+
type SafeIdentifierRest = SafeIdentifierStart | Digit | "$"
|
|
51
|
+
|
|
52
|
+
type EscapeIdentifier<Value extends string> =
|
|
53
|
+
Value extends `${infer Head}"${infer Tail}`
|
|
54
|
+
? `${Head}""${EscapeIdentifier<Tail>}`
|
|
55
|
+
: Value
|
|
56
|
+
|
|
57
|
+
type IsSafeIdentifierRest<Value extends string> =
|
|
58
|
+
Value extends ""
|
|
59
|
+
? true
|
|
60
|
+
: Value extends `${infer Head}${infer Tail}`
|
|
61
|
+
? Head extends SafeIdentifierRest
|
|
62
|
+
? IsSafeIdentifierRest<Tail>
|
|
63
|
+
: false
|
|
64
|
+
: false
|
|
65
|
+
|
|
66
|
+
type IsSafeIdentifier<Value extends string> =
|
|
67
|
+
Value extends `${infer Head}${infer Tail}`
|
|
68
|
+
? Head extends SafeIdentifierStart
|
|
69
|
+
? IsSafeIdentifierRest<Tail>
|
|
70
|
+
: false
|
|
71
|
+
: false
|
|
72
|
+
|
|
73
|
+
type RenderIdentifier<Value extends string> =
|
|
74
|
+
string extends Value
|
|
75
|
+
? string
|
|
76
|
+
: IsSafeIdentifier<Value> extends true
|
|
77
|
+
? Value
|
|
78
|
+
: `"${EscapeIdentifier<Value>}"`
|
|
79
|
+
|
|
80
|
+
type RenderQualifiedTypeName<
|
|
81
|
+
Name extends string,
|
|
82
|
+
SchemaName extends string | undefined
|
|
83
|
+
> = SchemaName extends string
|
|
84
|
+
? SchemaName extends "public"
|
|
85
|
+
? RenderIdentifier<Name>
|
|
86
|
+
: `${RenderIdentifier<SchemaName>}.${RenderIdentifier<Name>}`
|
|
87
|
+
: RenderIdentifier<Name>
|
|
88
|
+
|
|
19
89
|
type EnumColumn<
|
|
20
90
|
Name extends string,
|
|
21
91
|
Values extends readonly [string, ...string[]],
|
|
@@ -24,7 +94,7 @@ type EnumColumn<
|
|
|
24
94
|
Values[number],
|
|
25
95
|
Values[number],
|
|
26
96
|
Values[number],
|
|
27
|
-
Expression.DbType.Enum<"postgres",
|
|
97
|
+
Expression.DbType.Enum<"postgres", RenderQualifiedTypeName<Name, SchemaName>>,
|
|
28
98
|
false,
|
|
29
99
|
false,
|
|
30
100
|
false,
|
|
@@ -33,8 +103,26 @@ type EnumColumn<
|
|
|
33
103
|
undefined
|
|
34
104
|
>
|
|
35
105
|
|
|
106
|
+
const safeUnquotedIdentifier = /^[a-z_][a-z0-9_$]*$/
|
|
107
|
+
|
|
108
|
+
const quoteIdentifier = (value: string): string =>
|
|
109
|
+
`"${value.replaceAll("\"", "\"\"")}"`
|
|
110
|
+
|
|
111
|
+
const renderIdentifier = (value: string): string =>
|
|
112
|
+
safeUnquotedIdentifier.test(value)
|
|
113
|
+
? value
|
|
114
|
+
: quoteIdentifier(value)
|
|
115
|
+
|
|
116
|
+
const renderQualifiedTypeName = (
|
|
117
|
+
name: string,
|
|
118
|
+
schemaName: string | undefined
|
|
119
|
+
): string =>
|
|
120
|
+
schemaName === undefined || schemaName === "public"
|
|
121
|
+
? renderIdentifier(name)
|
|
122
|
+
: `${renderIdentifier(schemaName)}.${renderIdentifier(name)}`
|
|
123
|
+
|
|
36
124
|
const EnumProto = {
|
|
37
|
-
pipe(this:
|
|
125
|
+
pipe(this: Pipeable) {
|
|
38
126
|
return pipeArguments(this, arguments)
|
|
39
127
|
},
|
|
40
128
|
qualifiedName(this: EnumDefinition) {
|
|
@@ -45,12 +133,16 @@ const EnumProto = {
|
|
|
45
133
|
type(this: EnumDefinition) {
|
|
46
134
|
return {
|
|
47
135
|
dialect: "postgres",
|
|
48
|
-
kind: this.
|
|
136
|
+
kind: renderQualifiedTypeName(this.name, this.schemaName),
|
|
49
137
|
variant: "enum"
|
|
50
138
|
}
|
|
51
139
|
},
|
|
52
140
|
column(this: EnumDefinition) {
|
|
53
|
-
const
|
|
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
|
+
]
|
|
54
146
|
return makeColumnDefinition(
|
|
55
147
|
values.length === 1 ? values[0]! : Schema.Union(...values),
|
|
56
148
|
{
|
|
@@ -61,7 +153,7 @@ const EnumProto = {
|
|
|
61
153
|
primaryKey: false,
|
|
62
154
|
unique: false,
|
|
63
155
|
references: undefined,
|
|
64
|
-
ddlType: this.
|
|
156
|
+
ddlType: renderQualifiedTypeName(this.name, this.schemaName),
|
|
65
157
|
identity: undefined,
|
|
66
158
|
enum: {
|
|
67
159
|
name: this.name,
|
|
@@ -74,7 +166,7 @@ const EnumProto = {
|
|
|
74
166
|
}
|
|
75
167
|
|
|
76
168
|
const SequenceProto = {
|
|
77
|
-
pipe(this:
|
|
169
|
+
pipe(this: Pipeable) {
|
|
78
170
|
return pipeArguments(this, arguments)
|
|
79
171
|
},
|
|
80
172
|
qualifiedName(this: SequenceDefinition) {
|
|
@@ -99,7 +191,7 @@ export interface EnumDefinition<
|
|
|
99
191
|
readonly schemaName: SchemaName
|
|
100
192
|
}
|
|
101
193
|
readonly qualifiedName: () => QualifiedName<Name, SchemaName>
|
|
102
|
-
readonly type: () => Expression.DbType.Enum<"postgres",
|
|
194
|
+
readonly type: () => Expression.DbType.Enum<"postgres", RenderQualifiedTypeName<Name, SchemaName>>
|
|
103
195
|
readonly column: () => EnumColumn<Name, Values, SchemaName>
|
|
104
196
|
}
|
|
105
197
|
|
|
@@ -125,7 +217,7 @@ export function enumType<
|
|
|
125
217
|
Name extends string,
|
|
126
218
|
const Values extends readonly [string, ...string[]]
|
|
127
219
|
>(
|
|
128
|
-
name: Name
|
|
220
|
+
name: NonEmptyStringInput<Name>,
|
|
129
221
|
values: Values
|
|
130
222
|
): EnumDefinition<Name, Values, undefined>
|
|
131
223
|
export function enumType<
|
|
@@ -133,9 +225,9 @@ export function enumType<
|
|
|
133
225
|
const Values extends readonly [string, ...string[]],
|
|
134
226
|
SchemaName extends string
|
|
135
227
|
>(
|
|
136
|
-
name: Name
|
|
228
|
+
name: NonEmptyStringInput<Name>,
|
|
137
229
|
values: Values,
|
|
138
|
-
schemaName: SchemaName
|
|
230
|
+
schemaName: NonEmptyStringInput<SchemaName>
|
|
139
231
|
): EnumDefinition<Name, Values, SchemaName>
|
|
140
232
|
export function enumType(
|
|
141
233
|
name: string,
|
|
@@ -156,11 +248,11 @@ export function enumType(
|
|
|
156
248
|
}
|
|
157
249
|
|
|
158
250
|
export function sequence<Name extends string>(
|
|
159
|
-
name: Name
|
|
251
|
+
name: NonEmptyStringInput<Name>
|
|
160
252
|
): SequenceDefinition<Name, undefined>
|
|
161
253
|
export function sequence<Name extends string, SchemaName extends string>(
|
|
162
|
-
name: Name
|
|
163
|
-
schemaName: SchemaName
|
|
254
|
+
name: NonEmptyStringInput<Name>,
|
|
255
|
+
schemaName: NonEmptyStringInput<SchemaName>
|
|
164
256
|
): SequenceDefinition<Name, SchemaName>
|
|
165
257
|
export function sequence(
|
|
166
258
|
name: string,
|
|
@@ -178,21 +270,21 @@ export function sequence(
|
|
|
178
270
|
}
|
|
179
271
|
|
|
180
272
|
export const schema = <SchemaName extends string>(
|
|
181
|
-
schemaName: SchemaName
|
|
273
|
+
schemaName: NonEmptyStringInput<SchemaName>
|
|
182
274
|
) => ({
|
|
183
275
|
schemaName,
|
|
184
276
|
enumType: <
|
|
185
277
|
Name extends string,
|
|
186
278
|
const Values extends readonly [string, ...string[]]
|
|
187
279
|
>(
|
|
188
|
-
name: Name
|
|
280
|
+
name: NonEmptyStringInput<Name>,
|
|
189
281
|
values: Values
|
|
190
282
|
): EnumDefinition<Name, Values, SchemaName> =>
|
|
191
283
|
enumType(name, values, schemaName) as EnumDefinition<Name, Values, SchemaName>,
|
|
192
284
|
sequence: <
|
|
193
285
|
Name extends string
|
|
194
286
|
>(
|
|
195
|
-
name: Name
|
|
287
|
+
name: NonEmptyStringInput<Name>
|
|
196
288
|
): SequenceDefinition<Name, SchemaName> =>
|
|
197
289
|
sequence(name, schemaName) as SequenceDefinition<Name, SchemaName>
|
|
198
290
|
})
|
package/src/postgres/schema.ts
CHANGED
|
@@ -1,35 +1,118 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { pipeArguments, type Pipeable } from "effect/Pipeable"
|
|
2
|
+
|
|
3
|
+
import { ColumnTypeId } from "../internal/column-state.js"
|
|
4
|
+
import type { AnyColumnDefinition } from "../internal/column-state.js"
|
|
5
|
+
import * as Casing from "../internal/casing.js"
|
|
6
|
+
import * as BaseTable from "../internal/table.js"
|
|
7
|
+
import type { TableFieldMap } from "../internal/schema-derivation.js"
|
|
8
|
+
import { make as makeTable } from "../standard/table.js"
|
|
2
9
|
import { enumType, sequence, type EnumDefinition, type SequenceDefinition } from "./schema-management.js"
|
|
3
10
|
|
|
4
|
-
|
|
11
|
+
type InlinePrimaryKeyKeys<Fields extends TableFieldMap> = Extract<{
|
|
12
|
+
[K in keyof Fields]: Fields[K]["metadata"]["primaryKey"] extends true ? K : never
|
|
13
|
+
}[keyof Fields], string>
|
|
14
|
+
|
|
15
|
+
type FieldDialect<Column extends AnyColumnDefinition> = Column[typeof ColumnTypeId]["dbType"]["dialect"]
|
|
16
|
+
|
|
17
|
+
type ValidatePostgresSchemaFields<Fields extends TableFieldMap> = {
|
|
18
|
+
[K in keyof Fields]: Exclude<FieldDialect<Fields[K]>, "standard" | "postgres"> extends never ? Fields[K] : never
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
type ApplySchemaTableOptions<
|
|
22
|
+
Name extends string,
|
|
23
|
+
Fields extends TableFieldMap,
|
|
24
|
+
PrimaryKeyColumns extends keyof Fields & string,
|
|
25
|
+
SchemaName extends string,
|
|
26
|
+
Options extends BaseTable.DeclaredTableOptions
|
|
27
|
+
> = BaseTable.ApplyDeclaredOptions<
|
|
28
|
+
BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>,
|
|
29
|
+
Options
|
|
30
|
+
> extends BaseTable.TableDefinition<any, any, infer AppliedPrimaryKeyColumns extends keyof Fields & string, "schema", any>
|
|
31
|
+
? BaseTable.TableDefinition<Name, Fields, AppliedPrimaryKeyColumns, "schema", SchemaName>
|
|
32
|
+
: BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>
|
|
33
|
+
|
|
34
|
+
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>
|
|
38
|
+
: never
|
|
39
|
+
|
|
40
|
+
export type SchemaNamespace<SchemaName extends string> = Pipeable & {
|
|
41
|
+
readonly schemaName: SchemaName
|
|
42
|
+
readonly table: <
|
|
43
|
+
Name extends string,
|
|
44
|
+
Fields extends TableFieldMap,
|
|
45
|
+
const Options extends BaseTable.DeclaredTableOptions,
|
|
46
|
+
PrimaryKeyColumns extends keyof Fields & string = InlinePrimaryKeyKeys<Fields>
|
|
47
|
+
>(
|
|
48
|
+
name: BaseTable.NonEmptyStringInput<Name>,
|
|
49
|
+
fields: Fields & BaseTable.NonEmptyFieldMap<Fields> & ValidatePostgresSchemaFields<Fields>,
|
|
50
|
+
...options: Options & BaseTable.ValidateDeclaredOptions<BaseTable.TableDefinition<Name, Fields, PrimaryKeyColumns, "schema", SchemaName>, Options>
|
|
51
|
+
) => ApplySchemaTableOptions<Name, Fields, PrimaryKeyColumns, SchemaName, Options>
|
|
5
52
|
readonly enum: <
|
|
6
53
|
Name extends string,
|
|
7
54
|
const Values extends readonly [string, ...string[]]
|
|
8
55
|
>(
|
|
9
|
-
name: Name
|
|
56
|
+
name: BaseTable.NonEmptyStringInput<Name>,
|
|
10
57
|
values: Values
|
|
11
58
|
) => EnumDefinition<Name, Values, SchemaName>
|
|
12
59
|
readonly sequence: <
|
|
13
60
|
Name extends string
|
|
14
61
|
>(
|
|
15
|
-
name: Name
|
|
62
|
+
name: BaseTable.NonEmptyStringInput<Name>
|
|
16
63
|
) => SequenceDefinition<Name, SchemaName>
|
|
64
|
+
readonly withSchema: <
|
|
65
|
+
Table extends BaseTable.TableDefinition<any, any, any, any, any>
|
|
66
|
+
>(table: Table & ValidatePostgresSchemaTable<Table>) => BaseTable.TableDefinition<
|
|
67
|
+
Table[typeof BaseTable.TypeId]["name"],
|
|
68
|
+
Table[typeof BaseTable.TypeId]["fields"],
|
|
69
|
+
Table[typeof BaseTable.TypeId]["primaryKey"][number],
|
|
70
|
+
Table[typeof BaseTable.TypeId]["kind"],
|
|
71
|
+
SchemaName
|
|
72
|
+
>
|
|
73
|
+
readonly [Casing.TypeId]: Casing.State
|
|
74
|
+
readonly withCasing: (options: Casing.Options) => SchemaNamespace<SchemaName>
|
|
17
75
|
}
|
|
18
76
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
77
|
+
const SchemaProto = {
|
|
78
|
+
pipe(this: Pipeable) {
|
|
79
|
+
return pipeArguments(this, arguments)
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export const make = <SchemaName extends string>(
|
|
84
|
+
schemaName: BaseTable.NonEmptyStringInput<SchemaName>,
|
|
85
|
+
options: { readonly casing?: Casing.Options } = {}
|
|
86
|
+
): SchemaNamespace<SchemaName> => {
|
|
87
|
+
const physicalSchemaName = Casing.applyCategory(options.casing, "schemas", schemaName)
|
|
88
|
+
const namespace = Object.create(SchemaProto)
|
|
89
|
+
namespace.schemaName = schemaName
|
|
90
|
+
namespace.table = ((name: string, fields: any, ...declaredOptions: any[]) => {
|
|
91
|
+
let table = makeTable(name, fields, schemaName)
|
|
92
|
+
for (const option of declaredOptions) {
|
|
93
|
+
table = option(table)
|
|
94
|
+
}
|
|
95
|
+
return options.casing === undefined ? table : BaseTable.withCasing(table as any, options.casing)
|
|
96
|
+
}) as SchemaNamespace<SchemaName>["table"]
|
|
97
|
+
namespace.enum = <
|
|
24
98
|
Name extends string,
|
|
25
99
|
const Values extends readonly [string, ...string[]]
|
|
26
100
|
>(
|
|
27
|
-
name: Name
|
|
101
|
+
name: BaseTable.NonEmptyStringInput<Name>,
|
|
28
102
|
values: Values
|
|
29
|
-
) => enumType(name, values,
|
|
30
|
-
sequence
|
|
103
|
+
) => enumType(Casing.applyCategory(options.casing, "types", name), values, physicalSchemaName) as EnumDefinition<Name, Values, SchemaName>
|
|
104
|
+
namespace.sequence = <
|
|
31
105
|
Name extends string
|
|
32
106
|
>(
|
|
33
|
-
name: Name
|
|
34
|
-
) => sequence(name,
|
|
35
|
-
|
|
107
|
+
name: BaseTable.NonEmptyStringInput<Name>
|
|
108
|
+
) => sequence(Casing.applyCategory(options.casing, "sequences", name), physicalSchemaName) as SequenceDefinition<Name, SchemaName>
|
|
109
|
+
namespace.withSchema = <
|
|
110
|
+
Table extends BaseTable.TableDefinition<any, any, any, any, any>
|
|
111
|
+
>(table: Table & ValidatePostgresSchemaTable<Table>) => BaseTable.withSchema(table, schemaName, options.casing)
|
|
112
|
+
namespace[Casing.TypeId] = {
|
|
113
|
+
casing: options.casing
|
|
114
|
+
}
|
|
115
|
+
namespace.withCasing = (override: Casing.Options) =>
|
|
116
|
+
make(schemaName, { casing: Casing.merge(options.casing, override) })
|
|
117
|
+
return namespace as SchemaNamespace<SchemaName>
|
|
118
|
+
}
|