effect-qb 0.14.0 → 0.16.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.
Files changed (146) hide show
  1. package/dist/mysql.js +61555 -4252
  2. package/dist/postgres/metadata.js +728 -104
  3. package/dist/postgres.js +6906 -4023
  4. package/package.json +15 -2
  5. package/src/internal/aggregation-validation.ts +3 -3
  6. package/src/internal/case-analysis.d.ts +18 -0
  7. package/src/internal/case-analysis.ts +4 -4
  8. package/src/internal/coercion/analysis.d.ts +7 -0
  9. package/src/internal/{coercion-analysis.ts → coercion/analysis.ts} +3 -3
  10. package/src/internal/coercion/errors.d.ts +17 -0
  11. package/src/internal/{coercion-errors.ts → coercion/errors.ts} +1 -1
  12. package/src/internal/coercion/kind.d.ts +4 -0
  13. package/src/internal/{coercion-kind.ts → coercion/kind.ts} +2 -2
  14. package/src/internal/{coercion-normalize.ts → coercion/normalize.ts} +1 -1
  15. package/src/internal/coercion/rules.d.ts +6 -0
  16. package/src/internal/{coercion-rules.ts → coercion/rules.ts} +2 -2
  17. package/src/internal/column-state.d.ts +190 -0
  18. package/src/internal/column-state.ts +43 -47
  19. package/src/internal/column.ts +43 -305
  20. package/src/internal/datatypes/define.d.ts +17 -0
  21. package/src/internal/datatypes/define.ts +18 -4
  22. package/src/internal/datatypes/lookup.d.ts +44 -0
  23. package/src/internal/datatypes/lookup.ts +61 -152
  24. package/src/internal/datatypes/shape.d.ts +16 -0
  25. package/src/internal/datatypes/shape.ts +1 -1
  26. package/src/internal/derived-table.d.ts +4 -0
  27. package/src/internal/derived-table.ts +21 -16
  28. package/src/internal/dialect.ts +12 -1
  29. package/src/internal/dsl-mutation-runtime.ts +378 -0
  30. package/src/internal/dsl-plan-runtime.ts +387 -0
  31. package/src/internal/dsl-query-runtime.ts +160 -0
  32. package/src/internal/dsl-transaction-ddl-runtime.ts +263 -0
  33. package/src/internal/executor.ts +146 -34
  34. package/src/internal/expression-ast.ts +15 -5
  35. package/src/internal/grouping-key.d.ts +3 -0
  36. package/src/internal/grouping-key.ts +1 -1
  37. package/src/internal/implication-runtime.d.ts +15 -0
  38. package/src/internal/implication-runtime.ts +4 -4
  39. package/src/internal/json/ast.d.ts +30 -0
  40. package/src/internal/json/ast.ts +1 -1
  41. package/src/internal/json/errors.d.ts +8 -0
  42. package/src/internal/json/path.d.ts +75 -0
  43. package/src/internal/json/path.ts +1 -1
  44. package/src/internal/json/types.d.ts +62 -0
  45. package/src/internal/predicate/analysis.d.ts +20 -0
  46. package/src/internal/predicate/analysis.ts +183 -0
  47. package/src/internal/predicate/atom.d.ts +28 -0
  48. package/src/internal/{predicate-atom.ts → predicate/atom.ts} +7 -0
  49. package/src/internal/{predicate-branches.ts → predicate/branches.ts} +2 -2
  50. package/src/internal/predicate/context.d.ts +67 -0
  51. package/src/internal/{predicate-context.ts → predicate/context.ts} +163 -20
  52. package/src/internal/predicate/formula.d.ts +35 -0
  53. package/src/internal/{predicate-formula.ts → predicate/formula.ts} +1 -1
  54. package/src/internal/predicate/key.d.ts +11 -0
  55. package/src/internal/predicate/key.ts +73 -0
  56. package/src/internal/{predicate-nnf.ts → predicate/nnf.ts} +2 -2
  57. package/src/internal/predicate/normalize.d.ts +53 -0
  58. package/src/internal/{predicate-normalize.ts → predicate/normalize.ts} +130 -49
  59. package/src/internal/predicate/runtime.d.ts +31 -0
  60. package/src/internal/{predicate-runtime.ts → predicate/runtime.ts} +127 -17
  61. package/src/internal/projection-alias.d.ts +13 -0
  62. package/src/internal/projections.d.ts +31 -0
  63. package/src/internal/projections.ts +1 -1
  64. package/src/internal/query-ast.d.ts +217 -0
  65. package/src/internal/query-ast.ts +1 -1
  66. package/src/internal/query-requirements.d.ts +20 -0
  67. package/src/internal/query.d.ts +775 -0
  68. package/src/internal/query.ts +683 -369
  69. package/src/internal/renderer.ts +11 -21
  70. package/src/internal/row-set.d.ts +53 -0
  71. package/src/internal/{plan.ts → row-set.ts} +11 -9
  72. package/src/internal/runtime/driver-value-mapping.ts +186 -0
  73. package/src/internal/{runtime-normalize.ts → runtime/normalize.ts} +9 -31
  74. package/src/internal/{runtime-schema.ts → runtime/schema.ts} +13 -38
  75. package/src/internal/runtime/value.d.ts +22 -0
  76. package/src/internal/{runtime-value.ts → runtime/value.ts} +2 -2
  77. package/src/internal/scalar.d.ts +107 -0
  78. package/src/internal/scalar.ts +202 -0
  79. package/src/internal/schema-derivation.d.ts +105 -0
  80. package/src/internal/schema-expression.d.ts +18 -0
  81. package/src/internal/schema-expression.ts +38 -7
  82. package/src/internal/table-options.d.ts +94 -0
  83. package/src/internal/table-options.ts +8 -2
  84. package/src/internal/table.d.ts +173 -0
  85. package/src/internal/table.ts +32 -14
  86. package/src/mysql/column.ts +95 -18
  87. package/src/mysql/datatypes/index.ts +47 -7
  88. package/src/mysql/errors/generated.ts +57336 -0
  89. package/src/mysql/errors/index.ts +1 -0
  90. package/src/mysql/errors/normalize.ts +55 -53
  91. package/src/mysql/errors/types.ts +74 -0
  92. package/src/mysql/executor.ts +88 -11
  93. package/src/mysql/function/aggregate.ts +1 -5
  94. package/src/mysql/function/core.ts +1 -4
  95. package/src/mysql/function/index.ts +0 -1
  96. package/src/mysql/function/string.ts +1 -5
  97. package/src/mysql/function/temporal.ts +12 -15
  98. package/src/mysql/function/window.ts +1 -6
  99. package/src/{internal/mysql-dialect.ts → mysql/internal/dialect.ts} +12 -6
  100. package/src/{internal/mysql-query.ts → mysql/internal/dsl.ts} +1299 -2143
  101. package/src/mysql/internal/renderer.ts +46 -0
  102. package/src/mysql/internal/sql-expression-renderer.ts +1501 -0
  103. package/src/mysql/json.ts +2 -0
  104. package/src/mysql/query.ts +111 -91
  105. package/src/mysql/renderer.ts +8 -3
  106. package/src/mysql/table.ts +1 -1
  107. package/src/mysql.ts +6 -4
  108. package/src/postgres/cast.ts +30 -16
  109. package/src/postgres/column.ts +179 -46
  110. package/src/postgres/datatypes/index.d.ts +515 -0
  111. package/src/postgres/datatypes/index.ts +22 -13
  112. package/src/postgres/datatypes/spec.d.ts +412 -0
  113. package/src/postgres/errors/generated.ts +2636 -0
  114. package/src/postgres/errors/index.ts +1 -0
  115. package/src/postgres/errors/normalize.ts +47 -62
  116. package/src/postgres/errors/types.ts +92 -34
  117. package/src/postgres/executor.ts +54 -7
  118. package/src/postgres/function/aggregate.ts +1 -5
  119. package/src/postgres/function/core.ts +12 -6
  120. package/src/postgres/function/index.ts +0 -1
  121. package/src/postgres/function/string.ts +1 -5
  122. package/src/postgres/function/temporal.ts +12 -15
  123. package/src/postgres/function/window.ts +1 -6
  124. package/src/{internal/postgres-dialect.ts → postgres/internal/dialect.ts} +12 -6
  125. package/src/{internal/postgres-query.ts → postgres/internal/dsl.ts} +1356 -2133
  126. package/src/{internal/postgres-renderer.ts → postgres/internal/renderer.ts} +17 -8
  127. package/src/postgres/internal/schema-ddl.ts +108 -0
  128. package/src/{internal/postgres-schema-model.ts → postgres/internal/schema-model.ts} +12 -6
  129. package/src/{internal → postgres/internal}/sql-expression-renderer.ts +79 -25
  130. package/src/postgres/{function/json.ts → json.ts} +77 -85
  131. package/src/postgres/metadata.ts +2 -2
  132. package/src/postgres/query.ts +113 -89
  133. package/src/postgres/renderer.ts +8 -13
  134. package/src/postgres/schema-expression.ts +2 -1
  135. package/src/postgres/schema-management.ts +1 -1
  136. package/src/postgres/table.ts +12 -4
  137. package/src/postgres/type.ts +33 -2
  138. package/src/postgres.ts +6 -4
  139. package/src/internal/expression.ts +0 -327
  140. package/src/internal/mysql-renderer.ts +0 -37
  141. package/src/internal/predicate-analysis.ts +0 -81
  142. package/src/internal/predicate-key.ts +0 -28
  143. package/src/internal/schema-ddl.ts +0 -55
  144. package/src/mysql/function/json.ts +0 -4
  145. package/src/mysql/private/query.ts +0 -1
  146. package/src/postgres/private/query.ts +0 -1
