effect-qb 0.17.0 → 4.0.0-beta.66

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +7 -0
  2. package/dist/mysql.js +207 -134
  3. package/dist/postgres/metadata.js +121 -52
  4. package/dist/postgres.js +210 -138
  5. package/dist/sqlite.js +207 -134
  6. package/package.json +2 -4
  7. package/src/internal/column-state.d.ts +3 -3
  8. package/src/internal/column-state.ts +3 -3
  9. package/src/internal/column.ts +8 -8
  10. package/src/internal/dialect.ts +1 -1
  11. package/src/internal/executor.ts +54 -35
  12. package/src/internal/query.d.ts +1 -1
  13. package/src/internal/query.ts +1 -1
  14. package/src/internal/runtime/driver-value-mapping.ts +3 -3
  15. package/src/internal/runtime/schema.ts +28 -38
  16. package/src/internal/runtime/value.ts +20 -23
  17. package/src/internal/scalar.d.ts +1 -1
  18. package/src/internal/scalar.ts +1 -1
  19. package/src/internal/schema-derivation.d.ts +12 -61
  20. package/src/internal/schema-derivation.ts +95 -43
  21. package/src/internal/table.d.ts +29 -22
  22. package/src/internal/table.ts +178 -29
  23. package/src/mysql/column.ts +6 -6
  24. package/src/mysql/executor.ts +4 -4
  25. package/src/mysql/function/temporal.ts +1 -1
  26. package/src/mysql/internal/dsl.ts +23 -17
  27. package/src/mysql/table.ts +28 -25
  28. package/src/postgres/column.ts +11 -11
  29. package/src/postgres/executor.ts +4 -4
  30. package/src/postgres/function/temporal.ts +1 -1
  31. package/src/postgres/internal/dsl.ts +23 -17
  32. package/src/postgres/schema-management.ts +1 -2
  33. package/src/postgres/table.ts +13 -21
  34. package/src/sqlite/column.ts +6 -6
  35. package/src/sqlite/executor.ts +4 -4
  36. package/src/sqlite/function/temporal.ts +1 -1
  37. package/src/sqlite/internal/dsl.ts +7 -6
  38. package/src/sqlite/table.ts +17 -25
