effect-qb 0.16.0 → 0.19.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 (128) hide show
  1. package/README.md +4 -0
  2. package/dist/index.js +8065 -0
  3. package/dist/mysql.js +4036 -2418
  4. package/dist/postgres/metadata.js +2536 -625
  5. package/dist/postgres.js +8248 -7857
  6. package/dist/sqlite.js +8854 -0
  7. package/dist/standard.js +8019 -0
  8. package/package.json +15 -3
  9. package/src/casing.ts +71 -0
  10. package/src/index.ts +2 -0
  11. package/src/internal/casing.ts +89 -0
  12. package/src/internal/column-state.ts +11 -6
  13. package/src/internal/column.ts +44 -7
  14. package/src/internal/datatypes/define.ts +2 -1
  15. package/src/internal/datatypes/enrich.ts +23 -0
  16. package/src/internal/datatypes/lookup.ts +14 -7
  17. package/src/internal/derived-table.ts +7 -13
  18. package/src/internal/dialect-renderers/mysql.ts +2046 -0
  19. package/src/{postgres/internal/sql-expression-renderer.ts → internal/dialect-renderers/postgres.ts} +867 -283
  20. package/src/{mysql/internal/sql-expression-renderer.ts → internal/dialect-renderers/sqlite.ts} +834 -358
  21. package/src/internal/dialect.ts +37 -0
  22. package/src/internal/dsl-mutation-runtime.ts +29 -10
  23. package/src/internal/dsl-plan-runtime.ts +41 -24
  24. package/src/internal/dsl-query-runtime.ts +11 -31
  25. package/src/internal/dsl-transaction-ddl-runtime.ts +61 -15
  26. package/src/internal/executor.ts +57 -15
  27. package/src/internal/expression-ast.ts +3 -2
  28. package/src/internal/grouping-key.ts +216 -9
  29. package/src/internal/implication-runtime.ts +3 -2
  30. package/src/internal/json/types.ts +155 -40
  31. package/src/internal/predicate/context.ts +14 -1
  32. package/src/internal/predicate/key.ts +19 -2
  33. package/src/internal/predicate/runtime.ts +30 -3
  34. package/src/internal/query.d.ts +38 -11
  35. package/src/internal/query.ts +315 -54
  36. package/src/internal/renderer.ts +51 -6
  37. package/src/internal/runtime/driver-value-mapping.ts +58 -0
  38. package/src/internal/runtime/normalize.ts +74 -43
  39. package/src/internal/runtime/schema.ts +5 -3
  40. package/src/internal/runtime/value.ts +153 -30
  41. package/src/internal/scalar.ts +6 -1
  42. package/src/internal/schema-derivation.d.ts +12 -61
  43. package/src/internal/schema-derivation.ts +90 -38
  44. package/src/internal/schema-expression.ts +2 -2
  45. package/src/internal/sql-expression-renderer.ts +19 -0
  46. package/src/internal/standard-dsl.ts +6885 -0
  47. package/src/internal/table-options.ts +229 -62
  48. package/src/internal/table.d.ts +33 -32
  49. package/src/internal/table.ts +469 -160
  50. package/src/mysql/column-extension.ts +3 -0
  51. package/src/mysql/column.ts +27 -12
  52. package/src/mysql/datatypes/index.ts +24 -2
  53. package/src/mysql/errors/catalog.ts +5 -5
  54. package/src/mysql/errors/normalize.ts +2 -2
  55. package/src/mysql/executor.ts +7 -5
  56. package/src/mysql/internal/dialect.ts +9 -4
  57. package/src/mysql/internal/dsl.ts +906 -324
  58. package/src/mysql/internal/renderer.ts +7 -2
  59. package/src/mysql/json.ts +37 -0
  60. package/src/mysql/query-extension.ts +16 -0
  61. package/src/mysql/query.ts +9 -2
  62. package/src/mysql/renderer.ts +31 -4
  63. package/src/mysql.ts +4 -12
  64. package/src/postgres/column-extension.ts +28 -0
  65. package/src/postgres/column.ts +9 -13
  66. package/src/postgres/datatypes/index.d.ts +2 -1
  67. package/src/postgres/datatypes/index.ts +3 -2
  68. package/src/postgres/errors/normalize.ts +2 -2
  69. package/src/postgres/executor.ts +55 -10
  70. package/src/postgres/function/core.ts +20 -4
  71. package/src/postgres/function/index.ts +1 -17
  72. package/src/postgres/internal/dialect.ts +9 -4
  73. package/src/postgres/internal/dsl.ts +850 -359
  74. package/src/postgres/internal/renderer.ts +7 -2
  75. package/src/postgres/internal/schema-ddl.ts +22 -9
  76. package/src/postgres/internal/schema-model.ts +244 -10
  77. package/src/postgres/json.ts +100 -24
  78. package/src/postgres/jsonb.ts +38 -0
  79. package/src/postgres/query-extension.ts +2 -0
  80. package/src/postgres/query.ts +9 -2
  81. package/src/postgres/renderer.ts +31 -4
  82. package/src/postgres/schema-management.ts +108 -16
  83. package/src/postgres/schema.ts +98 -15
  84. package/src/postgres/table.ts +203 -398
  85. package/src/postgres/type.ts +8 -7
  86. package/src/postgres.ts +9 -11
  87. package/src/sqlite/column-extension.ts +3 -0
  88. package/src/sqlite/column.ts +127 -0
  89. package/src/sqlite/datatypes/index.ts +80 -0
  90. package/src/sqlite/datatypes/spec.ts +98 -0
  91. package/src/sqlite/errors/catalog.ts +103 -0
  92. package/src/sqlite/errors/fields.ts +19 -0
  93. package/src/sqlite/errors/index.ts +19 -0
  94. package/src/sqlite/errors/normalize.ts +229 -0
  95. package/src/sqlite/errors/requirements.ts +71 -0
  96. package/src/sqlite/errors/types.ts +29 -0
  97. package/src/sqlite/executor.ts +229 -0
  98. package/src/sqlite/function/aggregate.ts +2 -0
  99. package/src/sqlite/function/core.ts +2 -0
  100. package/src/sqlite/function/index.ts +19 -0
  101. package/src/sqlite/function/string.ts +2 -0
  102. package/src/sqlite/function/temporal.ts +100 -0
  103. package/src/sqlite/function/window.ts +2 -0
  104. package/src/sqlite/internal/dialect.ts +42 -0
  105. package/src/sqlite/internal/dsl.ts +6979 -0
  106. package/src/sqlite/internal/renderer.ts +51 -0
  107. package/src/sqlite/json.ts +39 -0
  108. package/src/sqlite/query-extension.ts +2 -0
  109. package/src/sqlite/query.ts +196 -0
  110. package/src/sqlite/renderer.ts +51 -0
  111. package/src/sqlite.ts +14 -0
  112. package/src/standard/column.ts +163 -0
  113. package/src/standard/datatypes/index.ts +83 -0
  114. package/src/standard/datatypes/spec.ts +98 -0
  115. package/src/standard/dialect.ts +40 -0
  116. package/src/standard/function/aggregate.ts +2 -0
  117. package/src/standard/function/core.ts +2 -0
  118. package/src/standard/function/index.ts +18 -0
  119. package/src/standard/function/string.ts +2 -0
  120. package/src/standard/function/temporal.ts +78 -0
  121. package/src/standard/function/window.ts +2 -0
  122. package/src/standard/internal/renderer.ts +45 -0
  123. package/src/standard/query.ts +152 -0
  124. package/src/standard/renderer.ts +21 -0
  125. package/src/standard/table.ts +147 -0
  126. package/src/standard.ts +18 -0
  127. package/src/internal/aggregation-validation.ts +0 -57
  128. package/src/mysql/table.ts +0 -157