@@ -1,6 +1,6 @@
1
1
  import * as Query from "./query.js"
2
+ import type * as Expression from "./scalar.js"
2
3
  import { type Projection, validateProjections } from "./projections.js"
3
- import { renderPostgresPlan } from "./postgres-renderer.js"
4
4
 
5
5
  /** Symbol used to attach rendered-query phantom row metadata. */
6
6
  export const TypeId: unique symbol = Symbol.for("effect-qb/Renderer")
@@ -22,6 +22,7 @@ export interface RenderedQuery<Row, Dialect extends string = string> {
22
22
  readonly params: readonly unknown[]
23
23
  readonly dialect: Dialect
24
24
  readonly projections: readonly Projection[]
25
+ readonly valueMappings?: Expression.DriverValueMappings
25
26
  readonly [TypeId]: {
26
27
  readonly row: Row
27
28
  readonly dialect: Dialect
@@ -41,53 +42,45 @@ export type RowOf<Value extends RenderedQuery<any, any>> = Value[typeof TypeId][
41
42
  */
42
43
  export interface Renderer<Dialect extends string = string> {
43
44
  readonly dialect: Dialect
44
- render<PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
45
+ render<PlanValue extends Query.Plan.Any>(
45
46
  plan: Query.DialectCompatiblePlan<PlanValue, Dialect>
46
47
  ): RenderedQuery<any, Dialect>
47
48
  }
48
49
 
49
- type CustomRender<Dialect extends string> = <PlanValue extends Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>>(
50
+ type CustomRender<Dialect extends string> = <PlanValue extends Query.Plan.Any>(
50
51
  plan: Query.DialectCompatiblePlan<PlanValue, Dialect>
51
52
  ) => {
52
53
  readonly sql: string
53
54
  readonly params?: readonly unknown[]
54
55
  readonly projections?: readonly Projection[]
56
+ readonly valueMappings?: Expression.DriverValueMappings
55
57
  }
56
58
 
57
59
  /**
58
- * Constructs a renderer from a dialect and optional implementation callback.
59
- *
60
- * When no callback is provided, the library supplies a built-in renderer for
61
- * `"postgres"` that consumes the query AST directly and produces SQL text plus
62
- * parameter values.
60
+ * Constructs a renderer from a dialect and implementation callback.
63
61
  */
64
- export function make(dialect: "postgres"): Renderer<"postgres">
65
62
  export function make<Dialect extends string>(
66
63
  dialect: Dialect,
67
64
  render: CustomRender<Dialect>
68
65
  ): Renderer<Dialect>
69
66
  export function make<Dialect extends string>(
70
67
  dialect: Dialect,
71
- render?: CustomRender<Dialect>
68
+ render: CustomRender<Dialect>
72
69
  ): Renderer<Dialect> {
73
- const implementation = render ?? ((dialect === "postgres"
74
- ? renderPostgresPlan
75
- : undefined) as CustomRender<Dialect> | undefined)
76
-
77
- if (!implementation) {
78
- throw new Error(`No built-in renderer for dialect: ${dialect}`)
70
+ if (typeof render !== "function") {
71
+ throw new Error(`Renderer.make requires an explicit render implementation for dialect: ${dialect}`)
79
72
  }
80
-
81
73
  return {
82
74
  dialect,
83
75
  render(plan) {
84
- const rendered = implementation(plan)
76
+ const rendered = render(plan)
85
77
  const projections = rendered.projections ?? []
86
78
  validateProjections(projections)
87
79
  return {
88
80
  sql: rendered.sql,
89
81
  params: rendered.params ?? [],
90
82
  projections,
83
+ valueMappings: rendered.valueMappings,
91
84
  dialect,
92
85
  [TypeId]: {
93
86
  row: undefined as any,
@@ -97,6 +90,3 @@ export function make<Dialect extends string>(
97
90
  }
98
91
  } as Renderer<Dialect>
99
92
  }
100
-
101
- /** Built-in Postgres renderer backed by the current query AST. */
102
- export const postgres = make("postgres")
@@ -0,0 +1,53 @@
1
+ import type { Pipeable } from "effect/Pipeable";
2
+ import type { PredicateFormula } from "./predicate/formula.js";
3
+ /** Symbol used to attach logical-plan metadata to runtime values. */
4
+ export declare const TypeId: unique symbol;
5
+ export type TypeId = typeof TypeId;
6
+ /**
7
+ * Source availability mode within a query scope.
8
+ *
9
+ * `required` means the source is guaranteed to produce a row at this point in
10
+ * the plan. `optional` means the source may be absent, such as the nullable
11
+ * side of a left join.
12
+ */
13
+ export type SourceMode = "required" | "optional";
14
+ /** Source made available to a plan. */
15
+ export interface Source<Name extends string = string, Mode extends SourceMode = SourceMode, PresentFormula extends PredicateFormula = PredicateFormula, PresenceWitness extends string = never> {
16
+ readonly name: Name;
17
+ readonly mode: Mode;
18
+ readonly baseName?: string;
19
+ readonly _presentFormula?: PresentFormula;
20
+ readonly _presenceWitnesses?: readonly PresenceWitness[];
21
+ }
22
+ export type AnySource = Source<string, SourceMode, PredicateFormula, string>;
23
+ /**
24
+ * Canonical static metadata stored on a plan.
25
+ *
26
+ * `required` tracks sources that the selection references but which are not yet
27
+ * in scope. `available` tracks sources already in scope for subsequent query
28
+ * operations.
29
+ */
30
+ export interface State<Columns, Required, Available extends Record<string, AnySource>, Dialect extends string> {
31
+ readonly selection: Columns;
32
+ readonly required: Required;
33
+ readonly available: Available;
34
+ readonly dialect: Dialect;
35
+ }
36
+ /**
37
+ * A composable logical row set.
38
+ *
39
+ * Tables implement this interface as already-complete plans. Future query
40
+ * builders such as `select()` and `from()` should produce and transform values
41
+ * with this same structure.
42
+ */
43
+ export interface RowSet<Columns, Required = never, Available extends Record<string, AnySource> = {}, Dialect extends string = never> extends Pipeable {
44
+ readonly [TypeId]: State<Columns, Required, Available, Dialect>;
45
+ }
46
+ /** Convenience alias for any plan-like value. */
47
+ export type Any = RowSet<any, any, Record<string, AnySource>, string>;
48
+ /** Extracts a row set's columns shape. */
49
+ export type ColumnsOf<Value extends Any> = Value[typeof TypeId]["selection"];
50
+ /** Extracts a plan's selection shape. */
51
+ export type SelectionOf<Value extends Any> = ColumnsOf<Value>;
52
+ /** Extracts a plan's effective dialect. */
53
+ export type DialectOf<Value extends Any> = Value[typeof TypeId]["dialect"];
@@ -1,5 +1,5 @@
1
1
  import type { Pipeable } from "effect/Pipeable"
2
- import type { PredicateFormula } from "./predicate-formula.js"
2
+ import type { PredicateFormula } from "./predicate/formula.js"
3
3
 
4
4
  /** Symbol used to attach logical-plan metadata to runtime values. */
5
5
  export const TypeId: unique symbol = Symbol.for("effect-qb/Plan")
@@ -39,36 +39,38 @@ export type AnySource = Source<string, SourceMode, PredicateFormula, string>
39
39
  * operations.
40
40
  */
41
41
  export interface State<
42
- Selection,
42
+ Columns,
43
43
  Required,
44
44
  Available extends Record<string, AnySource>,
45
45
  Dialect extends string
46
46
  > {
47
- readonly selection: Selection
47
+ readonly selection: Columns
48
48
  readonly required: Required
49
49
  readonly available: Available
50
50
  readonly dialect: Dialect
51
51
  }
52
52
 
53
53
  /**
54
- * A composable logical query plan.
54
+ * A composable logical row set.
55
55
  *
56
56
  * Tables implement this interface as already-complete plans. Future query
57
57
  * builders such as `select()` and `from()` should produce and transform values
58
58
  * with this same structure.
59
59
  */
60
- export interface Plan<
61
- Selection,
60
+ export interface RowSet<
61
+ Columns,
62
62
  Required = never,
63
63
  Available extends Record<string, AnySource> = {},
64
64
  Dialect extends string = never
65
65
  > extends Pipeable {
66
- readonly [TypeId]: State<Selection, Required, Available, Dialect>
66
+ readonly [TypeId]: State<Columns, Required, Available, Dialect>
67
67
  }
68
68
 
69
69
  /** Convenience alias for any plan-like value. */
70
- export type Any = Plan<any, any, Record<string, AnySource>, string>
70
+ export type Any = RowSet<any, any, Record<string, AnySource>, string>
71
+ /** Extracts a row set's columns shape. */
72
+ export type ColumnsOf<Value extends Any> = Value[typeof TypeId]["selection"]
71
73
  /** Extracts a plan's selection shape. */
72
- export type SelectionOf<Value extends Any> = Value[typeof TypeId]["selection"]
74
+ export type SelectionOf<Value extends Any> = ColumnsOf<Value>
73
75
  /** Extracts a plan's effective dialect. */
74
76
  export type DialectOf<Value extends Any> = Value[typeof TypeId]["dialect"]
@@ -0,0 +1,186 @@
1
+ import * as Schema from "effect/Schema"
2
+
3
+ import type * as Expression from "../scalar.js"
4
+ import { normalizeDbValue } from "./normalize.js"
5
+
6
+ export type DriverValueMapping = Expression.DriverValueMapping
7
+ export type DriverValueMappings = Expression.DriverValueMappings
8
+
9
+ export interface DriverValueContext {
10
+ readonly dialect?: string
11
+ readonly dbType?: Expression.DbType.Any
12
+ readonly runtimeSchema?: Schema.Schema.Any
13
+ readonly driverValueMapping?: DriverValueMapping
14
+ readonly valueMappings?: DriverValueMappings
15
+ }
16
+
17
+ type MappingKey =
18
+ | "fromDriver"
19
+ | "toDriver"
20
+ | "selectSql"
21
+ | "jsonSelectSql"
22
+
23
+ const runtimeTagOfDbType = (
24
+ dbType: Expression.DbType.Any | undefined
25
+ ): string | undefined => {
26
+ if (dbType === undefined) {
27
+ return undefined
28
+ }
29
+ if ("base" in dbType) {
30
+ return runtimeTagOfDbType(dbType.base)
31
+ }
32
+ if ("element" in dbType) {
33
+ return "array"
34
+ }
35
+ if ("fields" in dbType) {
36
+ return "record"
37
+ }
38
+ if ("variant" in dbType && dbType.variant === "json") {
39
+ return "json"
40
+ }
41
+ if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
42
+ return "string"
43
+ }
44
+ return dbType.runtime
45
+ }
46
+
47
+ const familyOfDbType = (
48
+ dbType: Expression.DbType.Any | undefined
49
+ ): string | undefined => {
50
+ if (dbType === undefined) {
51
+ return undefined
52
+ }
53
+ if ("base" in dbType) {
54
+ return familyOfDbType(dbType.base)
55
+ }
56
+ return dbType.family
57
+ }
58
+
59
+ const mappingCandidates = (
60
+ context: DriverValueContext
61
+ ): readonly (DriverValueMapping | undefined)[] => {
62
+ const dbType = context.dbType
63
+ const runtimeTag = runtimeTagOfDbType(dbType)
64
+ const family = familyOfDbType(dbType)
65
+ return [
66
+ context.driverValueMapping,
67
+ dbType?.driverValueMapping,
68
+ dbType === undefined ? undefined : context.valueMappings?.[dbType.kind],
69
+ family === undefined ? undefined : context.valueMappings?.[family],
70
+ runtimeTag === undefined ? undefined : context.valueMappings?.[runtimeTag]
71
+ ]
72
+ }
73
+
74
+ const findMapping = <Key extends MappingKey>(
75
+ context: DriverValueContext,
76
+ key: Key
77
+ ): NonNullable<DriverValueMapping[Key]> | undefined => {
78
+ for (const candidate of mappingCandidates(context)) {
79
+ const value = candidate?.[key]
80
+ if (value !== undefined) {
81
+ return value as NonNullable<DriverValueMapping[Key]>
82
+ }
83
+ }
84
+ return undefined
85
+ }
86
+
87
+ const encodeWithSchema = (
88
+ schema: Schema.Schema.Any | undefined,
89
+ value: unknown
90
+ ): { readonly value: unknown; readonly encoded: boolean } => {
91
+ if (schema === undefined) {
92
+ return { value, encoded: false }
93
+ }
94
+ if (!(Schema.is(schema) as (value: unknown) => boolean)(value)) {
95
+ return { value, encoded: false }
96
+ }
97
+ return {
98
+ value: (Schema.encodeUnknownSync as any)(schema)(value),
99
+ encoded: true
100
+ }
101
+ }
102
+
103
+ export const toDriverValue = (
104
+ value: unknown,
105
+ context: DriverValueContext
106
+ ): unknown => {
107
+ if (value === null) {
108
+ return null
109
+ }
110
+ const dbType = context.dbType
111
+ const encoded = encodeWithSchema(context.runtimeSchema, value)
112
+ let current = encoded.value
113
+ const custom = findMapping(context, "toDriver")
114
+ if (custom !== undefined && dbType !== undefined) {
115
+ return custom(current, dbType)
116
+ }
117
+ return dbType === undefined || !encoded.encoded
118
+ ? current
119
+ : normalizeDbValue(dbType, current)
120
+ }
121
+
122
+ export const fromDriverValue = (
123
+ value: unknown,
124
+ context: DriverValueContext
125
+ ): unknown => {
126
+ if (value === null) {
127
+ return null
128
+ }
129
+ const dbType = context.dbType
130
+ const custom = findMapping(context, "fromDriver")
131
+ if (custom !== undefined && dbType !== undefined) {
132
+ return custom(value, dbType)
133
+ }
134
+ return dbType === undefined
135
+ ? value
136
+ : normalizeDbValue(dbType, value)
137
+ }
138
+
139
+ const textCast = (sql: string): string => `(${sql})::text`
140
+
141
+ const postgresJsonSql = (
142
+ sql: string,
143
+ dbType: Expression.DbType.Any
144
+ ): string => {
145
+ const runtimeTag = runtimeTagOfDbType(dbType)
146
+ switch (runtimeTag) {
147
+ case "bigintString":
148
+ case "decimalString":
149
+ case "localDate":
150
+ case "localTime":
151
+ case "offsetTime":
152
+ case "localDateTime":
153
+ case "instant":
154
+ case "year":
155
+ return textCast(sql)
156
+ case "bytes":
157
+ return `encode(${sql}, 'base64')`
158
+ default:
159
+ return sql
160
+ }
161
+ }
162
+
163
+ export const renderSelectSql = (
164
+ sql: string,
165
+ context: DriverValueContext
166
+ ): string => {
167
+ const dbType = context.dbType
168
+ const custom = findMapping(context, "selectSql")
169
+ return custom !== undefined && dbType !== undefined
170
+ ? custom(sql, dbType)
171
+ : sql
172
+ }
173
+
174
+ export const renderJsonSelectSql = (
175
+ sql: string,
176
+ context: DriverValueContext
177
+ ): string => {
178
+ const dbType = context.dbType
179
+ const custom = findMapping(context, "jsonSelectSql")
180
+ if (custom !== undefined && dbType !== undefined) {
181
+ return custom(sql, dbType)
182
+ }
183
+ return context.dialect === "postgres" && dbType !== undefined
184
+ ? postgresJsonSql(sql, dbType)
185
+ : sql
186
+ }
@@ -1,22 +1,5 @@
1
- import type * as Expression from "./expression.js"
2
- import { mysqlDatatypeKinds } from "../mysql/datatypes/spec.js"
3
- import { postgresDatatypeKinds } from "../postgres/datatypes/spec.js"
4
- import type { RuntimeTag } from "./datatypes/shape.js"
5
-
6
- const stripParameterizedKind = (kind: string): string => {
7
- const openParen = kind.indexOf("(")
8
- return openParen === -1 ? kind : kind.slice(0, openParen)
9
- }
10
-
11
- const stripArrayKind = (kind: string): string => {
12
- let current = kind
13
- while (current.endsWith("[]")) {
14
- current = current.slice(0, -2)
15
- }
16
- return current
17
- }
18
-
19
- const baseKind = (kind: string): string => stripArrayKind(stripParameterizedKind(kind))
1
+ import type * as Expression from "../scalar.js"
2
+ import type { RuntimeTag } from "../datatypes/shape.js"
20
3
 
21
4
  const isRecord = (value: unknown): value is Record<string, unknown> =>
22
5
  typeof value === "object" && value !== null && !Array.isArray(value)
@@ -39,17 +22,9 @@ const formatLocalDateTime = (value: Date): string => {
39
22
  }
40
23
 
41
24
  const runtimeTagOfBaseDbType = (
42
- dialect: string,
43
- kind: string
25
+ dbType: Expression.DbType.Base<string, string>
44
26
  ): RuntimeTag | undefined => {
45
- const normalizedKind = baseKind(kind)
46
- if (dialect === "postgres") {
47
- return postgresDatatypeKinds[normalizedKind as keyof typeof postgresDatatypeKinds]?.runtime
48
- }
49
- if (dialect === "mysql") {
50
- return mysqlDatatypeKinds[normalizedKind as keyof typeof mysqlDatatypeKinds]?.runtime
51
- }
52
- return undefined
27
+ return dbType.runtime
53
28
  }
54
29
 
55
30
  const expectString = (value: unknown, label: string): string => {
@@ -225,7 +200,10 @@ const normalizeBytes = (value: unknown): Uint8Array => {
225
200
  if (value instanceof Uint8Array) {
226
201
  return new Uint8Array(value)
227
202
  }
228
- if (typeof Buffer !== "undefined" && value instanceof Buffer) {
203
+ const BufferConstructor = (globalThis as {
204
+ readonly Buffer?: abstract new (...args: never[]) => Uint8Array
205
+ }).Buffer
206
+ if (BufferConstructor !== undefined && value instanceof BufferConstructor) {
229
207
  return new Uint8Array(value)
230
208
  }
231
209
  throw new Error("Expected a byte array value")
@@ -298,7 +276,7 @@ export const normalizeDbValue = (
298
276
  if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
299
277
  return expectString(value, "text")
300
278
  }
301
- switch (runtimeTagOfBaseDbType(dbType.dialect, dbType.kind)) {
279
+ switch (runtimeTagOfBaseDbType(dbType)) {
302
280
  case "string":
303
281
  return expectString(value, "text")
304
282
  case "number":
@@ -1,19 +1,19 @@
1
1
  import * as Schema from "effect/Schema"
2
2
  import * as SchemaAST from "effect/SchemaAST"
3
3
 
4
- import * as Expression from "./expression.js"
5
- import * as ExpressionAst from "./expression-ast.js"
6
- import * as Query from "./query.js"
7
- import * as JsonPath from "./json/path.js"
8
- import type { PredicateFormula } from "./predicate-formula.js"
4
+ import * as Expression from "../scalar.js"
5
+ import * as ExpressionAst from "../expression-ast.js"
6
+ import * as Query from "../query.js"
7
+ import * as JsonPath from "../json/path.js"
8
+ import type { PredicateFormula } from "../predicate/formula.js"
9
9
  import {
10
10
  assumeFormulaFalse,
11
11
  assumeFormulaTrue,
12
12
  contradictsFormula,
13
13
  formulaOfExpression as formulaOfExpressionRuntime,
14
14
  impliesFormula
15
- } from "./predicate-runtime.js"
16
- import { flattenSelection } from "./projections.js"
15
+ } from "../predicate/runtime.js"
16
+ import { flattenSelection } from "../projections.js"
17
17
  import {
18
18
  BigIntStringSchema,
19
19
  DecimalStringSchema,
@@ -24,10 +24,8 @@ import {
24
24
  LocalTimeStringSchema,
25
25
  OffsetTimeStringSchema,
26
26
  YearStringSchema
27
- } from "./runtime-value.js"
28
- import { mysqlDatatypeKinds } from "../mysql/datatypes/spec.js"
29
- import { postgresDatatypeKinds } from "../postgres/datatypes/spec.js"
30
- import type { RuntimeTag } from "./datatypes/shape.js"
27
+ } from "./value.js"
28
+ import type { RuntimeTag } from "../datatypes/shape.js"
31
29
 
32
30
  export type RuntimeSchema = Schema.Schema<any, any, any>
33
31
 
@@ -37,21 +35,6 @@ type SchemaContext = {
37
35
 
38
36
  const schemaCache = new WeakMap<Expression.Any, RuntimeSchema | undefined>()
39
37
 
40
- const stripParameterizedKind = (kind: string): string => {
41
- const openParen = kind.indexOf("(")
42
- return openParen === -1 ? kind : kind.slice(0, openParen)
43
- }
44
-
45
- const stripArrayKind = (kind: string): string => {
46
- let current = kind
47
- while (current.endsWith("[]")) {
48
- current = current.slice(0, -2)
49
- }
50
- return current
51
- }
52
-
53
- const baseKind = (kind: string): string => stripArrayKind(stripParameterizedKind(kind))
54
-
55
38
  const isRecord = (value: unknown): value is Record<string, unknown> =>
56
39
  typeof value === "object" && value !== null && !Array.isArray(value)
57
40
 
@@ -98,17 +81,9 @@ const runtimeSchemaForTag = (tag: RuntimeTag): RuntimeSchema | undefined => {
98
81
  }
99
82
 
100
83
  const runtimeTagOfBaseDbType = (
101
- dialect: string,
102
- kind: string
84
+ dbType: Expression.DbType.Base<string, string>
103
85
  ): RuntimeTag | undefined => {
104
- const normalizedKind = baseKind(kind)
105
- if (dialect === "postgres") {
106
- return postgresDatatypeKinds[normalizedKind as keyof typeof postgresDatatypeKinds]?.runtime
107
- }
108
- if (dialect === "mysql") {
109
- return mysqlDatatypeKinds[normalizedKind as keyof typeof mysqlDatatypeKinds]?.runtime
110
- }
111
- return undefined
86
+ return dbType.runtime
112
87
  }
113
88
 
114
89
  export const runtimeSchemaForDbType = (
@@ -132,7 +107,7 @@ export const runtimeSchemaForDbType = (
132
107
  if ("variant" in dbType && (dbType.variant === "enum" || dbType.variant === "set")) {
133
108
  return Schema.String
134
109
  }
135
- const runtimeTag = runtimeTagOfBaseDbType(dbType.dialect, dbType.kind)
110
+ const runtimeTag = runtimeTagOfBaseDbType(dbType)
136
111
  return runtimeTag === undefined ? undefined : runtimeSchemaForTag(runtimeTag)
137
112
  }
138
113
 
@@ -257,7 +232,7 @@ const unionSchemas = (schemas: ReadonlyArray<RuntimeSchema | undefined>): Runtim
257
232
  }
258
233
 
259
234
  const firstSelectedExpression = (
260
- plan: Query.QueryPlan<any, any, any, any, any, any, any, any, any, any>
235
+ plan: Query.Plan.Any
261
236
  ): Expression.Any | undefined => {
262
237
  const selection = Query.getAst(plan).select
263
238
  return flattenSelection(selection as Record<string, unknown>)[0]?.expression
@@ -0,0 +1,22 @@
1
+ import type * as Brand from "effect/Brand";
2
+ import * as Schema from "effect/Schema";
3
+ import type { JsonPrimitive, JsonValue } from "../json/types.js";
4
+ export type { JsonPrimitive, JsonValue } from "../json/types.js";
5
+ export type LocalDateString = string & Brand.Brand<"LocalDateString">;
6
+ export type LocalTimeString = string & Brand.Brand<"LocalTimeString">;
7
+ export type OffsetTimeString = string & Brand.Brand<"OffsetTimeString">;
8
+ export type LocalDateTimeString = string & Brand.Brand<"LocalDateTimeString">;
9
+ export type InstantString = string & Brand.Brand<"InstantString">;
10
+ export type YearString = string & Brand.Brand<"YearString">;
11
+ export type BigIntString = string & Brand.Brand<"BigIntString">;
12
+ export type DecimalString = string & Brand.Brand<"DecimalString">;
13
+ export declare const LocalDateStringSchema: Schema.Schema<string & Brand.Brand<"LocalDateString">, string & Brand.Brand<"LocalDateString">, never>;
14
+ export declare const LocalTimeStringSchema: Schema.Schema<string & Brand.Brand<"LocalTimeString">, string & Brand.Brand<"LocalTimeString">, never>;
15
+ export declare const OffsetTimeStringSchema: Schema.Schema<string & Brand.Brand<"OffsetTimeString">, string & Brand.Brand<"OffsetTimeString">, never>;
16
+ export declare const LocalDateTimeStringSchema: Schema.Schema<string & Brand.Brand<"LocalDateTimeString">, string & Brand.Brand<"LocalDateTimeString">, never>;
17
+ export declare const InstantStringSchema: Schema.Schema<string & Brand.Brand<"InstantString">, string & Brand.Brand<"InstantString">, never>;
18
+ export declare const YearStringSchema: Schema.Schema<string & Brand.Brand<"YearString">, string & Brand.Brand<"YearString">, never>;
19
+ export declare const BigIntStringSchema: Schema.Schema<string & Brand.Brand<"BigIntString">, string & Brand.Brand<"BigIntString">, never>;
20
+ export declare const DecimalStringSchema: Schema.Schema<string & Brand.Brand<"DecimalString">, string & Brand.Brand<"DecimalString">, never>;
21
+ export declare const JsonValueSchema: Schema.Schema<JsonValue>;
22
+ export declare const JsonPrimitiveSchema: Schema.Schema<JsonPrimitive>;
@@ -1,9 +1,9 @@
1
1
  import type * as Brand from "effect/Brand"
2
2
  import * as Schema from "effect/Schema"
3
3
 
4
- import type { JsonPrimitive, JsonValue } from "./json/types.js"
4
+ import type { JsonPrimitive, JsonValue } from "../json/types.js"
5
5
 
6
- export type { JsonPrimitive, JsonValue } from "./json/types.js"
6
+ export type { JsonPrimitive, JsonValue } from "../json/types.js"
7
7
 
8
8
  export type LocalDateString = string & Brand.Brand<"LocalDateString">
9
9
  export type LocalTimeString = string & Brand.Brand<"LocalTimeString">