@@ -70,7 +70,7 @@ export interface ColumnState<Select, Insert, Update, Db extends Expression.DbTyp
70
70
  export interface ColumnDefinition<Select, Insert, Update, Db extends Expression.DbType.Any, Nullable extends boolean, HasDefault extends boolean, Generated extends boolean, PrimaryKey extends boolean, Unique extends boolean, Ref, Dependencies extends Expression.BindingId = never> extends Pipeable, Expression.Scalar<Select, Db, Nullable extends true ? "maybe" : "never", Db["dialect"], "scalar", Dependencies> {
71
71
  readonly pipe: Pipeable["pipe"];
72
72
  readonly [ColumnTypeId]: ColumnState<Select, Insert, Update, Db, Nullable, HasDefault, Generated, PrimaryKey, Unique, Ref, Dependencies>;
73
- readonly schema: Schema.Schema<NonNullable<Select>, any, any>;
73
+ readonly schema: Schema.Schema<NonNullable<Select>>;
74
74
  readonly metadata: {
75
75
  readonly dbType: Db;
76
76
  readonly nullable: Nullable;
@@ -111,7 +111,7 @@ export type AnyColumnDefinition = ColumnDefinition<any, any, any, Expression.DbT
111
111
  /** Convenience alias for any bound column. */
112
112
  export type AnyBoundColumn = BoundColumn<any, any, any, Expression.DbType.Any, boolean, boolean, boolean, boolean, boolean, any, string, string, string>;
113
113
  /** Constructs a runtime column-definition object from schema and metadata. */
114
- export declare const makeColumnDefinition: <Select, Insert, Update, Db extends Expression.DbType.Any, Nullable extends boolean, HasDefault extends boolean, Generated extends boolean, PrimaryKey extends boolean, Unique extends boolean, Ref, Dependencies extends string = never>(schema: Schema.Schema<NonNullable<Select>, any, any>, metadata: {
114
+ export declare const makeColumnDefinition: <Select, Insert, Update, Db extends Expression.DbType.Any, Nullable extends boolean, HasDefault extends boolean, Generated extends boolean, PrimaryKey extends boolean, Unique extends boolean, Ref, Dependencies extends string = never>(schema: Schema.Schema<NonNullable<Select>>, metadata: {
115
115
  readonly dbType: Db;
116
116
  readonly nullable: Nullable;
117
117
  readonly hasDefault: HasDefault;
@@ -135,7 +135,7 @@ export declare const makeColumnDefinition: <Select, Insert, Update, Db extends E
135
135
  } | undefined;
136
136
  }) => ColumnDefinition<Select, Insert, Update, Db, Nullable, HasDefault, Generated, PrimaryKey, Unique, Ref, Dependencies>;
137
137
  export declare const remapColumnDefinition: <Select, Insert, Update, Db extends Expression.DbType.Any, Nullable extends boolean, HasDefault extends boolean, Generated extends boolean, PrimaryKey extends boolean, Unique extends boolean, Ref, Dependencies extends string = never>(column: ColumnDefinition<Select, Insert, Update, Db, Nullable, HasDefault, Generated, PrimaryKey, Unique, Ref, Dependencies>, options?: {
138
- readonly schema?: Schema.Schema.Any | undefined;
138
+ readonly schema?: Schema.Top | undefined;
139
139
  readonly metadata?: {
140
140
  readonly dbType: Db;
141
141
  readonly nullable: Nullable;
@@ -123,7 +123,7 @@ export interface ColumnDefinition<
123
123
  Ref,
124
124
  Dependencies
125
125
  >
126
- readonly schema: Schema.Schema<NonNullable<Select>, any, any>
126
+ readonly schema: Schema.Schema<NonNullable<Select>>
127
127
  readonly metadata: {
128
128
  readonly dbType: Db
129
129
  readonly nullable: Nullable
@@ -257,7 +257,7 @@ export const makeColumnDefinition = <
257
257
  Ref,
258
258
  Dependencies extends Expression.BindingId = never
259
259
  >(
260
- schema: Schema.Schema<NonNullable<Select>, any, any>,
260
+ schema: Schema.Schema<NonNullable<Select>>,
261
261
  metadata: ColumnDefinition<
262
262
  Select,
263
263
  Insert,
@@ -345,7 +345,7 @@ export const remapColumnDefinition = <
345
345
  Dependencies
346
346
  >,
347
347
  options: {
348
- readonly schema?: Schema.Schema.Any
348
+ readonly schema?: Schema.Top
349
349
  readonly metadata?: ColumnDefinition<
350
350
  Select,
351
351
  Insert,
@@ -225,21 +225,21 @@ type ForeignKeyOptions<Target extends AnyBoundColumn> = {
225
225
 
226
226
  type SchemaCompatibleColumn<
227
227
  Column extends AnyColumnDefinition,
228
- SchemaType extends Schema.Schema.Any
229
- > = [BaseSelectType<Column>] extends [Schema.Schema.Encoded<SchemaType>]
228
+ SchemaType extends Schema.Top
229
+ > = [BaseSelectType<Column>] extends [Schema.Codec.Encoded<SchemaType>]
230
230
  ? Column
231
231
  : never
232
232
 
233
233
  type ColumnSchemaOutput<
234
234
  Column extends AnyColumnDefinition,
235
- SchemaType extends Schema.Schema.Any
235
+ SchemaType extends Schema.Top
236
236
  > = IsNullable<Column> extends true
237
237
  ? Schema.Schema.Type<SchemaType> | null
238
238
  : Schema.Schema.Type<SchemaType>
239
239
 
240
240
  type ColumnWithSchema<
241
241
  Column extends AnyColumnDefinition,
242
- SchemaType extends Schema.Schema.Any
242
+ SchemaType extends Schema.Top
243
243
  > = ColumnDefinition<
244
244
  ColumnSchemaOutput<Column, SchemaType>,
245
245
  ColumnSchemaOutput<Column, SchemaType>,
@@ -376,7 +376,7 @@ const isColumnDefinitionValue = (value: unknown): value is AnyColumnDefinition =
376
376
  typeof value === "object" && value !== null && ColumnTypeId in value
377
377
 
378
378
  const primitive = <Type, Db extends Expression.DbType.Any>(
379
- schema: Schema.Schema<Type, any, any>,
379
+ schema: Schema.Schema<Type>,
380
380
  dbType: Db
381
381
  ): ColumnDefinition<Type, Type, Type, Db, false, false, false, false, false, undefined> =>
382
382
  makeColumnDefinition(schema as Schema.Schema<NonNullable<Type>>, {
@@ -401,7 +401,7 @@ type ColumnModule<
401
401
  JsonKind extends string
402
402
  > = {
403
403
  readonly custom: <
404
- SchemaType extends Schema.Schema.Any,
404
+ SchemaType extends Schema.Top,
405
405
  Db extends Expression.DbType.Any
406
406
  >(
407
407
  schema: SchemaType,
@@ -425,7 +425,7 @@ type ColumnModule<
425
425
  readonly boolean: () => ColumnDefinition<boolean, boolean, boolean, Expression.DbType.Base<Dialect, BooleanKind>, false, false, false, false, false, undefined>
426
426
  readonly date: () => ColumnDefinition<LocalDateString, LocalDateString, LocalDateString, Expression.DbType.Base<Dialect, DateKind>, false, false, false, false, false, undefined>
427
427
  readonly timestamp: () => ColumnDefinition<LocalDateTimeString, LocalDateTimeString, LocalDateTimeString, Expression.DbType.Base<Dialect, TimestampKind>, false, false, false, false, false, undefined>
428
- readonly json: <SchemaType extends Schema.Schema.Any>(
428
+ readonly json: <SchemaType extends Schema.Top>(
429
429
  schema: SchemaType
430
430
  ) => ColumnDefinition<
431
431
  Schema.Schema.Type<SchemaType>,
@@ -442,7 +442,7 @@ type ColumnModule<
442
442
  }
443
443
 
444
444
  /** Replaces a column's runtime schema while preserving its SQL type metadata. */
445
- export const schema = <SchemaType extends Schema.Schema.Any>(nextSchema: SchemaType) =>
445
+ export const schema = <SchemaType extends Schema.Top>(nextSchema: SchemaType) =>
446
446
  <Column extends AnyColumnDefinition>(
447
447
  column: SchemaCompatibleColumn<Column, SchemaType>
448
448
  ): ColumnWithSchema<Column, SchemaType> =>
@@ -23,7 +23,7 @@ export interface RenderState {
23
23
 
24
24
  export interface RenderValueContext {
25
25
  readonly dbType?: Expression.DbType.Any
26
- readonly runtimeSchema?: Schema.Schema.Any
26
+ readonly runtimeSchema?: Schema.Top
27
27
  readonly driverValueMapping?: Expression.DriverValueMapping
28
28
  }
29
29
 
@@ -1,9 +1,10 @@
1
1
  import * as Chunk from "effect/Chunk"
2
2
  import * as Effect from "effect/Effect"
3
+ import * as Exit from "effect/Exit"
3
4
  import * as Option from "effect/Option"
4
5
  import * as Schema from "effect/Schema"
5
- import * as SqlClient from "@effect/sql/SqlClient"
6
- import * as SqlError from "@effect/sql/SqlError"
6
+ import * as SqlClient from "effect/unstable/sql/SqlClient"
7
+ import * as SqlError from "effect/unstable/sql/SqlError"
7
8
  import * as Stream from "effect/Stream"
8
9
 
9
10
  import * as Expression from "./scalar.js"
@@ -44,6 +45,10 @@ export interface RowDecodeError {
44
45
  readonly normalized?: unknown
45
46
  readonly stage: "normalize" | "schema"
46
47
  readonly cause: unknown
48
+ readonly schemaError?: {
49
+ readonly message: string
50
+ readonly issue: unknown
51
+ }
47
52
  }
48
53
 
49
54
  /**
@@ -183,26 +188,35 @@ const makeRowDecodeError = (
183
188
  stage: RowDecodeError["stage"],
184
189
  cause: unknown,
185
190
  normalized?: unknown
186
- ): RowDecodeError => ({
187
- _tag: "RowDecodeError",
188
- message: stage === "normalize"
189
- ? `Failed to normalize projection '${projection.alias}'`
190
- : `Failed to decode projection '${projection.alias}' against its runtime schema`,
191
- dialect: rendered.dialect,
192
- query: {
193
- sql: rendered.sql,
194
- params: rendered.params
195
- },
196
- projection: {
197
- alias: projection.alias,
198
- path: projection.path
199
- },
200
- dbType: expression[Expression.TypeId].dbType,
201
- raw,
202
- normalized,
203
- stage,
204
- cause
205
- })
191
+ ): RowDecodeError => {
192
+ const schemaError = Schema.isSchemaError(cause)
193
+ ? {
194
+ message: cause.message,
195
+ issue: cause.issue
196
+ }
197
+ : undefined
198
+ return {
199
+ _tag: "RowDecodeError",
200
+ message: stage === "normalize"
201
+ ? `Failed to normalize projection '${projection.alias}'`
202
+ : `Failed to decode projection '${projection.alias}' against its runtime schema`,
203
+ dialect: rendered.dialect,
204
+ query: {
205
+ sql: rendered.sql,
206
+ params: rendered.params
207
+ },
208
+ projection: {
209
+ alias: projection.alias,
210
+ path: projection.path
211
+ },
212
+ dbType: expression[Expression.TypeId].dbType,
213
+ raw,
214
+ normalized,
215
+ stage,
216
+ cause,
217
+ ...(schemaError === undefined ? {} : { schemaError })
218
+ }
219
+ }
206
220
 
207
221
  const hasOptionalSourceDependency = (
208
222
  expression: Expression.Any,
@@ -249,7 +263,7 @@ const dbTypeAllowsTopLevelJsonNull = (
249
263
  }
250
264
 
251
265
  const schemaAcceptsNull = (
252
- schema: Schema.Schema.Any | undefined
266
+ schema: Schema.Top | undefined
253
267
  ): boolean =>
254
268
  schema !== undefined && (Schema.is(schema) as (value: unknown) => boolean)(null)
255
269
 
@@ -325,15 +339,20 @@ const decodeProjectionValue = (
325
339
  return normalized
326
340
  }
327
341
 
328
- if ((Schema.is(schema as Schema.Schema.Any) as (value: unknown) => boolean)(normalized)) {
342
+ if ((Schema.is(schema as Schema.Top) as (value: unknown) => boolean)(normalized)) {
329
343
  return normalized
330
344
  }
331
345
 
332
- try {
333
- return (Schema.decodeUnknownSync as any)(schema)(normalized)
334
- } catch (cause) {
335
- throw makeRowDecodeError(rendered, projection, expression, raw, "schema", cause, normalized)
346
+ const decoded = (Schema.decodeUnknownExit as any)(schema)(normalized)
347
+ if (Exit.isSuccess(decoded)) {
348
+ return decoded.value
336
349
  }
350
+
351
+ const cause = Option.match(Exit.findErrorOption(decoded), {
352
+ onNone: () => decoded.cause,
353
+ onSome: (schemaError) => schemaError
354
+ })
355
+ throw makeRowDecodeError(rendered, projection, expression, raw, "schema", cause, normalized)
337
356
  }
338
357
 
339
358
  export const makeRowDecoder = (
@@ -390,7 +409,7 @@ export const decodeChunk = (
390
409
  } = {}
391
410
  ): Chunk.Chunk<any> => {
392
411
  const decodeRow = makeRowDecoder(rendered, plan, options)
393
- return Chunk.unsafeFromArray(Chunk.toReadonlyArray(rows).map((row) => decodeRow(row)))
412
+ return Chunk.fromIterable(Chunk.toReadonlyArray(rows).map((row) => decodeRow(row)))
394
413
  }
395
414
 
396
415
  export const decodeRows = (
@@ -520,9 +539,9 @@ export const fromDriver = <
520
539
  },
521
540
  stream(plan: any) {
522
541
  const rendered = renderer.render(plan) as Renderer.RenderedQuery<any, Dialect>
523
- return Stream.mapChunks(
542
+ return Stream.mapArray(
524
543
  sqlDriver.stream(rendered),
525
- (rows) => Chunk.unsafeFromArray(remapRows<any>(rendered, Chunk.toReadonlyArray(rows)))
544
+ (rows) => remapRows<any>(rendered, rows) as never
526
545
  )
527
546
  }
528
547
  }
@@ -532,10 +551,10 @@ export const fromDriver = <
532
551
  export const streamFromSqlClient = <Dialect extends string>(
533
552
  query: Renderer.RenderedQuery<any, Dialect>
534
553
  ): Stream.Stream<FlatRow, SqlError.SqlError, SqlClient.SqlClient> =>
535
- Stream.unwrapScoped(
554
+ Stream.unwrap(
536
555
  Effect.flatMap(SqlClient.SqlClient, (sql) =>
537
556
  Effect.flatMap(
538
- Effect.serviceOption(SqlClient.TransactionConnection),
557
+ Effect.serviceOption(sql.transactionService),
539
558
  Option.match({
540
559
  onNone: () => sql.reserve,
541
560
  onSome: ([connection]) => Effect.succeed(connection)
@@ -556,7 +575,7 @@ export const fromSqlClient = <Dialect extends string>(
556
575
  stream: (query) => streamFromSqlClient(query)
557
576
  }))
558
577
 
559
- /** Runs an effect within the ambient `@effect/sql` transaction service. */
578
+ /** Runs an effect within the ambient `effect/unstable/sql` transaction service. */
560
579
  export const withTransaction = <A, E, R>(
561
580
  effect: Effect.Effect<A, E, R>
562
581
  ): Effect.Effect<A, E | SqlError.SqlError, R | SqlClient.SqlClient> =>
@@ -565,7 +584,7 @@ export const withTransaction = <A, E, R>(
565
584
  /**
566
585
  * Runs an effect in a nested transaction scope.
567
586
  *
568
- * When the ambient `@effect/sql` client is already inside a transaction, the
587
+ * When the ambient `effect/unstable/sql` client is already inside a transaction, the
569
588
  * underlying client implementation uses a savepoint.
570
589
  */
571
590
  export const withSavepoint = <A, E, R>(
@@ -743,7 +743,7 @@ export declare const mergeManyDependencies: <Values extends readonly Expression.
743
743
  export declare const makeExpression: <Runtime, Db extends Expression.DbType.Any, Nullable extends Expression.Nullability, Dialect extends string, Kind extends Expression.ScalarKind, Deps extends string = never, Ast extends ExpressionAst.Any = ExpressionAst.Any, GroupKey extends string = GroupingKeyOfAst<Ast>>(state: {
744
744
  readonly runtime: Runtime;
745
745
  readonly dbType: Db;
746
- readonly runtimeSchema?: Schema.Schema.Any | undefined;
746
+ readonly runtimeSchema?: Schema.Top | undefined;
747
747
  readonly nullability: Nullable;
748
748
  readonly dialect: Dialect;
749
749
  readonly kind?: Kind | undefined;
@@ -2412,7 +2412,7 @@ export const makeExpression = <
2412
2412
  state: {
2413
2413
  readonly runtime: Runtime
2414
2414
  readonly dbType: Db
2415
- readonly runtimeSchema?: Schema.Schema.Any
2415
+ readonly runtimeSchema?: Schema.Top
2416
2416
  readonly driverValueMapping?: Expression.DriverValueMapping
2417
2417
  readonly nullability: Nullable
2418
2418
  readonly dialect: Dialect
@@ -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.Schema.Any
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.Schema.Any | undefined,
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.Schema.Any | undefined,
108
+ schema: Schema.Top | undefined,
109
109
  value: unknown
110
110
  ): { readonly value: unknown; readonly encoded: boolean } => {
111
111
  if (schema === undefined) {
@@ -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.Schema<any, any, any>
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.pipe(Schema.finite())
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.Uint8ArrayFromSelf
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.make(asts)
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.f(), key)
140
- case "TypeLiteral": {
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 === "StringKeyword")
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.f(), index)
171
- case "TupleType": {
159
+ return numberAstOf(ast.thunk(), index)
160
+ case "Arrays": {
172
161
  const element = ast.elements[index]
173
162
  if (element !== undefined) {
174
- return element.type
163
+ return element
175
164
  }
176
165
  if (ast.rest.length === 0) {
177
166
  return undefined
178
167
  }
179
- return unionAst(ast.rest.map((entry) => entry.type))
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
- let current: SchemaAST.AST = SchemaAST.typeAST(schema.ast)
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(...resolved)
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 "StringKeyword":
246
- case "NumberKeyword":
247
- case "BooleanKeyword":
248
- case "TupleType":
249
- case "TypeLiteral":
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 === null ||
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.f())
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.typeAST(schema.ast)
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(...values.map((value) => expressionRuntimeSchema(value, context) ?? JsonValueSchema))
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.pattern(pattern),
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.pattern(localDatePattern),
104
- Schema.filter(isValidLocalDateString),
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.pattern(localTimePattern),
110
- Schema.filter(isValidLocalTimeString),
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.pattern(offsetTimePattern),
116
- Schema.filter(isValidOffsetTimeString),
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.pattern(localDateTimePattern),
122
- Schema.filter(isValidLocalDateTimeString),
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.pattern(instantPattern),
128
- Schema.filter(isValidInstantString),
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.filter(isCanonicalBigIntString),
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.filter(isCanonicalDecimalString),
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.pipe(Schema.finite()),
192
+ Schema.Number.check(Schema.isFinite()),
193
193
  Schema.Boolean,
194
194
  Schema.Null,
195
195
  Schema.Array(JsonValueSchema),
196
- Schema.Record({
197
- key: Schema.String,
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.pipe(Schema.finite()),
202
+ Schema.Number.check(Schema.isFinite()),
206
203
  Schema.Boolean,
207
204
  Schema.Null
208
- )
205
+ ])
@@ -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.Schema.Any;
76
+ readonly runtimeSchema?: Schema.Top;
77
77
  readonly nullability: Nullable;
78
78
  readonly dialect: Dialect;
79
79
  readonly kind: Kind;
@@ -156,7 +156,7 @@ export interface State<
156
156
  > {
157
157
  readonly runtime: Runtime
158
158
  readonly dbType: Db
159
- readonly runtimeSchema?: Schema.Schema.Any
159
+ readonly runtimeSchema?: Schema.Top
160
160
  readonly driverValueMapping?: DriverValueMapping
161
161
  readonly nullability: Nullable
162
162
  readonly dialect: Dialect