@@ -0,0 +1,3 @@
1
+ export { custom } from "./column.js"
2
+
3
+ export type { Any, AnyBound } from "./column.js"
@@ -1,8 +1,10 @@
1
1
  import * as Schema from "effect/Schema"
2
2
 
3
3
  import * as BaseColumn from "../internal/column.js"
4
- import { makeColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
4
+ import { makeColumnDefinition, type AnyColumnDefinition, type ColumnDefinition } from "../internal/column-state.js"
5
5
  import type * as Expression from "../internal/scalar.js"
6
+ import type { NonEmptyStringInput } from "../internal/table-options.js"
7
+ import { enrichDbType } from "../internal/datatypes/enrich.js"
6
8
  import {
7
9
  DecimalStringSchema,
8
10
  LocalDateStringSchema,
@@ -13,13 +15,6 @@ import {
13
15
  } from "../internal/runtime/value.js"
14
16
  import { mysqlDatatypes } from "./datatypes/index.js"
15
17
 
16
- const enrichDbType = <Db extends Expression.DbType.Any>(dbType: Db): Db => {
17
- const candidate = (mysqlDatatypes as unknown as Record<string, (() => Expression.DbType.Any) | undefined>)[dbType.kind]
18
- return typeof candidate === "function"
19
- ? { ...candidate(), ...dbType } as Db
20
- : dbType
21
- }
22
-
23
18
  const primitive = <Type, Db extends Expression.DbType.Any>(
24
19
  schema: Schema.Schema<Type, any, any>,
25
20
  dbType: Db
@@ -50,8 +45,8 @@ export const custom = <SchemaType extends Schema.Schema.Any, Db extends Expressi
50
45
  schema: SchemaType,
51
46
  dbType: Db
52
47
  ) =>
53
- makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
54
- dbType: enrichDbType(dbType),
48
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
49
+ dbType: enrichDbType(mysqlDatatypes, dbType),
55
50
  nullable: false,
56
51
  hasDefault: false,
57
52
  generated: false,
@@ -82,7 +77,7 @@ export const date = () => primitive(LocalDateStringSchema, mysqlDatatypes.date()
82
77
  export const datetime = () => primitive(LocalDateTimeStringSchema, mysqlDatatypes.datetime())
83
78
  export const timestamp = () => primitive(LocalDateTimeStringSchema, mysqlDatatypes.timestamp())
84
79
  export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =>
85
- makeColumnDefinition(schema as unknown as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
80
+ makeColumnDefinition(schema as Schema.Schema<NonNullable<Schema.Schema.Type<SchemaType>>, any, any>, {
86
81
  dbType: { ...mysqlDatatypes.json(), variant: "json" } as Expression.DbType.Json<"mysql", "json">,
87
82
  nullable: false,
88
83
  hasDefault: false,
@@ -97,7 +92,27 @@ export const json = <SchemaType extends Schema.Schema.Any>(schema: SchemaType) =
97
92
  export const nullable = BaseColumn.nullable
98
93
  export const brand = BaseColumn.brand
99
94
  export const primaryKey = BaseColumn.primaryKey
100
- export const unique = BaseColumn.unique
95
+ type UniqueColumn<Column extends AnyColumnDefinition> = ReturnType<typeof BaseColumn.unique<Column>>
96
+
97
+ type MysqlUniqueOptions = {
98
+ readonly name?: string
99
+ readonly nullsNotDistinct?: never
100
+ readonly deferrable?: never
101
+ readonly initiallyDeferred?: never
102
+ }
103
+
104
+ type NonEmptyOptionNameInput<Options> = Options extends { readonly name: infer Name extends string }
105
+ ? NonEmptyStringInput<Name> extends never ? never : unknown
106
+ : unknown
107
+
108
+ type UniqueModifier = {
109
+ <Column extends AnyColumnDefinition>(column: Column): UniqueColumn<Column>
110
+ readonly options: <const Options extends MysqlUniqueOptions>(
111
+ options: Options & NonEmptyOptionNameInput<Options>
112
+ ) => <Column extends AnyColumnDefinition>(column: Column) => UniqueColumn<Column>
113
+ }
114
+
115
+ export const unique = BaseColumn.unique as UniqueModifier
101
116
  const default_ = BaseColumn.default_
102
117
  export const generated = BaseColumn.generated
103
118
  export const driverValueMapping = BaseColumn.driverValueMapping
@@ -1,5 +1,6 @@
1
1
  import type { DatatypeModule } from "../../internal/datatypes/define.js"
2
2
  import type * as Expression from "../../internal/scalar.js"
3
+ import type { NonEmptyStringInput } from "../../internal/table-options.js"
3
4
  import { mysqlDatatypeFamilies, mysqlDatatypeKinds } from "./spec.js"
4
5
 
5
6
  const withMetadata = <Kind extends keyof typeof mysqlDatatypeKinds & string>(
@@ -19,9 +20,9 @@ const withMetadata = <Kind extends keyof typeof mysqlDatatypeKinds & string>(
19
20
  }
20
21
 
21
22
  const mysqlDatatypeModule = {
22
- custom: (kind: string) => ({
23
+ custom: <Kind extends string>(kind: NonEmptyStringInput<Kind>) => ({
23
24
  dialect: "mysql",
24
- kind
25
+ kind: kind as Kind
25
26
  }),
26
27
  uuid: () => ({
27
28
  dialect: "mysql",
@@ -50,12 +51,33 @@ type MysqlUuidWitness = Expression.DbType.Base<"mysql", "uuid"> & {
50
51
  }
51
52
  }
52
53
 
54
+ type MysqlJsonWitness = Expression.DbType.Base<"mysql", "json"> & {
55
+ readonly family: "json"
56
+ readonly runtime: "json"
57
+ readonly compareGroup: "json"
58
+ readonly castTargets: readonly ["json", "text"]
59
+ readonly driverValueMapping: {
60
+ readonly toDriver: (value: unknown) => unknown
61
+ }
62
+ }
63
+
64
+ mysqlDatatypeModule.json = () => ({
65
+ ...withMetadata("json"),
66
+ driverValueMapping: {
67
+ toDriver: (value: unknown) =>
68
+ value !== null && typeof value === "object"
69
+ ? JSON.stringify(value)
70
+ : value
71
+ }
72
+ }) as MysqlJsonWitness
73
+
53
74
  export const mysqlDatatypes = mysqlDatatypeModule as DatatypeModule<
54
75
  "mysql",
55
76
  typeof mysqlDatatypeKinds,
56
77
  typeof mysqlDatatypeFamilies
57
78
  > & {
58
79
  readonly uuid: () => MysqlUuidWitness
80
+ readonly json: () => MysqlJsonWitness
59
81
  }
60
82
 
61
83
  export type MysqlDatatypeModule = typeof mysqlDatatypes
@@ -51636,17 +51636,17 @@ export const mysqlErrorCatalogByNumber = {
51636
51636
  "MY-015153": [mysqlErrorCatalogBySymbol["ER_WARN_AUDIT_LOG_FILTER_RECOVERY_LOGGING_DISABLED_LOG"]!],
51637
51637
  } as const
51638
51638
 
51639
- const mysqlSymbolPattern = /^(?:[A-Z][A-Z0-9_]*|MY-\d+)$/
51640
- const mysqlNumberPattern = /^(?:\d+|MY-\d+)$/
51641
-
51642
51639
  export type MysqlErrorSymbol = keyof typeof mysqlErrorCatalogBySymbol
51643
51640
  export type MysqlErrorDescriptor<Symbol extends MysqlErrorSymbol = MysqlErrorSymbol> = (typeof mysqlErrorCatalogBySymbol)[Symbol]
51644
51641
  export type MysqlErrorNumber = keyof typeof mysqlErrorCatalogByNumber
51645
51642
  export type MysqlErrorTag<Symbol extends MysqlErrorSymbol = MysqlErrorSymbol> = MysqlErrorDescriptor<Symbol>["tag"]
51646
51643
  export type MysqlErrorDescriptorsByNumber<Number extends MysqlErrorNumber = MysqlErrorNumber> = (typeof mysqlErrorCatalogByNumber)[Number]
51647
51644
 
51648
- export const isMysqlErrorSymbol = (value: string): value is MysqlErrorSymbol => mysqlSymbolPattern.test(value)
51649
- export const isMysqlErrorNumber = (value: string): value is MysqlErrorNumber => mysqlNumberPattern.test(value)
51645
+ export const isMysqlErrorSymbol = (value: string): value is MysqlErrorSymbol =>
51646
+ value in mysqlErrorCatalogBySymbol
51647
+
51648
+ export const isMysqlErrorNumber = (value: string): value is MysqlErrorNumber =>
51649
+ value in mysqlErrorCatalogByNumber
51650
51650
 
51651
51651
  export const getMysqlErrorDescriptor = <Symbol extends MysqlErrorSymbol>(symbol: Symbol): MysqlErrorDescriptor<Symbol> =>
51652
51652
  mysqlErrorCatalogBySymbol[symbol]
@@ -48,8 +48,8 @@ const asNumber = (value: unknown): number | undefined => {
48
48
  if (typeof value === "number" && Number.isFinite(value)) {
49
49
  return value
50
50
  }
51
- if (typeof value === "string" && value.trim() !== "") {
52
- const parsed = Number(value)
51
+ if (typeof value === "string" && /^[+-]?\d+$/.test(value.trim())) {
52
+ const parsed = Number(value.trim())
53
53
  return Number.isFinite(parsed) ? parsed : undefined
54
54
  }
55
55
  return undefined
@@ -6,6 +6,7 @@ import * as CoreExecutor from "../internal/executor.js"
6
6
  import * as CoreQuery from "../internal/query.js"
7
7
  import * as CoreRenderer from "../internal/renderer.js"
8
8
  import type * as Expression from "../internal/scalar.js"
9
+ import type { MysqlDatatypeFamily, MysqlDatatypeKind } from "./datatypes/spec.js"
9
10
  import { renderMysqlPlan } from "./internal/renderer.js"
10
11
  import {
11
12
  narrowMysqlDriverErrorForReadQuery,
@@ -24,12 +25,13 @@ export type Driver<Error = never, Context = never> = CoreExecutor.Driver<"mysql"
24
25
  export type Executor<Error = never, Context = never> = CoreExecutor.Executor<"mysql", Error, Context>
25
26
  /** MySQL-specialized renderer contract. */
26
27
  export type Renderer = CoreRenderer.Renderer<"mysql">
28
+ export type ValueMappings = Expression.DriverValueMappingsFor<MysqlDatatypeKind | "uuid", MysqlDatatypeFamily | "uuid">
27
29
  /** Optional renderer / driver overrides for the standard MySQL executor pipeline. */
28
30
  export interface MakeOptions<Error = never, Context = never> {
29
31
  readonly renderer?: Renderer
30
32
  readonly driver?: Driver<Error, Context>
31
33
  readonly driverMode?: CoreExecutor.DriverMode
32
- readonly valueMappings?: Expression.DriverValueMappings
34
+ readonly valueMappings?: ValueMappings
33
35
  }
34
36
  /** Standard composed error shape for MySQL executors. */
35
37
  export type MysqlExecutorError = MysqlDriverError | RowDecodeError
@@ -172,7 +174,7 @@ export function make(
172
174
  options: {
173
175
  readonly renderer?: Renderer
174
176
  readonly driverMode?: CoreExecutor.DriverMode
175
- readonly valueMappings?: Expression.DriverValueMappings
177
+ readonly valueMappings?: ValueMappings
176
178
  }
177
179
  ): QueryExecutor<SqlClient.SqlClient>
178
180
  export function make<Error = never, Context = never>(
@@ -180,7 +182,7 @@ export function make<Error = never, Context = never>(
180
182
  readonly renderer?: Renderer
181
183
  readonly driver: Driver<Error, Context>
182
184
  readonly driverMode?: CoreExecutor.DriverMode
183
- readonly valueMappings?: Expression.DriverValueMappings
185
+ readonly valueMappings?: ValueMappings
184
186
  }
185
187
  ): QueryExecutor<Context>
186
188
  export function make<Error = never, Context = never>(
@@ -188,14 +190,14 @@ export function make<Error = never, Context = never>(
188
190
  ): QueryExecutor<any> {
189
191
  if (options.driver) {
190
192
  return fromDriver(
191
- options.renderer ?? CoreRenderer.make("mysql", (plan) => renderMysqlPlan(plan, { valueMappings: options.valueMappings })),
193
+ options.renderer ?? CoreRenderer.makeTrusted("mysql", (plan) => renderMysqlPlan(plan, { valueMappings: options.valueMappings })),
192
194
  options.driver,
193
195
  options.driverMode,
194
196
  options.valueMappings
195
197
  )
196
198
  }
197
199
  return fromDriver(
198
- options.renderer ?? CoreRenderer.make("mysql", (plan) => renderMysqlPlan(plan, { valueMappings: options.valueMappings })),
200
+ options.renderer ?? CoreRenderer.makeTrusted("mysql", (plan) => renderMysqlPlan(plan, { valueMappings: options.valueMappings })),
199
201
  sqlClientDriver(),
200
202
  options.driverMode,
201
203
  options.valueMappings
@@ -1,7 +1,9 @@
1
- import type { RenderState, RenderValueContext, SqlDialect } from "../../internal/dialect.js"
1
+ import { quoteBacktickIdentifier, type RenderState, type RenderValueContext, type SqlDialect } from "../../internal/dialect.js"
2
+ import { renderExpression, renderQueryAst } from "../../internal/dialect-renderers/mysql.js"
2
3
  import { toDriverValue } from "../../internal/runtime/driver-value-mapping.js"
4
+ import { standardDialect } from "../../standard/dialect.js"
3
5
 
4
- const quoteIdentifier = (value: string): string => `\`${value.replaceAll("`", "``")}\``
6
+ const quoteIdentifier = quoteBacktickIdentifier
5
7
 
6
8
  const renderLiteral = (value: unknown, state: RenderState, context: RenderValueContext = {}): string => {
7
9
  const driverValue = toDriverValue(value, {
@@ -28,11 +30,12 @@ const renderLiteral = (value: unknown, state: RenderState, context: RenderValueC
28
30
  * grows.
29
31
  */
30
32
  export const mysqlDialect: SqlDialect<"mysql"> = {
33
+ ...standardDialect,
31
34
  name: "mysql",
32
35
  quoteIdentifier,
33
36
  renderLiteral,
34
37
  renderTableReference(tableName, baseTableName, schemaName) {
35
- const renderedBase = schemaName
38
+ const renderedBase = schemaName && schemaName !== "public"
36
39
  ? `${quoteIdentifier(schemaName)}.${quoteIdentifier(baseTableName)}`
37
40
  : quoteIdentifier(baseTableName)
38
41
  return tableName === baseTableName
@@ -41,5 +44,7 @@ export const mysqlDialect: SqlDialect<"mysql"> = {
41
44
  },
42
45
  renderConcat(values) {
43
46
  return `concat(${values.join(", ")})`
44
- }
47
+ },
48
+ renderQueryAst,
49
+ renderExpression
45
50
  }