effect-qb 0.19.0 → 4.0.0-beta.92
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 +7 -1
- package/dist/index.js +1987 -679
- package/dist/mysql.js +1486 -616
- package/dist/postgres/metadata.js +1334 -263
- package/dist/postgres.js +3374 -2308
- package/dist/sqlite.js +1569 -627
- package/dist/standard.js +1982 -674
- package/package.json +2 -4
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.d.ts +3 -3
- package/src/internal/column-state.ts +13 -12
- package/src/internal/column.ts +8 -8
- package/src/internal/datatypes/define.ts +5 -0
- package/src/internal/datatypes/lookup.ts +67 -18
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/dialect-renderers/mysql.ts +6 -4
- package/src/internal/dialect-renderers/postgres.ts +6 -4
- package/src/internal/dialect-renderers/sqlite.ts +6 -4
- package/src/internal/dialect.ts +1 -1
- package/src/internal/executor.ts +56 -43
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/query.d.ts +1 -1
- package/src/internal/query.ts +1 -1
- package/src/internal/runtime/driver-value-mapping.ts +3 -3
- package/src/internal/runtime/schema.ts +28 -38
- package/src/internal/runtime/value.ts +20 -23
- package/src/internal/scalar.d.ts +1 -1
- package/src/internal/scalar.ts +2 -1
- package/src/internal/schema-derivation.d.ts +7 -7
- package/src/internal/schema-derivation.ts +11 -11
- package/src/internal/standard-dsl.ts +118 -28
- package/src/internal/table.ts +451 -120
- package/src/mysql/column.ts +6 -6
- package/src/mysql/datatypes/index.ts +1 -0
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/executor.ts +4 -6
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dsl.ts +113 -16
- package/src/mysql/json.ts +1 -33
- package/src/mysql/renderer.ts +13 -6
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +3 -1
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column.ts +11 -11
- package/src/postgres/datatypes/index.ts +1 -0
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/executor.ts +4 -6
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/temporal.ts +1 -1
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dsl.ts +119 -21
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +726 -173
- package/src/postgres/jsonb.ts +0 -1
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/renderer.ts +13 -6
- package/src/postgres/schema-management.ts +1 -6
- package/src/postgres/schema.ts +16 -8
- package/src/postgres/table.ts +111 -113
- package/src/postgres/type.ts +86 -4
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +12 -6
- package/src/sqlite/column.ts +6 -6
- package/src/sqlite/datatypes/index.ts +1 -0
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/executor.ts +4 -6
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dsl.ts +97 -5
- package/src/sqlite/json.ts +1 -32
- package/src/sqlite/renderer.ts +13 -6
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +3 -1
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +10 -10
- package/src/standard/datatypes/index.ts +2 -2
- package/src/standard/datatypes/spec.ts +10 -96
- package/src/standard/foreign-key.ts +37 -0
- package/src/standard/function/temporal.ts +1 -1
- package/src/standard/index.ts +17 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/renderer.ts +31 -3
- package/src/standard/table.ts +25 -21
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +14 -0
- package/src/internal/table.d.ts +0 -174
- package/src/postgres/cast.ts +0 -45
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "./value.js"
|
|
28
28
|
import type { RuntimeTag } from "../datatypes/shape.js"
|
|
29
29
|
|
|
30
|
-
export type RuntimeSchema = Schema.
|
|
30
|
+
export type RuntimeSchema = Schema.Top
|
|
31
31
|
|
|
32
32
|
type SchemaContext = {
|
|
33
33
|
readonly assumptions: PredicateFormula
|
|
@@ -38,7 +38,7 @@ const schemaCache = new WeakMap<Expression.Any, RuntimeSchema | undefined>()
|
|
|
38
38
|
const isRecord = (value: unknown): value is Record<string, unknown> =>
|
|
39
39
|
typeof value === "object" && value !== null && !Array.isArray(value)
|
|
40
40
|
|
|
41
|
-
const FiniteNumberSchema = Schema.Number.
|
|
41
|
+
const FiniteNumberSchema = Schema.Number.check(Schema.isFinite())
|
|
42
42
|
|
|
43
43
|
const runtimeSchemaForTag = (tag: RuntimeTag): RuntimeSchema | undefined => {
|
|
44
44
|
switch (tag) {
|
|
@@ -67,14 +67,11 @@ const runtimeSchemaForTag = (tag: RuntimeTag): RuntimeSchema | undefined => {
|
|
|
67
67
|
case "decimalString":
|
|
68
68
|
return DecimalStringSchema
|
|
69
69
|
case "bytes":
|
|
70
|
-
return Schema.
|
|
70
|
+
return Schema.Uint8Array
|
|
71
71
|
case "array":
|
|
72
72
|
return Schema.Array(Schema.Unknown)
|
|
73
73
|
case "record":
|
|
74
|
-
return Schema.Record(
|
|
75
|
-
key: Schema.String,
|
|
76
|
-
value: Schema.Unknown
|
|
77
|
-
})
|
|
74
|
+
return Schema.Record(Schema.String, Schema.Unknown)
|
|
78
75
|
case "null":
|
|
79
76
|
return Schema.Null
|
|
80
77
|
case "unknown":
|
|
@@ -114,7 +111,7 @@ export const runtimeSchemaForDbType = (
|
|
|
114
111
|
}
|
|
115
112
|
|
|
116
113
|
const makeSchemaFromAst = (ast: SchemaAST.AST): RuntimeSchema =>
|
|
117
|
-
Schema.make(ast)
|
|
114
|
+
Schema.make<RuntimeSchema>(ast)
|
|
118
115
|
|
|
119
116
|
const unionAst = (asts: ReadonlyArray<SchemaAST.AST>): SchemaAST.AST | undefined => {
|
|
120
117
|
if (asts.length === 0) {
|
|
@@ -123,7 +120,7 @@ const unionAst = (asts: ReadonlyArray<SchemaAST.AST>): SchemaAST.AST | undefined
|
|
|
123
120
|
if (asts.length === 1) {
|
|
124
121
|
return asts[0]
|
|
125
122
|
}
|
|
126
|
-
return SchemaAST.Union
|
|
123
|
+
return new SchemaAST.Union(asts, "anyOf")
|
|
127
124
|
}
|
|
128
125
|
|
|
129
126
|
const propertyAstOf = (
|
|
@@ -131,18 +128,14 @@ const propertyAstOf = (
|
|
|
131
128
|
key: string
|
|
132
129
|
): SchemaAST.AST | undefined => {
|
|
133
130
|
switch (ast._tag) {
|
|
134
|
-
case "Transformation":
|
|
135
|
-
return propertyAstOf(SchemaAST.typeAST(ast), key)
|
|
136
|
-
case "Refinement":
|
|
137
|
-
return propertyAstOf(ast.from, key)
|
|
138
131
|
case "Suspend":
|
|
139
|
-
return propertyAstOf(ast.
|
|
140
|
-
case "
|
|
132
|
+
return propertyAstOf(ast.thunk(), key)
|
|
133
|
+
case "Objects": {
|
|
141
134
|
const property = ast.propertySignatures.find((entry) => entry.name === key)
|
|
142
135
|
if (property !== undefined) {
|
|
143
136
|
return property.type
|
|
144
137
|
}
|
|
145
|
-
const index = ast.indexSignatures.find((entry) => entry.parameter._tag === "
|
|
138
|
+
const index = ast.indexSignatures.find((entry) => entry.parameter._tag === "String")
|
|
146
139
|
return index?.type
|
|
147
140
|
}
|
|
148
141
|
case "Union": {
|
|
@@ -162,21 +155,17 @@ const numberAstOf = (
|
|
|
162
155
|
index: number
|
|
163
156
|
): SchemaAST.AST | undefined => {
|
|
164
157
|
switch (ast._tag) {
|
|
165
|
-
case "Transformation":
|
|
166
|
-
return numberAstOf(SchemaAST.typeAST(ast), index)
|
|
167
|
-
case "Refinement":
|
|
168
|
-
return numberAstOf(ast.from, index)
|
|
169
158
|
case "Suspend":
|
|
170
|
-
return numberAstOf(ast.
|
|
171
|
-
case "
|
|
159
|
+
return numberAstOf(ast.thunk(), index)
|
|
160
|
+
case "Arrays": {
|
|
172
161
|
const element = ast.elements[index]
|
|
173
162
|
if (element !== undefined) {
|
|
174
|
-
return element
|
|
163
|
+
return element
|
|
175
164
|
}
|
|
176
165
|
if (ast.rest.length === 0) {
|
|
177
166
|
return undefined
|
|
178
167
|
}
|
|
179
|
-
return unionAst(ast.rest
|
|
168
|
+
return unionAst(ast.rest)
|
|
180
169
|
}
|
|
181
170
|
case "Union": {
|
|
182
171
|
const values = ast.types.flatMap((member) => {
|
|
@@ -199,7 +188,9 @@ const schemaAstAtExactJsonPath = (
|
|
|
199
188
|
schema: RuntimeSchema,
|
|
200
189
|
segments: readonly JsonPath.CanonicalSegment[]
|
|
201
190
|
): SchemaAST.AST | undefined => {
|
|
202
|
-
|
|
191
|
+
// JSON path operators return encoded JSON subvalues, so preserve field-level
|
|
192
|
+
// encoding links instead of walking the type-side AST.
|
|
193
|
+
let current: SchemaAST.AST = schema.ast
|
|
203
194
|
for (const segment of segments) {
|
|
204
195
|
if (segment.kind === "key") {
|
|
205
196
|
const property = propertyAstOf(current, segment.key)
|
|
@@ -230,7 +221,7 @@ const unionSchemas = (schemas: ReadonlyArray<RuntimeSchema | undefined>): Runtim
|
|
|
230
221
|
if (resolved.length === 1) {
|
|
231
222
|
return resolved[0]
|
|
232
223
|
}
|
|
233
|
-
return Schema.Union(
|
|
224
|
+
return Schema.Union(resolved)
|
|
234
225
|
}
|
|
235
226
|
|
|
236
227
|
const firstSelectedExpression = (
|
|
@@ -241,24 +232,23 @@ const firstSelectedExpression = (
|
|
|
241
232
|
}
|
|
242
233
|
|
|
243
234
|
const isJsonCompatibleAst = (ast: SchemaAST.AST): boolean => {
|
|
235
|
+
ast = SchemaAST.toType(ast)
|
|
244
236
|
switch (ast._tag) {
|
|
245
|
-
case "
|
|
246
|
-
case "
|
|
247
|
-
case "
|
|
248
|
-
case "
|
|
249
|
-
case "
|
|
237
|
+
case "String":
|
|
238
|
+
case "Number":
|
|
239
|
+
case "Boolean":
|
|
240
|
+
case "Null":
|
|
241
|
+
case "Arrays":
|
|
242
|
+
case "Objects":
|
|
250
243
|
return true
|
|
251
244
|
case "Literal":
|
|
252
|
-
return ast.literal ===
|
|
253
|
-
typeof ast.literal === "string" ||
|
|
245
|
+
return typeof ast.literal === "string" ||
|
|
254
246
|
typeof ast.literal === "number" ||
|
|
255
247
|
typeof ast.literal === "boolean"
|
|
256
248
|
case "Union":
|
|
257
249
|
return ast.types.every(isJsonCompatibleAst)
|
|
258
|
-
case "Transformation":
|
|
259
|
-
return isJsonCompatibleAst(SchemaAST.typeAST(ast))
|
|
260
250
|
case "Suspend":
|
|
261
|
-
return isJsonCompatibleAst(ast.
|
|
251
|
+
return isJsonCompatibleAst(ast.thunk())
|
|
262
252
|
default:
|
|
263
253
|
return false
|
|
264
254
|
}
|
|
@@ -268,7 +258,7 @@ const jsonCompatibleSchema = (schema: RuntimeSchema | undefined): RuntimeSchema
|
|
|
268
258
|
if (schema === undefined) {
|
|
269
259
|
return undefined
|
|
270
260
|
}
|
|
271
|
-
const ast = SchemaAST.
|
|
261
|
+
const ast = SchemaAST.toType(schema.ast)
|
|
272
262
|
return isJsonCompatibleAst(ast) ? schema : JsonValueSchema
|
|
273
263
|
}
|
|
274
264
|
|
|
@@ -283,7 +273,7 @@ const buildStructSchema = (
|
|
|
283
273
|
}
|
|
284
274
|
|
|
285
275
|
const buildTupleSchema = (values: readonly Expression.Any[], context?: SchemaContext): RuntimeSchema =>
|
|
286
|
-
Schema.Tuple(
|
|
276
|
+
Schema.Tuple(values.map((value) => expressionRuntimeSchema(value, context) ?? JsonValueSchema))
|
|
287
277
|
|
|
288
278
|
const deriveCaseSchema = (
|
|
289
279
|
ast: ExpressionAst.CaseNode,
|
|
@@ -19,7 +19,7 @@ const brandString = <BrandName extends string>(
|
|
|
19
19
|
brand: BrandName
|
|
20
20
|
): Schema.Schema<string & Brand.Brand<BrandName>> =>
|
|
21
21
|
Schema.String.pipe(
|
|
22
|
-
Schema.
|
|
22
|
+
Schema.check(Schema.isPattern(pattern)),
|
|
23
23
|
Schema.brand(brand)
|
|
24
24
|
) as unknown as Schema.Schema<string & Brand.Brand<BrandName>>
|
|
25
25
|
|
|
@@ -100,32 +100,32 @@ export const isValidInstantString = (value: string): boolean => {
|
|
|
100
100
|
}
|
|
101
101
|
|
|
102
102
|
export const LocalDateStringSchema = Schema.String.pipe(
|
|
103
|
-
Schema.
|
|
104
|
-
Schema.
|
|
103
|
+
Schema.check(Schema.isPattern(localDatePattern)),
|
|
104
|
+
Schema.check(Schema.makeFilter((value) => isValidLocalDateString(value))),
|
|
105
105
|
Schema.brand("LocalDateString")
|
|
106
106
|
) as unknown as Schema.Schema<LocalDateString>
|
|
107
107
|
|
|
108
108
|
export const LocalTimeStringSchema = Schema.String.pipe(
|
|
109
|
-
Schema.
|
|
110
|
-
Schema.
|
|
109
|
+
Schema.check(Schema.isPattern(localTimePattern)),
|
|
110
|
+
Schema.check(Schema.makeFilter((value) => isValidLocalTimeString(value))),
|
|
111
111
|
Schema.brand("LocalTimeString")
|
|
112
112
|
) as unknown as Schema.Schema<LocalTimeString>
|
|
113
113
|
|
|
114
114
|
export const OffsetTimeStringSchema = Schema.String.pipe(
|
|
115
|
-
Schema.
|
|
116
|
-
Schema.
|
|
115
|
+
Schema.check(Schema.isPattern(offsetTimePattern)),
|
|
116
|
+
Schema.check(Schema.makeFilter((value) => isValidOffsetTimeString(value))),
|
|
117
117
|
Schema.brand("OffsetTimeString")
|
|
118
118
|
) as unknown as Schema.Schema<OffsetTimeString>
|
|
119
119
|
|
|
120
120
|
export const LocalDateTimeStringSchema = Schema.String.pipe(
|
|
121
|
-
Schema.
|
|
122
|
-
Schema.
|
|
121
|
+
Schema.check(Schema.isPattern(localDateTimePattern)),
|
|
122
|
+
Schema.check(Schema.makeFilter((value) => isValidLocalDateTimeString(value))),
|
|
123
123
|
Schema.brand("LocalDateTimeString")
|
|
124
124
|
) as unknown as Schema.Schema<LocalDateTimeString>
|
|
125
125
|
|
|
126
126
|
export const InstantStringSchema = Schema.String.pipe(
|
|
127
|
-
Schema.
|
|
128
|
-
Schema.
|
|
127
|
+
Schema.check(Schema.isPattern(instantPattern)),
|
|
128
|
+
Schema.check(Schema.makeFilter((value) => isValidInstantString(value))),
|
|
129
129
|
Schema.brand("InstantString")
|
|
130
130
|
) as unknown as Schema.Schema<InstantString>
|
|
131
131
|
|
|
@@ -177,32 +177,29 @@ export const isCanonicalDecimalString = (value: string): boolean => {
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
export const BigIntStringSchema = Schema.String.pipe(
|
|
180
|
-
Schema.
|
|
180
|
+
Schema.check(Schema.makeFilter((value) => isCanonicalBigIntString(value))),
|
|
181
181
|
Schema.brand("BigIntString")
|
|
182
182
|
) as unknown as Schema.Schema<BigIntString>
|
|
183
183
|
|
|
184
184
|
export const DecimalStringSchema = Schema.String.pipe(
|
|
185
|
-
Schema.
|
|
185
|
+
Schema.check(Schema.makeFilter((value) => isCanonicalDecimalString(value))),
|
|
186
186
|
Schema.brand("DecimalString")
|
|
187
187
|
) as unknown as Schema.Schema<DecimalString>
|
|
188
188
|
|
|
189
189
|
export const JsonValueSchema: Schema.Schema<JsonValue> = Schema.suspend(() =>
|
|
190
|
-
Schema.Union(
|
|
190
|
+
Schema.Union([
|
|
191
191
|
Schema.String,
|
|
192
|
-
Schema.Number.
|
|
192
|
+
Schema.Number.check(Schema.isFinite()),
|
|
193
193
|
Schema.Boolean,
|
|
194
194
|
Schema.Null,
|
|
195
195
|
Schema.Array(JsonValueSchema),
|
|
196
|
-
Schema.Record(
|
|
197
|
-
|
|
198
|
-
value: JsonValueSchema
|
|
199
|
-
})
|
|
200
|
-
)
|
|
196
|
+
Schema.Record(Schema.String, JsonValueSchema)
|
|
197
|
+
])
|
|
201
198
|
)
|
|
202
199
|
|
|
203
|
-
export const JsonPrimitiveSchema: Schema.Schema<JsonPrimitive> = Schema.Union(
|
|
200
|
+
export const JsonPrimitiveSchema: Schema.Schema<JsonPrimitive> = Schema.Union([
|
|
204
201
|
Schema.String,
|
|
205
|
-
Schema.Number.
|
|
202
|
+
Schema.Number.check(Schema.isFinite()),
|
|
206
203
|
Schema.Boolean,
|
|
207
204
|
Schema.Null
|
|
208
|
-
)
|
|
205
|
+
])
|
package/src/internal/scalar.d.ts
CHANGED
|
@@ -73,7 +73,7 @@ export declare namespace DbType {
|
|
|
73
73
|
export interface State<Runtime, Db extends DbType.Any, Nullable extends Nullability, Dialect extends string, Kind extends ScalarKind, Deps extends BindingId = never> {
|
|
74
74
|
readonly runtime: Runtime;
|
|
75
75
|
readonly dbType: Db;
|
|
76
|
-
readonly runtimeSchema?: Schema.
|
|
76
|
+
readonly runtimeSchema?: Schema.Top;
|
|
77
77
|
readonly nullability: Nullable;
|
|
78
78
|
readonly dialect: Dialect;
|
|
79
79
|
readonly kind: Kind;
|
package/src/internal/scalar.ts
CHANGED
|
@@ -50,6 +50,7 @@ export declare namespace DbType {
|
|
|
50
50
|
readonly runtime?: RuntimeTag
|
|
51
51
|
readonly compareGroup?: string
|
|
52
52
|
readonly castTargets?: readonly string[]
|
|
53
|
+
readonly implicitTargets?: readonly string[]
|
|
53
54
|
readonly traits?: DatatypeTraits
|
|
54
55
|
readonly driverValueMapping?: DriverValueMapping
|
|
55
56
|
}
|
|
@@ -161,7 +162,7 @@ export interface State<
|
|
|
161
162
|
> {
|
|
162
163
|
readonly runtime: Runtime
|
|
163
164
|
readonly dbType: Db
|
|
164
|
-
readonly runtimeSchema?: Schema.
|
|
165
|
+
readonly runtimeSchema?: Schema.Top
|
|
165
166
|
readonly driverValueMapping?: DriverValueMapping
|
|
166
167
|
readonly nullability: Nullable
|
|
167
168
|
readonly dialect: Dialect
|
|
@@ -34,11 +34,11 @@ export type InsertRow<TableName extends string, Fields extends TableFieldMap> =
|
|
|
34
34
|
export type UpdateRow<TableName extends string, Fields extends TableFieldMap, PrimaryKey extends keyof Fields> = Simplify<Partial<{
|
|
35
35
|
[K in UpdateKeys<Fields, PrimaryKey>]: BrandedUpdateType<Fields[K], TableName, Extract<K, string>>;
|
|
36
36
|
}>>;
|
|
37
|
-
type SchemaOfVariant<Variant extends TableSchemaVariant, TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string> = Variant extends "select" ? Schema.
|
|
37
|
+
type SchemaOfVariant<Variant extends TableSchemaVariant, TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string> = Variant extends "select" ? Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never> : Variant extends "insert" ? Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never> : Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never>;
|
|
38
38
|
export declare const deriveSchema: <Variant extends TableSchemaVariant, TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(variant: Variant, tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => SchemaOfVariant<Variant, TableName, Fields, PrimaryKeyColumns>;
|
|
39
|
-
export declare const deriveSelectSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.
|
|
40
|
-
export declare const deriveInsertSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.
|
|
41
|
-
export declare const deriveUpdateSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.
|
|
39
|
+
export declare const deriveSelectSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never>;
|
|
40
|
+
export declare const deriveInsertSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never>;
|
|
41
|
+
export declare const deriveUpdateSchema: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never>;
|
|
42
42
|
/**
|
|
43
43
|
* Derives the `select`, `insert`, and `update` schemas for a table.
|
|
44
44
|
*
|
|
@@ -49,8 +49,8 @@ export declare const deriveUpdateSchema: <TableName extends string, Fields exten
|
|
|
49
49
|
* `deriveUpdateSchema` so individual variants are derived lazily.
|
|
50
50
|
*/
|
|
51
51
|
export declare const deriveSchemas: <TableName extends string, Fields extends TableFieldMap, PrimaryKeyColumns extends keyof Fields & string>(tableName: TableName, fields: Fields, primaryKeyColumns: readonly PrimaryKeyColumns[]) => {
|
|
52
|
-
readonly select: Schema.
|
|
53
|
-
readonly insert: Schema.
|
|
54
|
-
readonly update: Schema.
|
|
52
|
+
readonly select: Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never>;
|
|
53
|
+
readonly insert: Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never>;
|
|
54
|
+
readonly update: Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never>;
|
|
55
55
|
};
|
|
56
56
|
export {};
|
|
@@ -105,7 +105,7 @@ const maybeBrandSchema = (
|
|
|
105
105
|
column: AnyColumnDefinition,
|
|
106
106
|
tableName: string,
|
|
107
107
|
columnName: string
|
|
108
|
-
): Schema.
|
|
108
|
+
): Schema.Top =>
|
|
109
109
|
column.metadata.brand === true
|
|
110
110
|
? Schema.brand(`${tableName}.${columnName}`)(column.schema)
|
|
111
111
|
: column.schema
|
|
@@ -114,7 +114,7 @@ const selectSchema = (
|
|
|
114
114
|
column: AnyColumnDefinition,
|
|
115
115
|
tableName: string,
|
|
116
116
|
columnName: string
|
|
117
|
-
): Schema.
|
|
117
|
+
): Schema.Top =>
|
|
118
118
|
column.metadata.nullable ? Schema.NullOr(maybeBrandSchema(column, tableName, columnName)) : maybeBrandSchema(column, tableName, columnName)
|
|
119
119
|
|
|
120
120
|
const insertSchema = (
|
|
@@ -151,9 +151,9 @@ type SchemaOfVariant<
|
|
|
151
151
|
TableName extends string,
|
|
152
152
|
Fields extends TableFieldMap,
|
|
153
153
|
PrimaryKeyColumns extends keyof Fields & string
|
|
154
|
-
> = Variant extends "select" ? Schema.
|
|
155
|
-
: Variant extends "insert" ? Schema.
|
|
156
|
-
: Schema.
|
|
154
|
+
> = Variant extends "select" ? Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never>
|
|
155
|
+
: Variant extends "insert" ? Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never>
|
|
156
|
+
: Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never>
|
|
157
157
|
|
|
158
158
|
const fieldSchemaForVariant = (
|
|
159
159
|
variant: TableSchemaVariant,
|
|
@@ -202,7 +202,7 @@ export const deriveSelectSchema = <
|
|
|
202
202
|
tableName: TableName,
|
|
203
203
|
fields: Fields,
|
|
204
204
|
primaryKeyColumns: readonly PrimaryKeyColumns[]
|
|
205
|
-
): Schema.
|
|
205
|
+
): Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never> =>
|
|
206
206
|
deriveSchema("select", tableName, fields, primaryKeyColumns)
|
|
207
207
|
|
|
208
208
|
export const deriveInsertSchema = <
|
|
@@ -213,7 +213,7 @@ export const deriveInsertSchema = <
|
|
|
213
213
|
tableName: TableName,
|
|
214
214
|
fields: Fields,
|
|
215
215
|
primaryKeyColumns: readonly PrimaryKeyColumns[]
|
|
216
|
-
): Schema.
|
|
216
|
+
): Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never> =>
|
|
217
217
|
deriveSchema("insert", tableName, fields, primaryKeyColumns)
|
|
218
218
|
|
|
219
219
|
export const deriveUpdateSchema = <
|
|
@@ -224,7 +224,7 @@ export const deriveUpdateSchema = <
|
|
|
224
224
|
tableName: TableName,
|
|
225
225
|
fields: Fields,
|
|
226
226
|
primaryKeyColumns: readonly PrimaryKeyColumns[]
|
|
227
|
-
): Schema.
|
|
227
|
+
): Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never> =>
|
|
228
228
|
deriveSchema("update", tableName, fields, primaryKeyColumns)
|
|
229
229
|
|
|
230
230
|
/**
|
|
@@ -245,9 +245,9 @@ export const deriveSchemas = <
|
|
|
245
245
|
fields: Fields,
|
|
246
246
|
primaryKeyColumns: readonly PrimaryKeyColumns[]
|
|
247
247
|
): {
|
|
248
|
-
readonly select: Schema.
|
|
249
|
-
readonly insert: Schema.
|
|
250
|
-
readonly update: Schema.
|
|
248
|
+
readonly select: Schema.ConstraintDecoder<SelectRow<TableName, Fields>, never>
|
|
249
|
+
readonly insert: Schema.ConstraintDecoder<InsertRow<TableName, Fields>, never>
|
|
250
|
+
readonly update: Schema.ConstraintDecoder<UpdateRow<TableName, Fields, PrimaryKeyColumns>, never>
|
|
251
251
|
} => ({
|
|
252
252
|
select: deriveSelectSchema(tableName, fields, primaryKeyColumns),
|
|
253
253
|
insert: deriveInsertSchema(tableName, fields, primaryKeyColumns),
|
|
@@ -114,6 +114,7 @@ import * as ExpressionAst from "./expression-ast.js"
|
|
|
114
114
|
import { presenceWitnessesOfSourceLike } from "./implication-runtime.js"
|
|
115
115
|
import type { JsonNode } from "./json/ast.js"
|
|
116
116
|
import type { JsonPathUsageError } from "./json/errors.js"
|
|
117
|
+
import { withJsonPathAccess } from "./json/path-access.js"
|
|
117
118
|
import * as JsonPath from "./json/path.js"
|
|
118
119
|
import type {
|
|
119
120
|
JsonConcatResult,
|
|
@@ -300,17 +301,21 @@ type ComparableInput<
|
|
|
300
301
|
TimestampDb extends Expression.DbType.Any,
|
|
301
302
|
NullDb extends Expression.DbType.Any,
|
|
302
303
|
Operator extends string
|
|
303
|
-
> =
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
304
|
+
> = 0 extends (1 & Left)
|
|
305
|
+
? Right
|
|
306
|
+
: 0 extends (1 & Right)
|
|
307
|
+
? Right
|
|
308
|
+
: CanCompareDbTypes<
|
|
309
|
+
DialectDbTypeOfInput<Left, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
310
|
+
DialectDbTypeOfInput<Right, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
311
|
+
Dialect
|
|
312
|
+
> extends true ? Right : OperandCompatibilityError<
|
|
313
|
+
Operator,
|
|
314
|
+
DialectDbTypeOfInput<Left, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
315
|
+
DialectDbTypeOfInput<Right, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
316
|
+
Dialect,
|
|
317
|
+
"the same db type family"
|
|
318
|
+
>
|
|
314
319
|
|
|
315
320
|
type TextInput<
|
|
316
321
|
Value extends ExpressionInput,
|
|
@@ -1519,7 +1524,7 @@ type NumberWindowExpression<
|
|
|
1519
1524
|
*/
|
|
1520
1525
|
type Dialect = "standard"
|
|
1521
1526
|
type TextDb = ReturnType<typeof standardDatatypes.text>
|
|
1522
|
-
type NumericDb = ReturnType<typeof standardDatatypes.
|
|
1527
|
+
type NumericDb = ReturnType<typeof standardDatatypes.real>
|
|
1523
1528
|
type BoolDb = ReturnType<typeof standardDatatypes.boolean>
|
|
1524
1529
|
type TimestampDb = ReturnType<typeof standardDatatypes.timestamp>
|
|
1525
1530
|
type NullDb = Expression.DbType.Base<"standard", "null"> & {
|
|
@@ -1533,7 +1538,7 @@ type TypeWitnesses = typeof standardDatatypes
|
|
|
1533
1538
|
const profile: QueryDialectProfile<Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb, TypeWitnesses> = {
|
|
1534
1539
|
dialect: "standard",
|
|
1535
1540
|
textDb: standardDatatypes.text() as TextDb,
|
|
1536
|
-
numericDb: standardDatatypes.
|
|
1541
|
+
numericDb: standardDatatypes.real() as NumericDb,
|
|
1537
1542
|
boolDb: standardDatatypes.boolean() as BoolDb,
|
|
1538
1543
|
timestampDb: standardDatatypes.timestamp() as TimestampDb,
|
|
1539
1544
|
nullDb: {
|
|
@@ -1554,11 +1559,11 @@ const profile: QueryDialectProfile<Dialect, TextDb, NumericDb, BoolDb, Timestamp
|
|
|
1554
1559
|
|
|
1555
1560
|
const literalSchemaOf = <Value extends LiteralValue>(
|
|
1556
1561
|
value: Value
|
|
1557
|
-
): Schema.
|
|
1562
|
+
): Schema.Top | undefined => {
|
|
1558
1563
|
if (value === null || value instanceof Date) {
|
|
1559
1564
|
return undefined
|
|
1560
1565
|
}
|
|
1561
|
-
return Schema.Literal(value) as Schema.
|
|
1566
|
+
return Schema.Literal(value) as unknown as Schema.Top
|
|
1562
1567
|
}
|
|
1563
1568
|
|
|
1564
1569
|
const literal = <const Value extends LiteralValue>(
|
|
@@ -2339,13 +2344,6 @@ type BinaryPredicateExpression<
|
|
|
2339
2344
|
|
|
2340
2345
|
const type = {
|
|
2341
2346
|
...profile.type,
|
|
2342
|
-
array,
|
|
2343
|
-
range,
|
|
2344
|
-
multirange,
|
|
2345
|
-
record,
|
|
2346
|
-
domain,
|
|
2347
|
-
enum: enum_,
|
|
2348
|
-
set,
|
|
2349
2347
|
custom,
|
|
2350
2348
|
driverValueMapping
|
|
2351
2349
|
}
|
|
@@ -2403,7 +2401,7 @@ type BinaryPredicateExpression<
|
|
|
2403
2401
|
MergeAggregationTuple<typeof expressions>,
|
|
2404
2402
|
TupleDependencies<typeof expressions>,
|
|
2405
2403
|
Ast
|
|
2406
|
-
> => makeExpression({
|
|
2404
|
+
> => withJsonPathAccess(makeExpression({
|
|
2407
2405
|
runtime: state.runtime,
|
|
2408
2406
|
dbType: state.dbType,
|
|
2409
2407
|
nullability: state.nullability,
|
|
@@ -2411,7 +2409,7 @@ type BinaryPredicateExpression<
|
|
|
2411
2409
|
kind: mergeAggregationManyRuntime(expressions) as MergeAggregationTuple<typeof expressions>,
|
|
2412
2410
|
|
|
2413
2411
|
dependencies: mergeManyDependencies(expressions)
|
|
2414
|
-
}, ast) as AstBackedExpression<
|
|
2412
|
+
}, ast)) as AstBackedExpression<
|
|
2415
2413
|
Runtime,
|
|
2416
2414
|
Db,
|
|
2417
2415
|
Nullability,
|
|
@@ -2432,7 +2430,7 @@ type BinaryPredicateExpression<
|
|
|
2432
2430
|
const makeJsonLiteralExpression = <Value extends JsonLiteralInput>(
|
|
2433
2431
|
value: Value,
|
|
2434
2432
|
dbType: Expression.DbType.Json<any, any> = jsonDb
|
|
2435
|
-
) => makeExpression({
|
|
2433
|
+
) => withJsonPathAccess(makeExpression({
|
|
2436
2434
|
runtime: value as JsonRuntime<Value>,
|
|
2437
2435
|
dbType,
|
|
2438
2436
|
nullability: (value === null ? "always" : "never") as JsonNullabilityOf<Value>,
|
|
@@ -2443,7 +2441,7 @@ type BinaryPredicateExpression<
|
|
|
2443
2441
|
}, {
|
|
2444
2442
|
kind: "literal",
|
|
2445
2443
|
value
|
|
2446
|
-
})
|
|
2444
|
+
}))
|
|
2447
2445
|
|
|
2448
2446
|
const wrapJsonExpression = (
|
|
2449
2447
|
value: Expression.Any,
|
|
@@ -4524,6 +4522,83 @@ type ValidateTargetColumnInput<
|
|
|
4524
4522
|
Columns extends DdlColumnInput
|
|
4525
4523
|
> = ValidateTargetColumns<Target, NormalizeDdlColumns<Columns>> extends never ? never : Columns
|
|
4526
4524
|
|
|
4525
|
+
type SameColumnSet<
|
|
4526
|
+
Left extends readonly string[],
|
|
4527
|
+
Right extends readonly string[]
|
|
4528
|
+
> = string extends Left[number] | Right[number]
|
|
4529
|
+
? false
|
|
4530
|
+
: Exclude<Left[number], Right[number]> extends never
|
|
4531
|
+
? Exclude<Right[number], Left[number]> extends never
|
|
4532
|
+
? true
|
|
4533
|
+
: false
|
|
4534
|
+
: false
|
|
4535
|
+
|
|
4536
|
+
type ConflictArbitersOf<Target extends MutationTargetLike> =
|
|
4537
|
+
Target[typeof Table.TypeId]["conflictArbiters"][number]
|
|
4538
|
+
|
|
4539
|
+
type MatchingConflictArbiter<
|
|
4540
|
+
Target extends MutationTargetLike,
|
|
4541
|
+
Columns extends readonly string[],
|
|
4542
|
+
AllowPartial extends boolean
|
|
4543
|
+
> = ConflictArbitersOf<Target> extends infer Arbiter extends Table.ConflictArbiter
|
|
4544
|
+
? Arbiter extends Table.ConflictArbiter
|
|
4545
|
+
? SameColumnSet<Arbiter["columns"], Columns> extends true
|
|
4546
|
+
? Arbiter["scope"] extends "unconditional"
|
|
4547
|
+
? true
|
|
4548
|
+
: AllowPartial extends true ? true : never
|
|
4549
|
+
: never
|
|
4550
|
+
: never
|
|
4551
|
+
: never
|
|
4552
|
+
|
|
4553
|
+
type HasInlineConflictArbiter<
|
|
4554
|
+
Target extends MutationTargetLike,
|
|
4555
|
+
Columns extends readonly string[]
|
|
4556
|
+
> = Columns extends readonly [infer Column extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>]
|
|
4557
|
+
? Target[typeof Table.TypeId]["fields"][Column] extends { readonly metadata: { readonly primaryKey: true } | { readonly unique: true } }
|
|
4558
|
+
? true
|
|
4559
|
+
: false
|
|
4560
|
+
: false
|
|
4561
|
+
|
|
4562
|
+
type HasConflictArbiter<
|
|
4563
|
+
Target extends MutationTargetLike,
|
|
4564
|
+
Columns extends readonly string[],
|
|
4565
|
+
AllowPartial extends boolean
|
|
4566
|
+
> = string extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>
|
|
4567
|
+
? true
|
|
4568
|
+
: HasInlineConflictArbiter<Target, Columns> extends true
|
|
4569
|
+
? true
|
|
4570
|
+
: true extends MatchingConflictArbiter<Target, Columns, AllowPartial> ? true : false
|
|
4571
|
+
|
|
4572
|
+
type ConflictTargetArbiterError<
|
|
4573
|
+
Columns,
|
|
4574
|
+
AllowPartial extends boolean
|
|
4575
|
+
> = {
|
|
4576
|
+
readonly __effect_qb_error__: "effect-qb: conflict target columns must match a primary key, unique constraint, or unique index"
|
|
4577
|
+
readonly __effect_qb_conflict_columns__: Columns
|
|
4578
|
+
readonly __effect_qb_partial_target__: AllowPartial
|
|
4579
|
+
readonly __effect_qb_hint__: "Declare the target columns as primaryKey/unique, add a table-level Unique.make(...), or use a simple Pg.Index.uniqueIndex(...)"
|
|
4580
|
+
}
|
|
4581
|
+
|
|
4582
|
+
type ValidateConflictColumnInput<
|
|
4583
|
+
Target extends MutationTargetLike,
|
|
4584
|
+
Columns extends DdlColumnInput,
|
|
4585
|
+
AllowPartial extends boolean
|
|
4586
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4587
|
+
? never
|
|
4588
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4589
|
+
? Columns
|
|
4590
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4591
|
+
|
|
4592
|
+
type ConflictColumnPlanConstraint<
|
|
4593
|
+
Target extends MutationTargetLike,
|
|
4594
|
+
Columns extends DdlColumnInput,
|
|
4595
|
+
AllowPartial extends boolean
|
|
4596
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4597
|
+
? never
|
|
4598
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4599
|
+
? unknown
|
|
4600
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4601
|
+
|
|
4527
4602
|
type CreateIndexOptions<Name extends string = string> = {
|
|
4528
4603
|
readonly name?: NonEmptyStringInput<Name>
|
|
4529
4604
|
readonly unique?: boolean
|
|
@@ -4964,6 +5039,21 @@ type ConflictConstraintNameConstraint<Target> =
|
|
|
4964
5039
|
? { readonly constraint: NonEmptyStringInput<Constraint> }
|
|
4965
5040
|
: unknown
|
|
4966
5041
|
|
|
5042
|
+
type ConflictTargetHasPredicate<Target> =
|
|
5043
|
+
Target extends { readonly where: PredicateInput } ? true : false
|
|
5044
|
+
|
|
5045
|
+
type ConflictTargetPlanConstraint<
|
|
5046
|
+
Target extends MutationTargetLike,
|
|
5047
|
+
ConflictTarget
|
|
5048
|
+
> =
|
|
5049
|
+
ConflictTarget extends { readonly constraint: string }
|
|
5050
|
+
? unknown
|
|
5051
|
+
: ConflictTarget extends { readonly columns: infer Columns extends DdlColumnInput }
|
|
5052
|
+
? ConflictColumnPlanConstraint<Target, Columns, ConflictTargetHasPredicate<ConflictTarget>>
|
|
5053
|
+
: ConflictTarget extends DdlColumnInput
|
|
5054
|
+
? ConflictColumnPlanConstraint<Target, ConflictTarget, false>
|
|
5055
|
+
: unknown
|
|
5056
|
+
|
|
4967
5057
|
type ConflictActionInput<
|
|
4968
5058
|
Target extends MutationTargetLike,
|
|
4969
5059
|
Dialect extends string,
|
|
@@ -6295,7 +6385,7 @@ type AsCurriedResult<
|
|
|
6295
6385
|
options?: Options & ConflictActionUpdateNonEmptyConstraint<Options>
|
|
6296
6386
|
) =>
|
|
6297
6387
|
<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
6298
|
-
plan: PlanValue & RequireInsertStatement<PlanValue>
|
|
6388
|
+
plan: PlanValue & RequireInsertStatement<PlanValue> & ConflictTargetPlanConstraint<MutationTargetOfPlan<PlanValue>, ConflictTarget>
|
|
6299
6389
|
) => QueryPlan<
|
|
6300
6390
|
SelectionOfPlan<PlanValue>,
|
|
6301
6391
|
Exclude<RequiredOfPlan<PlanValue> | ConflictRequired<UpdateValues, Options, ConflictTarget>, AvailableNames<AvailableOfPlan<PlanValue>>>,
|
|
@@ -6359,7 +6449,7 @@ type AsCurriedResult<
|
|
|
6359
6449
|
>(
|
|
6360
6450
|
target: Target,
|
|
6361
6451
|
values: Values & MutationValuesDialectConstraint<Values, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
6362
|
-
conflictColumns:
|
|
6452
|
+
conflictColumns: ValidateConflictColumnInput<Target, Columns, false>,
|
|
6363
6453
|
updateValues?: UpdateValues & UpdateValuesNonEmptyConstraint<Exclude<UpdateValues, undefined>> & MutationValuesDialectConstraint<Exclude<UpdateValues, undefined>, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>
|
|
6364
6454
|
) => QueryPlan<
|
|
6365
6455
|
{},
|