effect-qb 0.19.0 → 0.21.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 +7 -1
- package/dist/index.js +1990 -679
- package/dist/mysql.js +1490 -617
- package/dist/postgres/metadata.js +1334 -263
- package/dist/postgres.js +3376 -2307
- package/dist/sqlite.js +1573 -628
- package/dist/standard.js +1984 -673
- package/package.json +3 -6
- 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 +121 -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/errors/normalize.ts +0 -1
- package/src/mysql/executor.ts +4 -6
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dsl.ts +116 -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/errors/normalize.ts +0 -1
- 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 +122 -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/errors/normalize.ts +0 -1
- package/src/sqlite/executor.ts +4 -6
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dsl.ts +100 -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,14 @@ 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
|
-
|
|
1566
|
+
if (typeof value === "number" && !Number.isFinite(value)) {
|
|
1567
|
+
return undefined
|
|
1568
|
+
}
|
|
1569
|
+
return Schema.Literal(value) as unknown as Schema.Top
|
|
1562
1570
|
}
|
|
1563
1571
|
|
|
1564
1572
|
const literal = <const Value extends LiteralValue>(
|
|
@@ -2339,13 +2347,6 @@ type BinaryPredicateExpression<
|
|
|
2339
2347
|
|
|
2340
2348
|
const type = {
|
|
2341
2349
|
...profile.type,
|
|
2342
|
-
array,
|
|
2343
|
-
range,
|
|
2344
|
-
multirange,
|
|
2345
|
-
record,
|
|
2346
|
-
domain,
|
|
2347
|
-
enum: enum_,
|
|
2348
|
-
set,
|
|
2349
2350
|
custom,
|
|
2350
2351
|
driverValueMapping
|
|
2351
2352
|
}
|
|
@@ -2403,7 +2404,7 @@ type BinaryPredicateExpression<
|
|
|
2403
2404
|
MergeAggregationTuple<typeof expressions>,
|
|
2404
2405
|
TupleDependencies<typeof expressions>,
|
|
2405
2406
|
Ast
|
|
2406
|
-
> => makeExpression({
|
|
2407
|
+
> => withJsonPathAccess(makeExpression({
|
|
2407
2408
|
runtime: state.runtime,
|
|
2408
2409
|
dbType: state.dbType,
|
|
2409
2410
|
nullability: state.nullability,
|
|
@@ -2411,7 +2412,7 @@ type BinaryPredicateExpression<
|
|
|
2411
2412
|
kind: mergeAggregationManyRuntime(expressions) as MergeAggregationTuple<typeof expressions>,
|
|
2412
2413
|
|
|
2413
2414
|
dependencies: mergeManyDependencies(expressions)
|
|
2414
|
-
}, ast) as AstBackedExpression<
|
|
2415
|
+
}, ast)) as AstBackedExpression<
|
|
2415
2416
|
Runtime,
|
|
2416
2417
|
Db,
|
|
2417
2418
|
Nullability,
|
|
@@ -2432,7 +2433,7 @@ type BinaryPredicateExpression<
|
|
|
2432
2433
|
const makeJsonLiteralExpression = <Value extends JsonLiteralInput>(
|
|
2433
2434
|
value: Value,
|
|
2434
2435
|
dbType: Expression.DbType.Json<any, any> = jsonDb
|
|
2435
|
-
) => makeExpression({
|
|
2436
|
+
) => withJsonPathAccess(makeExpression({
|
|
2436
2437
|
runtime: value as JsonRuntime<Value>,
|
|
2437
2438
|
dbType,
|
|
2438
2439
|
nullability: (value === null ? "always" : "never") as JsonNullabilityOf<Value>,
|
|
@@ -2443,7 +2444,7 @@ type BinaryPredicateExpression<
|
|
|
2443
2444
|
}, {
|
|
2444
2445
|
kind: "literal",
|
|
2445
2446
|
value
|
|
2446
|
-
})
|
|
2447
|
+
}))
|
|
2447
2448
|
|
|
2448
2449
|
const wrapJsonExpression = (
|
|
2449
2450
|
value: Expression.Any,
|
|
@@ -4524,6 +4525,83 @@ type ValidateTargetColumnInput<
|
|
|
4524
4525
|
Columns extends DdlColumnInput
|
|
4525
4526
|
> = ValidateTargetColumns<Target, NormalizeDdlColumns<Columns>> extends never ? never : Columns
|
|
4526
4527
|
|
|
4528
|
+
type SameColumnSet<
|
|
4529
|
+
Left extends readonly string[],
|
|
4530
|
+
Right extends readonly string[]
|
|
4531
|
+
> = string extends Left[number] | Right[number]
|
|
4532
|
+
? false
|
|
4533
|
+
: Exclude<Left[number], Right[number]> extends never
|
|
4534
|
+
? Exclude<Right[number], Left[number]> extends never
|
|
4535
|
+
? true
|
|
4536
|
+
: false
|
|
4537
|
+
: false
|
|
4538
|
+
|
|
4539
|
+
type ConflictArbitersOf<Target extends MutationTargetLike> =
|
|
4540
|
+
Target[typeof Table.TypeId]["conflictArbiters"][number]
|
|
4541
|
+
|
|
4542
|
+
type MatchingConflictArbiter<
|
|
4543
|
+
Target extends MutationTargetLike,
|
|
4544
|
+
Columns extends readonly string[],
|
|
4545
|
+
AllowPartial extends boolean
|
|
4546
|
+
> = ConflictArbitersOf<Target> extends infer Arbiter extends Table.ConflictArbiter
|
|
4547
|
+
? Arbiter extends Table.ConflictArbiter
|
|
4548
|
+
? SameColumnSet<Arbiter["columns"], Columns> extends true
|
|
4549
|
+
? Arbiter["scope"] extends "unconditional"
|
|
4550
|
+
? true
|
|
4551
|
+
: AllowPartial extends true ? true : never
|
|
4552
|
+
: never
|
|
4553
|
+
: never
|
|
4554
|
+
: never
|
|
4555
|
+
|
|
4556
|
+
type HasInlineConflictArbiter<
|
|
4557
|
+
Target extends MutationTargetLike,
|
|
4558
|
+
Columns extends readonly string[]
|
|
4559
|
+
> = Columns extends readonly [infer Column extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>]
|
|
4560
|
+
? Target[typeof Table.TypeId]["fields"][Column] extends { readonly metadata: { readonly primaryKey: true } | { readonly unique: true } }
|
|
4561
|
+
? true
|
|
4562
|
+
: false
|
|
4563
|
+
: false
|
|
4564
|
+
|
|
4565
|
+
type HasConflictArbiter<
|
|
4566
|
+
Target extends MutationTargetLike,
|
|
4567
|
+
Columns extends readonly string[],
|
|
4568
|
+
AllowPartial extends boolean
|
|
4569
|
+
> = string extends Extract<keyof Target[typeof Table.TypeId]["fields"], string>
|
|
4570
|
+
? true
|
|
4571
|
+
: HasInlineConflictArbiter<Target, Columns> extends true
|
|
4572
|
+
? true
|
|
4573
|
+
: true extends MatchingConflictArbiter<Target, Columns, AllowPartial> ? true : false
|
|
4574
|
+
|
|
4575
|
+
type ConflictTargetArbiterError<
|
|
4576
|
+
Columns,
|
|
4577
|
+
AllowPartial extends boolean
|
|
4578
|
+
> = {
|
|
4579
|
+
readonly __effect_qb_error__: "effect-qb: conflict target columns must match a primary key, unique constraint, or unique index"
|
|
4580
|
+
readonly __effect_qb_conflict_columns__: Columns
|
|
4581
|
+
readonly __effect_qb_partial_target__: AllowPartial
|
|
4582
|
+
readonly __effect_qb_hint__: "Declare the target columns as primaryKey/unique, add a table-level Unique.make(...), or use a simple Pg.Index.uniqueIndex(...)"
|
|
4583
|
+
}
|
|
4584
|
+
|
|
4585
|
+
type ValidateConflictColumnInput<
|
|
4586
|
+
Target extends MutationTargetLike,
|
|
4587
|
+
Columns extends DdlColumnInput,
|
|
4588
|
+
AllowPartial extends boolean
|
|
4589
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4590
|
+
? never
|
|
4591
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4592
|
+
? Columns
|
|
4593
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4594
|
+
|
|
4595
|
+
type ConflictColumnPlanConstraint<
|
|
4596
|
+
Target extends MutationTargetLike,
|
|
4597
|
+
Columns extends DdlColumnInput,
|
|
4598
|
+
AllowPartial extends boolean
|
|
4599
|
+
> = ValidateTargetColumnInput<Target, Columns> extends never
|
|
4600
|
+
? never
|
|
4601
|
+
: HasConflictArbiter<Target, NormalizeDdlColumns<Columns>, AllowPartial> extends true
|
|
4602
|
+
? unknown
|
|
4603
|
+
: ConflictTargetArbiterError<NormalizeDdlColumns<Columns>, AllowPartial>
|
|
4604
|
+
|
|
4527
4605
|
type CreateIndexOptions<Name extends string = string> = {
|
|
4528
4606
|
readonly name?: NonEmptyStringInput<Name>
|
|
4529
4607
|
readonly unique?: boolean
|
|
@@ -4964,6 +5042,21 @@ type ConflictConstraintNameConstraint<Target> =
|
|
|
4964
5042
|
? { readonly constraint: NonEmptyStringInput<Constraint> }
|
|
4965
5043
|
: unknown
|
|
4966
5044
|
|
|
5045
|
+
type ConflictTargetHasPredicate<Target> =
|
|
5046
|
+
Target extends { readonly where: PredicateInput } ? true : false
|
|
5047
|
+
|
|
5048
|
+
type ConflictTargetPlanConstraint<
|
|
5049
|
+
Target extends MutationTargetLike,
|
|
5050
|
+
ConflictTarget
|
|
5051
|
+
> =
|
|
5052
|
+
ConflictTarget extends { readonly constraint: string }
|
|
5053
|
+
? unknown
|
|
5054
|
+
: ConflictTarget extends { readonly columns: infer Columns extends DdlColumnInput }
|
|
5055
|
+
? ConflictColumnPlanConstraint<Target, Columns, ConflictTargetHasPredicate<ConflictTarget>>
|
|
5056
|
+
: ConflictTarget extends DdlColumnInput
|
|
5057
|
+
? ConflictColumnPlanConstraint<Target, ConflictTarget, false>
|
|
5058
|
+
: unknown
|
|
5059
|
+
|
|
4967
5060
|
type ConflictActionInput<
|
|
4968
5061
|
Target extends MutationTargetLike,
|
|
4969
5062
|
Dialect extends string,
|
|
@@ -6295,7 +6388,7 @@ type AsCurriedResult<
|
|
|
6295
6388
|
options?: Options & ConflictActionUpdateNonEmptyConstraint<Options>
|
|
6296
6389
|
) =>
|
|
6297
6390
|
<PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
|
|
6298
|
-
plan: PlanValue & RequireInsertStatement<PlanValue>
|
|
6391
|
+
plan: PlanValue & RequireInsertStatement<PlanValue> & ConflictTargetPlanConstraint<MutationTargetOfPlan<PlanValue>, ConflictTarget>
|
|
6299
6392
|
) => QueryPlan<
|
|
6300
6393
|
SelectionOfPlan<PlanValue>,
|
|
6301
6394
|
Exclude<RequiredOfPlan<PlanValue> | ConflictRequired<UpdateValues, Options, ConflictTarget>, AvailableNames<AvailableOfPlan<PlanValue>>>,
|
|
@@ -6359,7 +6452,7 @@ type AsCurriedResult<
|
|
|
6359
6452
|
>(
|
|
6360
6453
|
target: Target,
|
|
6361
6454
|
values: Values & MutationValuesDialectConstraint<Values, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>,
|
|
6362
|
-
conflictColumns:
|
|
6455
|
+
conflictColumns: ValidateConflictColumnInput<Target, Columns, false>,
|
|
6363
6456
|
updateValues?: UpdateValues & UpdateValuesNonEmptyConstraint<Exclude<UpdateValues, undefined>> & MutationValuesDialectConstraint<Exclude<UpdateValues, undefined>, Dialect, TextDb, NumericDb, BoolDb, TimestampDb, NullDb>
|
|
6364
6457
|
) => QueryPlan<
|
|
6365
6458
|
{},
|