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
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
type AnyColumnDefinition,
|
|
5
5
|
type IsNullable
|
|
6
6
|
} from "./column-state.js"
|
|
7
|
+
import type * as Casing from "./casing.js"
|
|
8
|
+
import * as Expression from "./scalar.js"
|
|
7
9
|
import type { Any as AnyExpression } from "./scalar.js"
|
|
10
|
+
import * as SchemaExpression from "./schema-expression.js"
|
|
8
11
|
import type { Any as AnySchemaExpression } from "./schema-expression.js"
|
|
9
12
|
import type { TableFieldMap } from "./schema-derivation.js"
|
|
10
13
|
|
|
@@ -39,6 +42,27 @@ const validateReferentialAction = (action: unknown): void => {
|
|
|
39
42
|
}
|
|
40
43
|
}
|
|
41
44
|
|
|
45
|
+
const requireColumnArray = (
|
|
46
|
+
value: unknown,
|
|
47
|
+
message: string
|
|
48
|
+
): readonly string[] => {
|
|
49
|
+
if (!Array.isArray(value) || value.some((column) => typeof column !== "string" || column.length === 0)) {
|
|
50
|
+
throw new Error(message)
|
|
51
|
+
}
|
|
52
|
+
return value
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const requireOptionalColumnArray = (
|
|
56
|
+
value: unknown,
|
|
57
|
+
message: string
|
|
58
|
+
): readonly string[] =>
|
|
59
|
+
value === undefined ? [] : requireColumnArray(value, message)
|
|
60
|
+
|
|
61
|
+
const isDdlExpressionLike = (value: unknown): value is DdlExpressionLike =>
|
|
62
|
+
typeof value === "object" &&
|
|
63
|
+
value !== null &&
|
|
64
|
+
(Expression.TypeId in value || SchemaExpression.TypeId in value)
|
|
65
|
+
|
|
42
66
|
export type IndexKeySpec =
|
|
43
67
|
| {
|
|
44
68
|
readonly kind: "column"
|
|
@@ -91,6 +115,7 @@ export type TableOptionSpec =
|
|
|
91
115
|
readonly references: () => {
|
|
92
116
|
readonly tableName: string
|
|
93
117
|
readonly schemaName?: string
|
|
118
|
+
readonly casing?: Casing.Options
|
|
94
119
|
readonly columns: ColumnList
|
|
95
120
|
readonly knownColumns?: readonly string[]
|
|
96
121
|
}
|
|
@@ -134,6 +159,83 @@ type TupleFromColumns<Columns> = Columns extends readonly [infer Head extends st
|
|
|
134
159
|
export type NonEmptyColumnInput<Columns extends string | readonly string[]> =
|
|
135
160
|
TupleFromColumns<Columns> extends never ? never : Columns
|
|
136
161
|
|
|
162
|
+
export type NonEmptyStringInput<Value extends string> =
|
|
163
|
+
string extends Value ? Value : Value extends "" ? never : Value
|
|
164
|
+
|
|
165
|
+
export type LiteralStringInput<Value extends string> =
|
|
166
|
+
string extends Value ? never : NonEmptyStringInput<Value>
|
|
167
|
+
|
|
168
|
+
type LowerAlpha =
|
|
169
|
+
| "a"
|
|
170
|
+
| "b"
|
|
171
|
+
| "c"
|
|
172
|
+
| "d"
|
|
173
|
+
| "e"
|
|
174
|
+
| "f"
|
|
175
|
+
| "g"
|
|
176
|
+
| "h"
|
|
177
|
+
| "i"
|
|
178
|
+
| "j"
|
|
179
|
+
| "k"
|
|
180
|
+
| "l"
|
|
181
|
+
| "m"
|
|
182
|
+
| "n"
|
|
183
|
+
| "o"
|
|
184
|
+
| "p"
|
|
185
|
+
| "q"
|
|
186
|
+
| "r"
|
|
187
|
+
| "s"
|
|
188
|
+
| "t"
|
|
189
|
+
| "u"
|
|
190
|
+
| "v"
|
|
191
|
+
| "w"
|
|
192
|
+
| "x"
|
|
193
|
+
| "y"
|
|
194
|
+
| "z"
|
|
195
|
+
type UpperAlpha = Uppercase<LowerAlpha>
|
|
196
|
+
type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
|
|
197
|
+
type IdentifierStart = LowerAlpha | UpperAlpha | "_"
|
|
198
|
+
type IdentifierRest = IdentifierStart | Digit
|
|
199
|
+
|
|
200
|
+
type SafeIdentifierRest<Value extends string> =
|
|
201
|
+
Value extends ""
|
|
202
|
+
? Value
|
|
203
|
+
: Value extends `${infer Head}${infer Tail}`
|
|
204
|
+
? Head extends IdentifierRest ? SafeIdentifierRest<Tail> : never
|
|
205
|
+
: never
|
|
206
|
+
|
|
207
|
+
type SafeSqlIdentifier<Value extends string> =
|
|
208
|
+
Value extends `${infer Head}${infer Tail}`
|
|
209
|
+
? Head extends IdentifierStart
|
|
210
|
+
? SafeIdentifierRest<Tail> extends never ? never : Value
|
|
211
|
+
: never
|
|
212
|
+
: never
|
|
213
|
+
|
|
214
|
+
export type SafeSqlIdentifierPathInput<Value extends string> =
|
|
215
|
+
string extends Value
|
|
216
|
+
? never
|
|
217
|
+
: Value extends `${infer Head}.${infer Tail}`
|
|
218
|
+
? SafeSqlIdentifier<Head> extends never
|
|
219
|
+
? never
|
|
220
|
+
: SafeSqlIdentifierPathInput<Tail> extends never ? never : Value
|
|
221
|
+
: SafeSqlIdentifier<Value> extends never ? never : Value
|
|
222
|
+
|
|
223
|
+
export type SafeSqlIdentifierInput<Value extends string> =
|
|
224
|
+
string extends Value
|
|
225
|
+
? never
|
|
226
|
+
: SafeSqlIdentifier<Value> extends never ? never : Value
|
|
227
|
+
|
|
228
|
+
type LiteralStringTupleInput<Values extends readonly string[]> = {
|
|
229
|
+
readonly [K in keyof Values]: Values[K] extends string ? LiteralStringInput<Values[K]> : never
|
|
230
|
+
} & Values
|
|
231
|
+
|
|
232
|
+
export type CollationIdentifierInput<Value extends string | readonly [string, ...string[]]> =
|
|
233
|
+
Value extends string
|
|
234
|
+
? LiteralStringInput<Value>
|
|
235
|
+
: Value extends readonly [string, ...string[]]
|
|
236
|
+
? LiteralStringTupleInput<Value>
|
|
237
|
+
: never
|
|
238
|
+
|
|
137
239
|
export type MatchingColumnArityInput<
|
|
138
240
|
Left extends string | readonly string[],
|
|
139
241
|
Right extends string | readonly string[]
|
|
@@ -206,11 +308,10 @@ type InlinePrimaryKeyKeys<Fields extends TableFieldMap> = Extract<{
|
|
|
206
308
|
|
|
207
309
|
/** Normalizes a string or tuple input into a non-empty column list. */
|
|
208
310
|
export const normalizeColumnList = (columns: string | readonly string[]): ColumnList => {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
throw new Error("Table options require at least one column")
|
|
311
|
+
if (typeof columns === "string") {
|
|
312
|
+
return [columns]
|
|
212
313
|
}
|
|
213
|
-
return
|
|
314
|
+
return [columns[0] as string, ...columns.slice(1)]
|
|
214
315
|
}
|
|
215
316
|
|
|
216
317
|
/** Converts inline column flags into normalized table option records. */
|
|
@@ -236,8 +337,6 @@ export const collectInlineOptions = <Fields extends TableFieldMap>(
|
|
|
236
337
|
})
|
|
237
338
|
}
|
|
238
339
|
if (column.metadata.references) {
|
|
239
|
-
validateReferentialAction(column.metadata.references.onUpdate)
|
|
240
|
-
validateReferentialAction(column.metadata.references.onDelete)
|
|
241
340
|
const local = [columnName] as ColumnList
|
|
242
341
|
options.push({
|
|
243
342
|
kind: "foreignKey",
|
|
@@ -248,6 +347,7 @@ export const collectInlineOptions = <Fields extends TableFieldMap>(
|
|
|
248
347
|
return {
|
|
249
348
|
tableName: bound.baseTableName,
|
|
250
349
|
schemaName: bound.schemaName,
|
|
350
|
+
casing: bound.casing,
|
|
251
351
|
columns: [bound.columnName]
|
|
252
352
|
}
|
|
253
353
|
},
|
|
@@ -287,24 +387,16 @@ export const resolvePrimaryKeyColumns = <Fields extends TableFieldMap>(
|
|
|
287
387
|
const inline = Object.entries(fields)
|
|
288
388
|
.filter(([, column]) => column.metadata.primaryKey)
|
|
289
389
|
.map(([key]) => key) as (keyof Fields & string)[]
|
|
290
|
-
const explicit = declaredOptions
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
}
|
|
390
|
+
const explicit = declaredOptions.flatMap((option) => {
|
|
391
|
+
if (typeof option !== "object" || option === null || !("kind" in option) || option.kind !== "primaryKey") {
|
|
392
|
+
return []
|
|
393
|
+
}
|
|
394
|
+
return Array.isArray(option.columns) ? [option.columns] : []
|
|
395
|
+
})
|
|
296
396
|
if (explicit.length === 0) {
|
|
297
397
|
return inline
|
|
298
398
|
}
|
|
299
399
|
const tablePrimaryKey = [...explicit[0]!] as (keyof Fields & string)[]
|
|
300
|
-
if (inline.length > 0) {
|
|
301
|
-
const same =
|
|
302
|
-
inline.length === tablePrimaryKey.length &&
|
|
303
|
-
inline.every((column) => tablePrimaryKey.includes(column))
|
|
304
|
-
if (!same) {
|
|
305
|
-
throw new Error("Inline primary keys conflict with table-level primary key declaration")
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
400
|
return tablePrimaryKey
|
|
309
401
|
}
|
|
310
402
|
|
|
@@ -312,67 +404,35 @@ export const resolvePrimaryKeyColumns = <Fields extends TableFieldMap>(
|
|
|
312
404
|
export const validateOptions = <Fields extends TableFieldMap>(
|
|
313
405
|
tableName: string,
|
|
314
406
|
fields: Fields,
|
|
315
|
-
options:
|
|
407
|
+
options: unknown
|
|
316
408
|
): void => {
|
|
317
|
-
const
|
|
318
|
-
|
|
409
|
+
const tableOptions = (Array.isArray(options)
|
|
410
|
+
? options
|
|
411
|
+
: [options]) as readonly TableOptionSpec[]
|
|
412
|
+
for (const option of tableOptions) {
|
|
413
|
+
if (typeof option !== "object" || option === null || !("kind" in option)) {
|
|
414
|
+
continue
|
|
415
|
+
}
|
|
319
416
|
switch (option.kind) {
|
|
320
417
|
case "index":
|
|
321
418
|
case "primaryKey":
|
|
322
419
|
case "unique":
|
|
323
420
|
case "foreignKey": {
|
|
324
|
-
const columns = option.kind === "index"
|
|
325
|
-
? option.columns ?? []
|
|
326
|
-
: option.columns
|
|
327
|
-
if (columns.length === 0 && option.kind !== "index") {
|
|
328
|
-
throw new Error(`Option '${option.kind}' on table '${tableName}' requires at least one column`)
|
|
329
|
-
}
|
|
330
|
-
for (const column of columns) {
|
|
331
|
-
if (!knownColumns.has(column)) {
|
|
332
|
-
throw new Error(`Unknown column '${column}' on table '${tableName}'`)
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
if (option.kind === "foreignKey") {
|
|
336
|
-
validateReferentialAction(option.onUpdate)
|
|
337
|
-
validateReferentialAction(option.onDelete)
|
|
338
|
-
const reference = option.references()
|
|
339
|
-
if (reference.columns.length !== columns.length) {
|
|
340
|
-
throw new Error(`Foreign key on table '${tableName}' must reference the same number of columns`)
|
|
341
|
-
}
|
|
342
|
-
if (reference.knownColumns) {
|
|
343
|
-
const referenced = new Set(reference.knownColumns)
|
|
344
|
-
for (const column of reference.columns) {
|
|
345
|
-
if (!referenced.has(column)) {
|
|
346
|
-
throw new Error(`Unknown referenced column '${column}' on table '${reference.tableName}'`)
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
421
|
if (option.kind === "index") {
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}
|
|
357
|
-
for (const key of option.keys ?? []) {
|
|
358
|
-
if (key.kind === "column" && !knownColumns.has(key.column)) {
|
|
359
|
-
throw new Error(`Unknown index key column '${key.column}' on table '${tableName}'`)
|
|
422
|
+
const keys = Array.isArray(option.keys) ? option.keys : []
|
|
423
|
+
for (const key of keys) {
|
|
424
|
+
if (typeof key !== "object" || key === null || !("kind" in key)) {
|
|
425
|
+
continue
|
|
360
426
|
}
|
|
361
427
|
}
|
|
362
|
-
if (columns.length === 0 && (option.keys === undefined || option.keys.length === 0)) {
|
|
363
|
-
throw new Error(`Index on table '${tableName}' requires at least one column or key`)
|
|
364
|
-
}
|
|
365
428
|
}
|
|
366
429
|
break
|
|
367
430
|
}
|
|
368
431
|
case "check": {
|
|
369
432
|
break
|
|
370
433
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
for (const column of resolvePrimaryKeyColumns(fields, options)) {
|
|
374
|
-
if (fields[column]!.metadata.nullable) {
|
|
375
|
-
throw new Error(`Primary key column '${String(column)}' cannot be nullable`)
|
|
434
|
+
default:
|
|
435
|
+
break
|
|
376
436
|
}
|
|
377
437
|
}
|
|
378
438
|
}
|