effect-qb 0.17.0 → 0.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -1
- package/dist/index.js +9376 -0
- package/dist/mysql.js +4092 -2671
- package/dist/postgres/metadata.js +2589 -1402
- package/dist/postgres.js +3953 -3583
- package/dist/sqlite.js +5527 -4088
- package/dist/standard.js +9330 -0
- package/package.json +9 -4
- package/src/casing.ts +71 -0
- package/src/index.ts +2 -0
- package/src/internal/casing.ts +89 -0
- package/src/internal/coercion/rules.ts +13 -1
- package/src/internal/column-state.d.ts +3 -3
- package/src/internal/column-state.ts +24 -18
- package/src/internal/column.ts +52 -15
- package/src/internal/datatypes/define.ts +7 -1
- package/src/internal/datatypes/enrich.ts +23 -0
- package/src/internal/datatypes/lookup.ts +81 -25
- package/src/internal/datatypes/matrix.ts +903 -0
- package/src/internal/datatypes/shape.ts +2 -0
- package/src/internal/derived-table.ts +4 -36
- package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/mysql.ts} +552 -361
- package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +657 -400
- package/src/{sqlite/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +505 -347
- package/src/internal/dialect.ts +36 -1
- package/src/internal/dsl-mutation-runtime.ts +12 -162
- package/src/internal/dsl-plan-runtime.ts +10 -138
- package/src/internal/dsl-query-runtime.ts +5 -79
- package/src/internal/dsl-transaction-ddl-runtime.ts +41 -65
- package/src/internal/executor.ts +66 -49
- package/src/internal/grouping-key.ts +87 -20
- package/src/internal/implication-runtime.ts +1 -1
- package/src/internal/json/path-access.ts +351 -0
- package/src/internal/predicate/runtime.ts +3 -0
- package/src/internal/query.d.ts +39 -12
- package/src/internal/query.ts +65 -26
- package/src/internal/renderer.ts +26 -14
- package/src/internal/runtime/driver-value-mapping.ts +3 -3
- package/src/internal/runtime/normalize.ts +12 -5
- 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 +8 -2
- package/src/internal/schema-derivation.d.ts +12 -61
- package/src/internal/schema-derivation.ts +95 -43
- package/src/internal/schema-expression.ts +2 -2
- package/src/internal/sql-expression-renderer.ts +19 -0
- package/src/internal/standard-dsl.ts +6978 -0
- package/src/internal/table-options.ts +126 -66
- package/src/internal/table.ts +819 -237
- package/src/mysql/column-extension.ts +3 -0
- package/src/mysql/column.ts +14 -15
- package/src/mysql/datatypes/index.ts +4 -2
- package/src/mysql/datatypes/spec.ts +6 -176
- package/src/mysql/errors/normalize.ts +0 -1
- package/src/mysql/executor.ts +11 -11
- package/src/mysql/function/temporal.ts +1 -1
- package/src/mysql/internal/dialect.ts +9 -4
- package/src/mysql/internal/dsl.ts +334 -170
- package/src/mysql/internal/renderer.ts +6 -2
- package/src/mysql/json.ts +7 -2
- package/src/mysql/query-extension.ts +16 -0
- package/src/mysql/renderer.ts +37 -3
- package/src/mysql/type.ts +60 -0
- package/src/mysql.ts +7 -13
- package/src/postgres/check.ts +1 -0
- package/src/postgres/column-extension.ts +28 -0
- package/src/postgres/column.ts +13 -19
- package/src/postgres/datatypes/index.d.ts +2 -1
- package/src/postgres/datatypes/index.ts +4 -2
- package/src/postgres/datatypes/spec.ts +6 -260
- package/src/postgres/errors/normalize.ts +0 -1
- package/src/postgres/executor.ts +11 -11
- package/src/postgres/foreign-key.ts +24 -0
- package/src/postgres/function/core.ts +1 -3
- package/src/postgres/function/index.ts +1 -17
- package/src/postgres/function/temporal.ts +1 -1
- package/src/postgres/index.ts +1 -0
- package/src/postgres/internal/dialect.ts +9 -4
- package/src/postgres/internal/dsl.ts +328 -179
- package/src/postgres/internal/renderer.ts +6 -2
- package/src/postgres/internal/schema-ddl.ts +22 -10
- package/src/postgres/internal/schema-model.ts +238 -7
- package/src/postgres/json-extension.ts +7 -0
- package/src/postgres/json.ts +762 -173
- package/src/postgres/jsonb.ts +37 -0
- package/src/postgres/primary-key.ts +24 -0
- package/src/postgres/query-extension.ts +2 -0
- package/src/postgres/renderer.ts +37 -3
- package/src/postgres/schema-management.ts +13 -13
- package/src/postgres/schema.ts +106 -15
- package/src/postgres/table.ts +205 -538
- package/src/postgres/type.ts +93 -10
- package/src/postgres/unique.ts +32 -0
- package/src/postgres.ts +20 -16
- package/src/sqlite/column-extension.ts +3 -0
- package/src/sqlite/column.ts +14 -15
- package/src/sqlite/datatypes/index.ts +4 -2
- package/src/sqlite/datatypes/spec.ts +6 -94
- package/src/sqlite/errors/normalize.ts +0 -1
- package/src/sqlite/executor.ts +11 -11
- package/src/sqlite/function/temporal.ts +1 -1
- package/src/sqlite/internal/dialect.ts +9 -4
- package/src/sqlite/internal/dsl.ts +307 -159
- package/src/sqlite/internal/renderer.ts +6 -2
- package/src/sqlite/json.ts +8 -2
- package/src/sqlite/query-extension.ts +2 -0
- package/src/sqlite/renderer.ts +37 -3
- package/src/sqlite/type.ts +40 -0
- package/src/sqlite.ts +7 -13
- package/src/standard/cast.ts +113 -0
- package/src/standard/check.ts +17 -0
- package/src/standard/column.ts +163 -0
- package/src/standard/datatypes/index.ts +83 -0
- package/src/standard/datatypes/spec.ts +12 -0
- package/src/standard/dialect.ts +40 -0
- package/src/standard/foreign-key.ts +37 -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/index.ts +17 -0
- package/src/standard/internal/renderer.ts +45 -0
- package/src/standard/json.ts +883 -0
- package/src/standard/primary-key.ts +17 -0
- package/src/standard/query.ts +152 -0
- package/src/standard/renderer.ts +49 -0
- package/src/standard/table.ts +151 -0
- package/src/standard/unique.ts +17 -0
- package/src/standard.ts +32 -0
- package/src/internal/aggregation-validation.ts +0 -57
- package/src/internal/table.d.ts +0 -173
- package/src/mysql/table.ts +0 -183
- package/src/postgres/cast.ts +0 -45
- package/src/sqlite/table.ts +0 -183
package/src/internal/query.ts
CHANGED
|
@@ -96,7 +96,7 @@ export { union_query_capabilities } from "./query-requirements.js"
|
|
|
96
96
|
* `Pipeable.pipe(...)` plus the metadata stored under `Expression.TypeId`.
|
|
97
97
|
*/
|
|
98
98
|
const ExpressionProto = {
|
|
99
|
-
pipe(this:
|
|
99
|
+
pipe(this: Pipeable) {
|
|
100
100
|
return pipeArguments(this, arguments)
|
|
101
101
|
}
|
|
102
102
|
}
|
|
@@ -108,7 +108,7 @@ const ExpressionProto = {
|
|
|
108
108
|
* chained through `.pipe(...)`.
|
|
109
109
|
*/
|
|
110
110
|
const PlanProto = {
|
|
111
|
-
pipe(this:
|
|
111
|
+
pipe(this: Pipeable) {
|
|
112
112
|
return pipeArguments(this, arguments)
|
|
113
113
|
}
|
|
114
114
|
}
|
|
@@ -143,6 +143,34 @@ export interface QueryState<
|
|
|
143
143
|
|
|
144
144
|
/** Effective SQL dialect carried by an expression. */
|
|
145
145
|
export type DialectOf<Value extends Expression.Any> = Value[typeof Expression.TypeId]["dialect"]
|
|
146
|
+
type ConcreteDialect<D> = D extends "standard" ? never : D
|
|
147
|
+
type IsDialectUnion<Union, All = Union> = Union extends any
|
|
148
|
+
? [All] extends [Union] ? false : true
|
|
149
|
+
: false
|
|
150
|
+
export type DialectConflictError<A extends string, B extends string> = string & {
|
|
151
|
+
readonly _tag: "DialectConflict"
|
|
152
|
+
readonly left: A
|
|
153
|
+
readonly right: B
|
|
154
|
+
}
|
|
155
|
+
export type MergeDialect<A extends string, B extends string> =
|
|
156
|
+
[ConcreteDialect<A>, ConcreteDialect<B>] extends [never, never] ? "standard"
|
|
157
|
+
: [ConcreteDialect<A>, ConcreteDialect<B>] extends [never, infer C extends string] ? C
|
|
158
|
+
: [ConcreteDialect<A>, ConcreteDialect<B>] extends [infer C extends string, never] ? C
|
|
159
|
+
: ConcreteDialect<A> extends ConcreteDialect<B>
|
|
160
|
+
? ConcreteDialect<B> extends ConcreteDialect<A>
|
|
161
|
+
? A
|
|
162
|
+
: DialectConflictError<A, B>
|
|
163
|
+
: DialectConflictError<A, B>
|
|
164
|
+
|
|
165
|
+
/** Collapses the portable standard tag out of a dialect union. */
|
|
166
|
+
export type NormalizeDialect<Dialect extends string> =
|
|
167
|
+
[Dialect] extends [never]
|
|
168
|
+
? never
|
|
169
|
+
: [Exclude<Dialect, "standard">] extends [never]
|
|
170
|
+
? "standard"
|
|
171
|
+
: IsDialectUnion<Exclude<Dialect, "standard">> extends true
|
|
172
|
+
? DialectConflictError<Exclude<Dialect, "standard">, Exclude<Dialect, "standard">>
|
|
173
|
+
: Exclude<Dialect, "standard">
|
|
146
174
|
/** Source dependency union carried by an expression. */
|
|
147
175
|
export type DependenciesOf<Value extends Expression.Any> = Expression.DependenciesOf<Value>
|
|
148
176
|
/** Aggregation kind carried by an expression. */
|
|
@@ -464,15 +492,17 @@ export type ExtractRequired<Selection> = Selection extends Expression.Any
|
|
|
464
492
|
}[keyof Selection]
|
|
465
493
|
: never
|
|
466
494
|
|
|
467
|
-
|
|
468
|
-
export type ExtractDialect<Selection> = Selection extends Expression.Any
|
|
495
|
+
type ExtractDialectRaw<Selection> = Selection extends Expression.Any
|
|
469
496
|
? DialectOf<Selection>
|
|
470
497
|
: Selection extends Record<string, any>
|
|
471
498
|
? {
|
|
472
|
-
[K in keyof Selection]:
|
|
499
|
+
[K in keyof Selection]: ExtractDialectRaw<Selection[K]>
|
|
473
500
|
}[keyof Selection]
|
|
474
501
|
: never
|
|
475
502
|
|
|
503
|
+
/** Walks a selection tree and extracts the effective dialects referenced by its leaves. */
|
|
504
|
+
export type ExtractDialect<Selection> = NormalizeDialect<Extract<ExtractDialectRaw<Selection>, string>>
|
|
505
|
+
|
|
476
506
|
/**
|
|
477
507
|
* Minimal table-like shape required by `from(...)` and joins.
|
|
478
508
|
*
|
|
@@ -1005,8 +1035,7 @@ export type UpdateInputOfTarget<Target extends MutationTargetInput> =
|
|
|
1005
1035
|
}>
|
|
1006
1036
|
: never
|
|
1007
1037
|
|
|
1008
|
-
|
|
1009
|
-
export type SourceDialectOf<Source extends SourceLike> =
|
|
1038
|
+
type SourceDialectOfRaw<Source extends SourceLike> =
|
|
1010
1039
|
Source extends TableLike<any, infer Dialect> ? Dialect :
|
|
1011
1040
|
Source extends { readonly kind: "derived"; readonly plan: infer PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any> } ? PlanDialectOf<PlanValue> :
|
|
1012
1041
|
Source extends { readonly kind: "cte"; readonly plan: infer PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any> } ? PlanDialectOf<PlanValue> :
|
|
@@ -1014,6 +1043,9 @@ export type SourceDialectOf<Source extends SourceLike> =
|
|
|
1014
1043
|
Source extends { readonly dialect: infer Dialect extends string } ? Dialect :
|
|
1015
1044
|
never
|
|
1016
1045
|
|
|
1046
|
+
/** Extracts the effective dialect from a source. */
|
|
1047
|
+
export type SourceDialectOf<Source extends SourceLike> = NormalizeDialect<SourceDialectOfRaw<Source>>
|
|
1048
|
+
|
|
1017
1049
|
/** Extracts the base table name from a source. */
|
|
1018
1050
|
export type SourceBaseNameOf<Source extends SourceLike> =
|
|
1019
1051
|
Source extends TableLike<any, any> ? Source[typeof Table.TypeId]["baseName"] :
|
|
@@ -1148,6 +1180,21 @@ type DerivedProjectionIssues<Selection> =
|
|
|
1148
1180
|
: | DerivedProjectionDuplicateAliases<Selection>
|
|
1149
1181
|
| DerivedProjectionAliasMismatches<Selection>
|
|
1150
1182
|
|
|
1183
|
+
export type SelectionProjectionDuplicateAliases<Selection> =
|
|
1184
|
+
IsBroadSelection<Selection> extends true
|
|
1185
|
+
? never
|
|
1186
|
+
: DuplicateProjectionAliases<SelectionProjectionEntries<Selection>>
|
|
1187
|
+
|
|
1188
|
+
export type SelectionProjectionAliasCollisionError<Selection> = Selection & {
|
|
1189
|
+
readonly __effect_qb_error__: "effect-qb: projection aliases must be unique"
|
|
1190
|
+
readonly __effect_qb_duplicate_projection_aliases__: SelectionProjectionDuplicateAliases<Selection>
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
export type SelectionProjectionAliasCollisionConstraint<Selection> =
|
|
1194
|
+
[SelectionProjectionDuplicateAliases<Selection>] extends [never]
|
|
1195
|
+
? unknown
|
|
1196
|
+
: SelectionProjectionAliasCollisionError<Selection>
|
|
1197
|
+
|
|
1151
1198
|
export type DerivedSourceProjectionCompatibilityError<
|
|
1152
1199
|
PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>
|
|
1153
1200
|
> = PlanValue & {
|
|
@@ -1254,7 +1301,7 @@ export type AvailableOfPlan<
|
|
|
1254
1301
|
/** Extracts the effective dialect carried by a query plan. */
|
|
1255
1302
|
export type PlanDialectOf<
|
|
1256
1303
|
PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>
|
|
1257
|
-
> = QueryPlanParts<PlanValue>["dialect"]
|
|
1304
|
+
> = NormalizeDialect<QueryPlanParts<PlanValue>["dialect"]>
|
|
1258
1305
|
/** Extracts the grouped-source phantom carried by a query plan. */
|
|
1259
1306
|
export type GroupedOfPlan<
|
|
1260
1307
|
PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any, any, any>
|
|
@@ -1465,7 +1512,7 @@ export type MergeNullabilityTuple<
|
|
|
1465
1512
|
/** Dialect union across a tuple of expressions. */
|
|
1466
1513
|
export type TupleDialect<
|
|
1467
1514
|
Values extends readonly Expression.Any[]
|
|
1468
|
-
> = Values[number] extends never ? never : DialectOf<Values[number]
|
|
1515
|
+
> = Values[number] extends never ? never : NormalizeDialect<DialectOf<Values[number]>>
|
|
1469
1516
|
|
|
1470
1517
|
/** Converts a union into an intersection. */
|
|
1471
1518
|
type UnionToIntersection<Union> = (
|
|
@@ -2124,7 +2171,7 @@ type DialectCompatibilityError<
|
|
|
2124
2171
|
EngineDialect extends string
|
|
2125
2172
|
> = PlanValue & {
|
|
2126
2173
|
readonly __effect_qb_error__: "effect-qb: plan dialect is not compatible with the target renderer or executor"
|
|
2127
|
-
readonly __effect_qb_plan_dialect__: PlanValue
|
|
2174
|
+
readonly __effect_qb_plan_dialect__: PlanDialectOf<PlanValue>
|
|
2128
2175
|
readonly __effect_qb_target_dialect__: EngineDialect
|
|
2129
2176
|
readonly __effect_qb_hint__: "Use the matching dialect module or renderer/executor"
|
|
2130
2177
|
}
|
|
@@ -2175,7 +2222,7 @@ type IsDialectCompatible<
|
|
|
2175
2222
|
EngineDialect extends string
|
|
2176
2223
|
> = [PlanDialect] extends [never]
|
|
2177
2224
|
? true
|
|
2178
|
-
: Exclude<PlanDialect, EngineDialect> extends never
|
|
2225
|
+
: Exclude<PlanDialect, EngineDialect | "standard"> extends never
|
|
2179
2226
|
? true
|
|
2180
2227
|
: false
|
|
2181
2228
|
|
|
@@ -2183,7 +2230,7 @@ type IsDialectCompatible<
|
|
|
2183
2230
|
export type DialectCompatiblePlan<
|
|
2184
2231
|
PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>,
|
|
2185
2232
|
EngineDialect extends string
|
|
2186
|
-
> = IsDialectCompatible<PlanValue
|
|
2233
|
+
> = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true
|
|
2187
2234
|
? CompletePlan<PlanValue>
|
|
2188
2235
|
: DialectCompatibilityError<PlanValue, EngineDialect>
|
|
2189
2236
|
|
|
@@ -2201,7 +2248,7 @@ type NestedPlanStatementError<
|
|
|
2201
2248
|
export type DialectCompatibleNestedPlan<
|
|
2202
2249
|
PlanValue extends QueryPlan<any, any, any, any, any, any, any, any, any, any>,
|
|
2203
2250
|
EngineDialect extends string
|
|
2204
|
-
> = IsDialectCompatible<PlanValue
|
|
2251
|
+
> = IsDialectCompatible<PlanDialectOf<PlanValue>, EngineDialect> extends true
|
|
2205
2252
|
? StatementOfPlan<PlanValue> extends SelectLikeStatement
|
|
2206
2253
|
? AggregationCompatiblePlan<PlanValue>
|
|
2207
2254
|
: NestedPlanStatementError<PlanValue>
|
|
@@ -2412,7 +2459,7 @@ export const makeExpression = <
|
|
|
2412
2459
|
state: {
|
|
2413
2460
|
readonly runtime: Runtime
|
|
2414
2461
|
readonly dbType: Db
|
|
2415
|
-
readonly runtimeSchema?: Schema.
|
|
2462
|
+
readonly runtimeSchema?: Schema.Top
|
|
2416
2463
|
readonly driverValueMapping?: Expression.DriverValueMapping
|
|
2417
2464
|
readonly nullability: Nullable
|
|
2418
2465
|
readonly dialect: Dialect
|
|
@@ -2427,7 +2474,7 @@ export const makeExpression = <
|
|
|
2427
2474
|
Object.defineProperty(expression, "pipe", {
|
|
2428
2475
|
configurable: true,
|
|
2429
2476
|
writable: true,
|
|
2430
|
-
value: function(this:
|
|
2477
|
+
value: function(this: Pipeable) {
|
|
2431
2478
|
return pipeArguments(expression, arguments)
|
|
2432
2479
|
}
|
|
2433
2480
|
})
|
|
@@ -2477,7 +2524,7 @@ export const makePlan = <
|
|
|
2477
2524
|
Object.defineProperty(plan, "pipe", {
|
|
2478
2525
|
configurable: true,
|
|
2479
2526
|
writable: true,
|
|
2480
|
-
value: function(this:
|
|
2527
|
+
value: function(this: Pipeable) {
|
|
2481
2528
|
return pipeArguments(plan, arguments)
|
|
2482
2529
|
}
|
|
2483
2530
|
})
|
|
@@ -2536,16 +2583,8 @@ export const extractRequiredRuntime = (selection: SelectionShape): readonly stri
|
|
|
2536
2583
|
|
|
2537
2584
|
/** Extracts the single top-level expression from a scalar subquery selection. */
|
|
2538
2585
|
export const extractSingleSelectedExpressionRuntime = (selection: SelectionShape): Expression.Any => {
|
|
2539
|
-
const
|
|
2540
|
-
|
|
2541
|
-
throw new Error("scalar subqueries must select exactly one top-level expression")
|
|
2542
|
-
}
|
|
2543
|
-
const record = selection as Record<string, unknown>
|
|
2544
|
-
const value = record[keys[0]!]
|
|
2545
|
-
if (value === null || typeof value !== "object" || !(Expression.TypeId in (value as object))) {
|
|
2546
|
-
throw new Error("scalar subqueries must select a scalar expression")
|
|
2547
|
-
}
|
|
2548
|
-
return value as unknown as Expression.Any
|
|
2586
|
+
const record = selection as Record<string, Expression.Any>
|
|
2587
|
+
return record[Object.keys(record)[0]!]!
|
|
2549
2588
|
}
|
|
2550
2589
|
|
|
2551
2590
|
/** Converts the plan's runtime `required` metadata into a mutable string list. */
|
package/src/internal/renderer.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import * as Query from "./query.js"
|
|
2
|
-
import
|
|
2
|
+
import * as Expression from "./scalar.js"
|
|
3
3
|
import { flattenSelection, type Projection, validateProjections } from "./projections.js"
|
|
4
|
-
import * as Plan from "./row-set.js"
|
|
5
4
|
|
|
6
5
|
/** Symbol used to attach rendered-query phantom row metadata. */
|
|
7
6
|
export const TypeId: unique symbol = Symbol.for("effect-qb/Renderer")
|
|
@@ -38,8 +37,7 @@ export type RowOf<Value extends RenderedQuery<any, any>> = Value[typeof TypeId][
|
|
|
38
37
|
*
|
|
39
38
|
* Renderers only accept complete, dialect-compatible plans. The returned
|
|
40
39
|
* `RenderedQuery` keeps the canonical `Query.ResultRow<...>` type attached for
|
|
41
|
-
* downstream executor layers
|
|
42
|
-
* matching runtime aggregate-shape validation.
|
|
40
|
+
* downstream executor layers.
|
|
43
41
|
*/
|
|
44
42
|
export interface Renderer<Dialect extends string = string> {
|
|
45
43
|
readonly dialect: Dialect
|
|
@@ -91,24 +89,38 @@ export function make<Dialect extends string>(
|
|
|
91
89
|
dialect: Dialect,
|
|
92
90
|
render: CustomRender<Dialect>
|
|
93
91
|
): Renderer<Dialect> {
|
|
92
|
+
return makeRenderer(dialect, render, true)
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Internal renderer factory for built-in renderers that derive projections from typed plans. */
|
|
96
|
+
export function makeTrusted<Dialect extends string>(
|
|
97
|
+
dialect: Dialect,
|
|
98
|
+
render: CustomRender<Dialect>
|
|
99
|
+
): Renderer<Dialect>
|
|
100
|
+
export function makeTrusted<Dialect extends string>(
|
|
101
|
+
dialect: Dialect,
|
|
102
|
+
render: CustomRender<Dialect>
|
|
103
|
+
): Renderer<Dialect> {
|
|
104
|
+
return makeRenderer(dialect, render, false)
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const makeRenderer = <Dialect extends string>(
|
|
108
|
+
dialect: Dialect,
|
|
109
|
+
render: CustomRender<Dialect>,
|
|
110
|
+
validate: boolean
|
|
111
|
+
): Renderer<Dialect> => {
|
|
94
112
|
if (typeof render !== "function") {
|
|
95
113
|
throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`)
|
|
96
114
|
}
|
|
97
115
|
return {
|
|
98
116
|
dialect,
|
|
99
117
|
render(plan) {
|
|
100
|
-
const required = Query.currentRequiredList(plan[Plan.TypeId].required)
|
|
101
|
-
if (required.length > 0) {
|
|
102
|
-
throw new Error(`query references sources that are not yet in scope: ${required.join(", ")}`)
|
|
103
|
-
}
|
|
104
|
-
const planDialect = plan[Plan.TypeId].dialect
|
|
105
|
-
if (planDialect !== dialect) {
|
|
106
|
-
throw new Error("effect-qb: plan dialect is not compatible with the target renderer or executor")
|
|
107
|
-
}
|
|
108
118
|
const rendered = render(plan)
|
|
109
119
|
const projections = rendered.projections ?? []
|
|
110
|
-
|
|
111
|
-
|
|
120
|
+
if (validate) {
|
|
121
|
+
validateProjections(projections)
|
|
122
|
+
validateProjectionPathsMatchSelection(plan as Query.Plan.Any, projections)
|
|
123
|
+
}
|
|
112
124
|
return {
|
|
113
125
|
sql: rendered.sql,
|
|
114
126
|
params: rendered.params ?? [],
|
|
@@ -9,7 +9,7 @@ export type DriverValueMappings = Expression.DriverValueMappings
|
|
|
9
9
|
export interface DriverValueContext {
|
|
10
10
|
readonly dialect?: string
|
|
11
11
|
readonly dbType?: Expression.DbType.Any
|
|
12
|
-
readonly runtimeSchema?: Schema.
|
|
12
|
+
readonly runtimeSchema?: Schema.Top
|
|
13
13
|
readonly driverValueMapping?: DriverValueMapping
|
|
14
14
|
readonly valueMappings?: DriverValueMappings
|
|
15
15
|
}
|
|
@@ -99,13 +99,13 @@ const isJsonDbType = (dbType: Expression.DbType.Any | undefined): boolean => {
|
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
const schemaAccepts = (
|
|
102
|
-
schema: Schema.
|
|
102
|
+
schema: Schema.Top | undefined,
|
|
103
103
|
value: unknown
|
|
104
104
|
): boolean =>
|
|
105
105
|
schema !== undefined && (Schema.is(schema) as (candidate: unknown) => boolean)(value)
|
|
106
106
|
|
|
107
107
|
const encodeWithSchema = (
|
|
108
|
-
schema: Schema.
|
|
108
|
+
schema: Schema.Top | undefined,
|
|
109
109
|
value: unknown
|
|
110
110
|
): { readonly value: unknown; readonly encoded: boolean } => {
|
|
111
111
|
if (schema === undefined) {
|
|
@@ -23,6 +23,13 @@ const isPlainRecord = (value: unknown): value is Record<string, unknown> => {
|
|
|
23
23
|
|
|
24
24
|
const pad = (value: number, width = 2): string => value.toString().padStart(width, "0")
|
|
25
25
|
|
|
26
|
+
const validDate = (value: Date): Date => {
|
|
27
|
+
if (Number.isNaN(value.getTime())) {
|
|
28
|
+
throw new Error("Expected a valid Date value")
|
|
29
|
+
}
|
|
30
|
+
return value
|
|
31
|
+
}
|
|
32
|
+
|
|
26
33
|
const formatLocalDate = (value: Date): string =>
|
|
27
34
|
`${pad(value.getUTCFullYear(), 4)}-${pad(value.getUTCMonth() + 1)}-${pad(value.getUTCDate())}`
|
|
28
35
|
|
|
@@ -125,7 +132,7 @@ const normalizeDecimalString = (value: unknown): string => {
|
|
|
125
132
|
|
|
126
133
|
const normalizeLocalDate = (value: unknown): string => {
|
|
127
134
|
if (value instanceof Date) {
|
|
128
|
-
return formatLocalDate(value)
|
|
135
|
+
return formatLocalDate(validDate(value))
|
|
129
136
|
}
|
|
130
137
|
const raw = expectString(value, "local date").trim()
|
|
131
138
|
if (isValidLocalDateString(raw)) {
|
|
@@ -143,7 +150,7 @@ const normalizeLocalDate = (value: unknown): string => {
|
|
|
143
150
|
|
|
144
151
|
const normalizeLocalTime = (value: unknown): string => {
|
|
145
152
|
if (value instanceof Date) {
|
|
146
|
-
return formatLocalTime(value)
|
|
153
|
+
return formatLocalTime(validDate(value))
|
|
147
154
|
}
|
|
148
155
|
const raw = expectString(value, "local time").trim()
|
|
149
156
|
if (isValidLocalTimeString(raw)) {
|
|
@@ -154,7 +161,7 @@ const normalizeLocalTime = (value: unknown): string => {
|
|
|
154
161
|
|
|
155
162
|
const normalizeOffsetTime = (value: unknown): string => {
|
|
156
163
|
if (value instanceof Date) {
|
|
157
|
-
return `${formatLocalTime(value)}Z`
|
|
164
|
+
return `${formatLocalTime(validDate(value))}Z`
|
|
158
165
|
}
|
|
159
166
|
const raw = expectString(value, "offset time").trim()
|
|
160
167
|
if (isValidOffsetTimeString(raw)) {
|
|
@@ -165,7 +172,7 @@ const normalizeOffsetTime = (value: unknown): string => {
|
|
|
165
172
|
|
|
166
173
|
const normalizeLocalDateTime = (value: unknown): string => {
|
|
167
174
|
if (value instanceof Date) {
|
|
168
|
-
return formatLocalDateTime(value)
|
|
175
|
+
return formatLocalDateTime(validDate(value))
|
|
169
176
|
}
|
|
170
177
|
const raw = expectString(value, "local datetime").trim()
|
|
171
178
|
const canonicalLocalDateTime = raw.replace(" ", "T")
|
|
@@ -184,7 +191,7 @@ const normalizeLocalDateTime = (value: unknown): string => {
|
|
|
184
191
|
|
|
185
192
|
const normalizeInstant = (value: unknown): string => {
|
|
186
193
|
if (value instanceof Date) {
|
|
187
|
-
return value.toISOString()
|
|
194
|
+
return validDate(value).toISOString()
|
|
188
195
|
}
|
|
189
196
|
const raw = expectString(value, "instant").trim()
|
|
190
197
|
if (!/[zZ]|[+-]\d{2}:\d{2}$/.test(raw)) {
|
|
@@ -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
|
}
|
|
@@ -143,7 +144,12 @@ export interface DriverValueMapping {
|
|
|
143
144
|
readonly jsonSelectSql?: (sql: string, dbType: DbType.Any) => string
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
export type DriverValueMappings = Readonly<Record<string, DriverValueMapping
|
|
147
|
+
export type DriverValueMappings = Readonly<Partial<Record<string, DriverValueMapping>>>
|
|
148
|
+
|
|
149
|
+
export type DriverValueMappingsFor<
|
|
150
|
+
Kind extends string,
|
|
151
|
+
Family extends string
|
|
152
|
+
> = Readonly<Partial<Record<Kind | Family | RuntimeTag, DriverValueMapping>>>
|
|
147
153
|
|
|
148
154
|
/** Canonical static metadata stored on an expression. */
|
|
149
155
|
export interface State<
|
|
@@ -156,7 +162,7 @@ export interface State<
|
|
|
156
162
|
> {
|
|
157
163
|
readonly runtime: Runtime
|
|
158
164
|
readonly dbType: Db
|
|
159
|
-
readonly runtimeSchema?: Schema.
|
|
165
|
+
readonly runtimeSchema?: Schema.Top
|
|
160
166
|
readonly driverValueMapping?: DriverValueMapping
|
|
161
167
|
readonly nullability: Nullable
|
|
162
168
|
readonly dialect: Dialect
|