tempest-db-js 0.4.0 → 0.5.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/dist/index.d.cts CHANGED
@@ -26,6 +26,28 @@ interface AggregateTerm {
26
26
  /** The result alias. */
27
27
  readonly alias: string;
28
28
  }
29
+ /**
30
+ * A row-level locking clause (`SELECT ... FOR UPDATE`).
31
+ *
32
+ * `wait` decides what happens when another transaction already holds the lock:
33
+ * `"block"` waits, `"skipLocked"` skips those rows (the job-queue claim), and
34
+ * `"noWait"` fails immediately.
35
+ */
36
+ interface LockClause {
37
+ readonly strength: "update" | "share";
38
+ readonly wait: "block" | "skipLocked" | "noWait";
39
+ /** Tables to lock (`FOR UPDATE OF t`); empty locks every table in the query. */
40
+ readonly of: readonly string[];
41
+ }
42
+ /** Options accepted by {@link SelectBuilder.forUpdate} / {@link SelectBuilder.forShare}. */
43
+ interface LockOptions {
44
+ /** Skip rows another transaction has locked instead of waiting for them. */
45
+ readonly skipLocked?: boolean;
46
+ /** Fail immediately instead of waiting for a locked row. */
47
+ readonly noWait?: boolean;
48
+ /** Restrict the lock to these tables (`FOR UPDATE OF ...`). */
49
+ readonly of?: readonly string[];
50
+ }
29
51
  /** Serializable AST for a SELECT. Dialects (Phase 4) compile this to SQL. */
30
52
  interface SelectNode {
31
53
  readonly kind: "select";
@@ -42,6 +64,10 @@ interface SelectNode {
42
64
  readonly orderBy: readonly OrderTerm[];
43
65
  readonly limit: number | undefined;
44
66
  readonly offset: number | undefined;
67
+ /** Row-level locking clause, or `undefined` for none. */
68
+ readonly lock?: LockClause | undefined;
69
+ /** Property → column map, or `undefined` when every name is the identity. */
70
+ readonly names?: NameMap | undefined;
45
71
  }
46
72
  /** Operators valid on every column type. */
47
73
  interface BaseOperators<T> {
@@ -71,19 +97,41 @@ interface OrderedOperators<T> extends BaseOperators<T> {
71
97
  }
72
98
  /** Extra operators for string-like types. */
73
99
  interface StringOperators<T> extends BaseOperators<T> {
74
- /** `LIKE` pattern (case-sensitive). */
100
+ /** `LIKE` pattern (case-sensitive). `%` and `_` are wildcards. */
75
101
  like?: string;
76
- /** `ILIKE` pattern (case-insensitive). */
102
+ /**
103
+ * `ILIKE` **pattern** (case-insensitive). This is pattern matching, not
104
+ * equality: `%` and `_` in the operand are wildcards, so `{ ilike: "%" }`
105
+ * matches every row. Never feed it unescaped user input — for a
106
+ * case-insensitive *equality* test use {@link StringOperators.ieq}, and to
107
+ * match a literal that may contain wildcards, wrap it in `escapeLike`.
108
+ */
77
109
  ilike?: string;
110
+ /**
111
+ * Case-insensitive equality — compiles to `lower(col) = lower($1)`, with no
112
+ * wildcards. The safe operator for a case-insensitive lookup (login, email),
113
+ * and the one that matches a `lower(col)` functional index.
114
+ */
115
+ ieq?: T;
116
+ }
117
+ /** Extra operators for array columns (PostgreSQL). */
118
+ interface ArrayOperators<T> extends BaseOperators<T> {
119
+ /** `@>` — the column contains every element of the operand. */
120
+ contains?: T;
121
+ /** `<@` — every element of the column is in the operand. */
122
+ containedBy?: T;
123
+ /** `&&` — the column and the operand share at least one element. */
124
+ overlaps?: T;
78
125
  }
79
126
  /**
80
127
  * The operator object allowed for a column of (non-null) type `T`:
81
- * - `string` → equality, `in`, `like`/`ilike`
128
+ * - `T[]` → equality, `in`, `contains`/`containedBy`/`overlaps` (PostgreSQL)
129
+ * - `string` → equality, `in`, `like`/`ilike`/`ieq`
82
130
  * - `number` / `bigint` / `Date` → equality, `in`, ordered comparisons, `between`
83
131
  * - `boolean` → equality, `isNull`
84
132
  * - anything else (json/blob) → equality and `in` only
85
133
  */
86
- type OperatorsFor<T> = [T] extends [string] ? StringOperators<T> : [T] extends [number] ? OrderedOperators<T> : [T] extends [bigint] ? OrderedOperators<T> : [T] extends [Date] ? OrderedOperators<T> : [T] extends [boolean] ? BaseOperators<T> : BaseOperators<T>;
134
+ type OperatorsFor<T> = [T] extends [readonly unknown[]] ? ArrayOperators<T> : [T] extends [string] ? StringOperators<T> : [T] extends [number] ? OrderedOperators<T> : [T] extends [bigint] ? OrderedOperators<T> : [T] extends [Date] ? OrderedOperators<T> : [T] extends [boolean] ? BaseOperators<T> : BaseOperators<T>;
87
135
  /**
88
136
  * `where` shape: each key must be a real column; each value accepts either a
89
137
  * bare value (shorthand for `eq`) or an operator object restricted to operators
@@ -94,7 +142,7 @@ type WhereInput<Row = Record<string, unknown>> = {
94
142
  [K in keyof Row]?: Row[K] | OperatorsFor<NonNullable<Row[K]>>;
95
143
  };
96
144
  /** The full set of operator keys, for the dialect compiler to recognize. */
97
- declare const OPERATORS: readonly ["eq", "ne", "gt", "gte", "lt", "lte", "like", "ilike", "in", "notIn", "between", "isNull"];
145
+ declare const OPERATORS: readonly ["eq", "ne", "gt", "gte", "lt", "lte", "like", "ilike", "ieq", "in", "notIn", "between", "isNull", "contains", "containedBy", "overlaps"];
98
146
  /** One supported operator name. */
99
147
  type Operator = (typeof OPERATORS)[number];
100
148
  /** An aggregate expression carrying its result type `T` as a phantom. */
@@ -165,6 +213,44 @@ declare class SelectBuilder<Full, Proj = Full> {
165
213
  limit(n: number): SelectBuilder<Full, Proj>;
166
214
  /** Skip the first `n` rows. */
167
215
  offset(n: number): SelectBuilder<Full, Proj>;
216
+ /**
217
+ * Lock the selected rows for update (`SELECT ... FOR UPDATE`), à la
218
+ * SQLAlchemy's `with_for_update()`.
219
+ *
220
+ * `{ skipLocked: true }` is the job-queue claim: competing workers each take a
221
+ * disjoint batch instead of blocking on — or worse, double-processing — the
222
+ * same rows.
223
+ *
224
+ * PostgreSQL and MySQL 8.0+ only. SQLite has no row-level locking, and its
225
+ * dialect throws rather than emitting a `SELECT` that silently locks nothing —
226
+ * a lock that does not exist only fails under production concurrency.
227
+ *
228
+ * @param options `skipLocked` / `noWait` wait behavior, and `of` to restrict
229
+ * the lock to specific tables.
230
+ * @returns A builder carrying the locking clause.
231
+ * @throws Error When both `skipLocked` and `noWait` are set.
232
+ *
233
+ * @example
234
+ * ```ts
235
+ * const batch = await session.execute(
236
+ * select(Outbound)
237
+ * .where({ status: "queued" })
238
+ * .orderBy("nextAttemptAt")
239
+ * .limit(10)
240
+ * .forUpdate({ skipLocked: true }),
241
+ * ).all();
242
+ * ```
243
+ */
244
+ forUpdate(options?: LockOptions): SelectBuilder<Full, Proj>;
245
+ /**
246
+ * Take a shared read lock on the selected rows (`SELECT ... FOR SHARE`), the
247
+ * weaker counterpart of {@link SelectBuilder.forUpdate}.
248
+ *
249
+ * @param options `skipLocked` / `noWait` wait behavior, and `of` tables.
250
+ * @returns A builder carrying the locking clause.
251
+ * @throws Error When both `skipLocked` and `noWait` are set.
252
+ */
253
+ forShare(options?: LockOptions): SelectBuilder<Full, Proj>;
168
254
  }
169
255
  /** Build a SELECT over every column of the model. */
170
256
  declare function select<C extends ModelClass>(model: C): SelectBuilder<InferModel<C>, InferModel<C>>;
@@ -235,6 +321,19 @@ declare function not<Row = Record<string, unknown>>(input: WhereArg<NoInfer<Row>
235
321
 
236
322
  /** Columns to return from a mutation, or "*" for the whole row. */
237
323
  type Returning = readonly string[] | "*" | null;
324
+ /**
325
+ * A write shape over `Row`: every column accepts its own value **or** a
326
+ * {@link SqlExpression}, which the dialect renders inline instead of binding.
327
+ * Optionality is preserved from `Row`, so an insert shape keeps its defaults
328
+ * optional.
329
+ */
330
+ type WriteValues<Row> = {
331
+ [K in keyof Row]: Row[K] | SqlExpression;
332
+ };
333
+ /** A partial write shape — the `SET` clause of an UPDATE or a `DO UPDATE`. */
334
+ type WritePatch<Row> = {
335
+ [K in keyof Row]?: Row[K] | SqlExpression;
336
+ };
238
337
  /**
239
338
  * Conflict-resolution clause for an INSERT (`ON CONFLICT`). `target` is the
240
339
  * conflicting column(s) (a unique/PK constraint); `update` is `"nothing"` for
@@ -243,6 +342,28 @@ type Returning = readonly string[] | "*" | null;
243
342
  interface OnConflict {
244
343
  readonly target: readonly string[];
245
344
  readonly update: Record<string, unknown> | "nothing";
345
+ /**
346
+ * The predicate of a **partial** unique index. PostgreSQL only matches a
347
+ * partial index as a conflict target when `ON CONFLICT` repeats its predicate,
348
+ * so without this an insert against `... WHERE key IS NOT NULL` is rejected
349
+ * with "there is no unique or exclusion constraint matching the ON CONFLICT
350
+ * specification".
351
+ */
352
+ readonly targetWhere?: CondNode | undefined;
353
+ /** Extra condition restricting which conflicting rows `DO UPDATE` rewrites. */
354
+ readonly updateWhere?: CondNode | undefined;
355
+ }
356
+ /** Options for the `ON CONFLICT` clause of {@link InsertBuilder.onConflictDoNothing}. */
357
+ interface OnConflictOptions<Full> {
358
+ /** The predicate of the partial unique index used as the conflict target. */
359
+ readonly where?: WhereInput<Full> | Condition;
360
+ }
361
+ /** Options for {@link InsertBuilder.onConflictDoUpdate}. */
362
+ interface OnConflictUpdateOptions<Full> {
363
+ /** The predicate of the partial unique index used as the conflict target. */
364
+ readonly indexWhere?: WhereInput<Full> | Condition;
365
+ /** Extra condition deciding which conflicting rows are actually rewritten. */
366
+ readonly updateWhere?: WhereInput<Full> | Condition;
246
367
  }
247
368
  /** Serializable AST for an INSERT. */
248
369
  interface InsertNode {
@@ -252,6 +373,8 @@ interface InsertNode {
252
373
  readonly returning: Returning;
253
374
  /** Conflict handling (`ON CONFLICT ...`), or `undefined` for none. */
254
375
  readonly onConflict?: OnConflict;
376
+ /** Property → column map, or `undefined` when every name is the identity. */
377
+ readonly names?: NameMap | undefined;
255
378
  }
256
379
  /**
257
380
  * INSERT builder.
@@ -269,21 +392,46 @@ declare class InsertBuilder<Full, Ins, Ret = number> {
269
392
  /** The source model, used to coerce returned rows on execution. */
270
393
  source: ModelClass);
271
394
  private with;
272
- /** Provide one row or many rows to insert, typed by the insert shape. */
273
- values(rows: Ins | readonly Ins[]): InsertBuilder<Full, Ins, Ret>;
395
+ /**
396
+ * Provide one row or many rows to insert, typed by the insert shape.
397
+ *
398
+ * @param rows One row, or an array of rows.
399
+ * @returns A builder carrying the rows.
400
+ * @throws ValidationError When a value is not a column value the dialect can
401
+ * bind (see the `sql` helpers for writing an expression instead).
402
+ */
403
+ values(rows: WriteValues<Ins> | readonly WriteValues<Ins>[]): InsertBuilder<Full, Ins, Ret>;
274
404
  /**
275
405
  * On a unique/PK conflict on `target`, do nothing (skip the row).
276
406
  *
277
407
  * @param target The conflicting column(s) — a unique or primary key.
408
+ * @param options Pass `where` to name the predicate of a **partial** unique
409
+ * index, which PostgreSQL requires in order to match it as a conflict target.
410
+ * @returns A builder carrying the conflict clause.
411
+ *
412
+ * @example
413
+ * ```ts
414
+ * insert(Outbound)
415
+ * .values(data)
416
+ * .onConflictDoNothing(["consumer", "idempotencyKey"], {
417
+ * where: { idempotencyKey: { isNull: false } },
418
+ * })
419
+ * .returning();
420
+ * ```
278
421
  */
279
- onConflictDoNothing(target: readonly (keyof Full & string)[]): InsertBuilder<Full, Ins, Ret>;
422
+ onConflictDoNothing(target: readonly (keyof Full & string)[], options?: OnConflictOptions<Full>): InsertBuilder<Full, Ins, Ret>;
280
423
  /**
281
424
  * On a unique/PK conflict on `target`, overwrite the given columns (upsert).
282
425
  *
283
426
  * @param target The conflicting column(s) — a unique or primary key.
284
427
  * @param set The columns to update with new values.
428
+ * @param options `indexWhere` names the predicate of a partial unique index
429
+ * (the conflict target); `updateWhere` further restricts which conflicting
430
+ * rows are rewritten.
431
+ * @returns A builder carrying the conflict clause.
432
+ * @throws ValidationError When a `set` value cannot be bound.
285
433
  */
286
- onConflictDoUpdate(target: readonly (keyof Full & string)[], set: Partial<Full>): InsertBuilder<Full, Ins, Ret>;
434
+ onConflictDoUpdate(target: readonly (keyof Full & string)[], set: WritePatch<Full>, options?: OnConflictUpdateOptions<Full>): InsertBuilder<Full, Ins, Ret>;
287
435
  /** Return the full inserted row(s). */
288
436
  returning(): InsertBuilder<Full, Ins, Full>;
289
437
  /** Return only the given columns of the inserted row(s). */
@@ -300,6 +448,8 @@ interface UpdateNode {
300
448
  /** True once a where-clause or explicit opt-in makes the write safe. */
301
449
  readonly guarded: boolean;
302
450
  readonly returning: Returning;
451
+ /** Property → column map, or `undefined` when every name is the identity. */
452
+ readonly names?: NameMap | undefined;
303
453
  }
304
454
  /**
305
455
  * UPDATE builder.
@@ -318,8 +468,26 @@ declare class UpdateBuilder<Full, Guarded extends boolean, Ret = number> {
318
468
  /** The source model, used to coerce returned rows on execution. */
319
469
  source: ModelClass);
320
470
  private with;
321
- /** The columns to write. Partial — only the given columns change. */
322
- set(values: Partial<Full>): UpdateBuilder<Full, Guarded, Ret>;
471
+ /**
472
+ * The columns to write. Partial only the given columns change.
473
+ *
474
+ * A value is bound as a parameter unless it is a {@link sql} expression, which
475
+ * is rendered inline instead — that is how a counter is written without a
476
+ * read-modify-write race.
477
+ *
478
+ * @param values The column → value map.
479
+ * @returns A builder carrying the assignments.
480
+ * @throws ValidationError When a value is not a column value the dialect can
481
+ * bind (a bare object, an array on a scalar column, a function).
482
+ *
483
+ * @example
484
+ * ```ts
485
+ * update(Outbound)
486
+ * .set({ attempts: sql.raw("attempts + 1"), updatedAt: sql.now() })
487
+ * .where({ id });
488
+ * ```
489
+ */
490
+ set(values: WritePatch<Full>): UpdateBuilder<Full, Guarded, Ret>;
323
491
  /** Restrict the rows to update. Marks the builder safe to execute. */
324
492
  where(input: WhereInput<Full> | Condition): UpdateBuilder<Full, true, Ret>;
325
493
  /** Explicit opt-in to update EVERY row. Use deliberately. */
@@ -338,6 +506,8 @@ interface DeleteNode {
338
506
  readonly where: CondNode | undefined;
339
507
  readonly guarded: boolean;
340
508
  readonly returning: Returning;
509
+ /** Property → column map, or `undefined` when every name is the identity. */
510
+ readonly names?: NameMap | undefined;
341
511
  }
342
512
  /**
343
513
  * DELETE builder. Starts unguarded — same safety rule as UPDATE.
@@ -532,6 +702,8 @@ interface JoinNode {
532
702
  }[];
533
703
  readonly limit: number | undefined;
534
704
  readonly offset: number | undefined;
705
+ /** Per-alias property → column maps, for the sources that rename columns. */
706
+ readonly names?: Readonly<Record<string, NameMap>> | undefined;
535
707
  }
536
708
  /** A map of source alias → its (possibly nullable) row type. */
537
709
  type Sources = Record<string, object | null>;
@@ -605,6 +777,16 @@ interface CompiledQuery {
605
777
  }
606
778
  /** Any compilable AST node. */
607
779
  type QueryNode = SelectNode | InsertNode | UpdateNode | DeleteNode | JoinNode;
780
+ /**
781
+ * Collects bound parameters and renders placeholders in dialect style. Exposed
782
+ * because dialect subclasses receive it when overriding clause rendering.
783
+ */
784
+ declare class Params {
785
+ private readonly placeholder;
786
+ readonly values: unknown[];
787
+ constructor(placeholder: (index: number) => string);
788
+ bind(value: unknown): string;
789
+ }
608
790
  /**
609
791
  * Base SQL compiler shared by every dialect. Subclasses customize only what
610
792
  * actually differs between databases (placeholder syntax, `ILIKE` support).
@@ -623,6 +805,17 @@ declare abstract class BaseDialect {
623
805
  protected abstract placeholder(index: number): string;
624
806
  /** Render a case-insensitive LIKE for the active dialect. */
625
807
  protected abstract ilike(column: string, param: string): string;
808
+ /**
809
+ * The SQL operator for an array containment/overlap test.
810
+ *
811
+ * Only PostgreSQL has native arrays; the other dialects throw rather than
812
+ * emitting an operator that means something else there.
813
+ *
814
+ * @param op The array operator name.
815
+ * @returns The SQL operator text.
816
+ * @throws Error On a dialect without native array support.
817
+ */
818
+ protected arrayOperator(op: "contains" | "containedBy" | "overlaps"): string;
626
819
  /**
627
820
  * Quote an identifier (column/table) for the active dialect.
628
821
  *
@@ -634,10 +827,70 @@ declare abstract class BaseDialect {
634
827
  protected quoteId(name: string): string;
635
828
  /** Compile any node to `{ sql, params }`. */
636
829
  compile(node: QueryNode): CompiledQuery;
637
- /** Render a qualified `alias.column` ref as `"alias"."column"`. */
830
+ /**
831
+ * Render a qualified `alias.column` ref as `"alias"."column"`, translating the
832
+ * property name to the real column name for that alias's model.
833
+ *
834
+ * @param ref The `alias.property` reference (a bare name is left unqualified).
835
+ * @param names The node's per-alias name maps, if any source renames columns.
836
+ * @returns The quoted, qualified identifier.
837
+ */
638
838
  private qualify;
839
+ /**
840
+ * Quote a column identifier, translating the model property name to the real
841
+ * database column name first.
842
+ *
843
+ * `names` is `undefined` for a model that renames nothing — the overwhelmingly
844
+ * common case — so this stays a single lookup plus the memoized quote.
845
+ *
846
+ * @param prop The model property name as written in the builder.
847
+ * @param names The node's property → column map, if any.
848
+ * @returns The quoted database identifier.
849
+ */
850
+ protected columnId(prop: string, names: NameMap | undefined): string;
851
+ /**
852
+ * Render a {@link SqlExpression} inline, binding the parameters it carries.
853
+ *
854
+ * This is what keeps `set({ attempts: sql.raw("attempts + 1") })` an expression
855
+ * instead of a bound object: the fragment goes into the statement text, and
856
+ * only a `sql.expr` template's interpolations become parameters.
857
+ *
858
+ * @param expr The branded expression.
859
+ * @param params The parameter collector for the statement being compiled.
860
+ * @returns The SQL text of the expression.
861
+ */
862
+ protected renderExpression(expr: SqlExpression, params: Params): string;
863
+ /** Render one write value: a SQL expression inline, anything else as a parameter. */
864
+ protected renderValue(value: unknown, params: Params): string;
865
+ /**
866
+ * Render a row-level locking clause (`FOR UPDATE ...`).
867
+ *
868
+ * Standard on PostgreSQL and MySQL 8.0+; SQLite overrides it to throw.
869
+ *
870
+ * @param lock The locking clause from the node.
871
+ * @returns The SQL text, leading space included.
872
+ */
873
+ protected renderLock(lock: LockClause): string;
639
874
  private compileSelect;
875
+ /**
876
+ * Compile an INSERT.
877
+ *
878
+ * Takes the cached fast path only when the statement text is a pure function of
879
+ * its structure. A SQL expression among the values, or a conflict predicate,
880
+ * makes the text depend on the values themselves — those compile uncached, in
881
+ * SQL order, so placeholder positions stay correct.
882
+ */
640
883
  private compileInsert;
884
+ /**
885
+ * Compile an INSERT without the template cache, rendering clauses in statement
886
+ * order so every parameter is bound at the position it appears.
887
+ *
888
+ * @param node The insert node.
889
+ * @param columns The column keys shared by every row.
890
+ * @param params The parameter collector.
891
+ * @returns The SQL text.
892
+ */
893
+ private compileInsertDirect;
641
894
  /**
642
895
  * The INSERT SQL template for a given structure, cached across calls.
643
896
  *
@@ -649,17 +902,24 @@ declare abstract class BaseDialect {
649
902
  private insertTemplate;
650
903
  /**
651
904
  * Render the conflict-handling clause. Standard SQL (SQLite/PostgreSQL) uses
652
- * `ON CONFLICT (...) DO NOTHING | DO UPDATE SET ...`; MySQL overrides this.
905
+ * `ON CONFLICT (...) [WHERE predicate] DO NOTHING | DO UPDATE SET ... [WHERE ...]`;
906
+ * MySQL overrides this.
907
+ *
908
+ * The index predicate is rendered before the `DO UPDATE` assignments because
909
+ * that is where it sits in the statement, so its parameters bind first.
653
910
  *
654
911
  * @param onConflict The conflict clause from the node.
655
912
  * @param conflictCols The columns to overwrite on `DO UPDATE` (empty for nothing).
656
- * @param nextPlaceholder Yields the next positional placeholder (advances the count).
913
+ * @param nextValue Yields the SQL for the next `DO UPDATE` assignment value.
914
+ * @param names The node's property → column map, if any.
915
+ * @param params The parameter collector, for the predicates.
916
+ * @returns The SQL text, leading space included.
657
917
  */
658
- protected renderConflict(onConflict: NonNullable<InsertNode["onConflict"]>, conflictCols: readonly string[], nextPlaceholder: () => string): string;
918
+ protected renderConflict(onConflict: NonNullable<InsertNode["onConflict"]>, conflictCols: readonly string[], nextValue: () => string, names: NameMap | undefined, params: Params): string;
659
919
  private compileUpdate;
660
920
  private compileDelete;
661
921
  private compileJoin;
662
- protected compileReturning(returning: readonly string[] | "*" | null): string;
922
+ protected compileReturning(returning: readonly string[] | "*" | null, names?: NameMap | undefined): string;
663
923
  /**
664
924
  * Compile a condition tree (fields / and / or / not) to SQL. `idFor` renders a
665
925
  * key to a quoted identifier — `quoteId` for single-table, `qualify` for joins —
@@ -674,12 +934,19 @@ declare class SqliteDialect extends BaseDialect {
674
934
  readonly name: "sqlite";
675
935
  protected placeholder(): string;
676
936
  protected ilike(column: string, param: string): string;
937
+ /**
938
+ * SQLite has no row-level locking, so a lock request is an error rather than a
939
+ * silently unlocked `SELECT` — a lock that does not exist only shows up as
940
+ * duplicated work under production concurrency.
941
+ */
942
+ protected renderLock(): string;
677
943
  }
678
- /** PostgreSQL dialect: `$1` placeholders; native `ILIKE`. */
944
+ /** PostgreSQL dialect: `$1` placeholders; native `ILIKE`; native array operators. */
679
945
  declare class PostgresDialect extends BaseDialect {
680
946
  readonly name: "postgresql";
681
947
  protected placeholder(index: number): string;
682
948
  protected ilike(column: string, param: string): string;
949
+ protected arrayOperator(op: "contains" | "containedBy" | "overlaps"): string;
683
950
  }
684
951
  /**
685
952
  * MySQL dialect: `?` placeholders, backtick identifiers, `ON DUPLICATE KEY
@@ -691,7 +958,7 @@ declare class MysqlDialect extends BaseDialect {
691
958
  protected placeholder(): string;
692
959
  protected ilike(column: string, param: string): string;
693
960
  protected quoteId(name: string): string;
694
- protected renderConflict(onConflict: NonNullable<InsertNode["onConflict"]>, conflictCols: readonly string[], nextPlaceholder: () => string): string;
961
+ protected renderConflict(onConflict: NonNullable<InsertNode["onConflict"]>, conflictCols: readonly string[], nextValue: () => string, names: NameMap | undefined): string;
695
962
  protected compileReturning(returning: readonly string[] | "*" | null): string;
696
963
  }
697
964
  /** Get a dialect instance by name. */
@@ -832,6 +1099,40 @@ declare class SyncSession {
832
1099
  logger?: QueryLogger | undefined);
833
1100
  /** Log, run, and error-wrap one raw statement. */
834
1101
  private exec;
1102
+ /**
1103
+ * Run a raw, parameterized SQL statement (synchronous) — the runtime counterpart of the
1104
+ * migrations' `Op.execute`.
1105
+ *
1106
+ * A query builder never covers all of SQL, and without an escape hatch a single
1107
+ * unsupported query forces a whole second database stack alongside this one. Use
1108
+ * it for what the builder cannot yet express, and keep everything else typed.
1109
+ *
1110
+ * The statement goes through the same path as a compiled one: it is logged via
1111
+ * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the
1112
+ * reserved connection inside `transaction()`.
1113
+ *
1114
+ * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —
1115
+ * never interpolate a value into this string.
1116
+ * @param params The bound parameters, in placeholder order.
1117
+ * @param options Pass `as` to coerce the returned rows with a model's column
1118
+ * types (and its column-name mapping).
1119
+ * @returns The result view over the returned rows.
1120
+ * @throws Error When `params` is not an array — the guard against calling this
1121
+ * with an interpolated string and no parameters by mistake.
1122
+ *
1123
+ * @example
1124
+ * ```ts
1125
+ * const claimed = await session.raw<OutboundRow>(
1126
+ * `UPDATE outbound_messages SET status = 'sending'
1127
+ * WHERE id = ANY($1) RETURNING *`,
1128
+ * [ids],
1129
+ * { as: Outbound },
1130
+ * ).all();
1131
+ * ```
1132
+ */
1133
+ raw<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[], options?: {
1134
+ readonly as?: ModelClass;
1135
+ }): SyncResult<Row>;
835
1136
  /** Compile, run, and coerce a builder into a result. */
836
1137
  execute<B extends Executable>(builder: B): SyncResult<RowOf<B>>;
837
1138
  /** Run `fn` inside a transaction: commit on success, rollback on throw. */
@@ -858,6 +1159,40 @@ declare class AsyncSession {
858
1159
  logger?: QueryLogger | undefined);
859
1160
  /** Log, run, and error-wrap one raw statement. */
860
1161
  private exec;
1162
+ /**
1163
+ * Run a raw, parameterized SQL statement — the runtime counterpart of the
1164
+ * migrations' `Op.execute`.
1165
+ *
1166
+ * A query builder never covers all of SQL, and without an escape hatch a single
1167
+ * unsupported query forces a whole second database stack alongside this one. Use
1168
+ * it for what the builder cannot yet express, and keep everything else typed.
1169
+ *
1170
+ * The statement goes through the same path as a compiled one: it is logged via
1171
+ * `onQuery`, wrapped in {@link QueryExecutionError} on failure, and runs on the
1172
+ * reserved connection inside `transaction()`.
1173
+ *
1174
+ * @param sql The statement text. Placeholders only (`$1` / `?` per dialect) —
1175
+ * never interpolate a value into this string.
1176
+ * @param params The bound parameters, in placeholder order.
1177
+ * @param options Pass `as` to coerce the returned rows with a model's column
1178
+ * types (and its column-name mapping).
1179
+ * @returns The result view over the returned rows.
1180
+ * @throws Error When `params` is not an array — the guard against calling this
1181
+ * with an interpolated string and no parameters by mistake.
1182
+ *
1183
+ * @example
1184
+ * ```ts
1185
+ * const claimed = await session.raw<OutboundRow>(
1186
+ * `UPDATE outbound_messages SET status = 'sending'
1187
+ * WHERE id = ANY($1) RETURNING *`,
1188
+ * [ids],
1189
+ * { as: Outbound },
1190
+ * ).all();
1191
+ * ```
1192
+ */
1193
+ raw<Row = Record<string, unknown>>(sql: string, params?: readonly unknown[], options?: {
1194
+ readonly as?: ModelClass;
1195
+ }): AsyncResult<Row>;
861
1196
  execute<B extends Executable>(builder: B): AsyncResult<RowOf<B>>;
862
1197
  /** Lazily iterate result rows. Uses driver streaming when available. */
863
1198
  stream<B extends Executable>(builder: B): AsyncIterableIterator<RowOf<B>>;
@@ -1168,7 +1503,7 @@ interface ColumnFlags {
1168
1503
  * generic types (e.g. `String` → varchar, `Text` → text). Dialect renderers
1169
1504
  * (Phase 4/6) map each kind + meta to concrete SQL per database.
1170
1505
  */
1171
- type ColumnTypeKind = "smallint" | "integer" | "bigint" | "numeric" | "real" | "double" | "varchar" | "text" | "char" | "boolean" | "date" | "time" | "datetime" | "timestamp" | "blob" | "json" | "uuid" | "enum";
1506
+ type ColumnTypeKind = "smallint" | "integer" | "bigint" | "numeric" | "real" | "double" | "varchar" | "text" | "char" | "boolean" | "date" | "time" | "datetime" | "timestamp" | "blob" | "json" | "uuid" | "enum" | "array";
1172
1507
  /** Parameters that refine a column type and feed the migration IR / DDL. */
1173
1508
  interface ColumnTypeMeta {
1174
1509
  /** Max length for `varchar`/`char`. */
@@ -1183,6 +1518,8 @@ interface ColumnTypeMeta {
1183
1518
  readonly values?: readonly string[] | undefined;
1184
1519
  /** Render as `JSONB` (PostgreSQL) instead of `JSON`. */
1185
1520
  readonly jsonb?: boolean | undefined;
1521
+ /** The element type of an `array` column (`text[]`, `integer[]`). */
1522
+ readonly element?: ColumnType | undefined;
1186
1523
  }
1187
1524
  /** A structured, dialect-neutral column type descriptor. */
1188
1525
  interface ColumnType {
@@ -1193,10 +1530,14 @@ interface ColumnType {
1193
1530
  * A portable default expression. The token is dialect-neutral; the renderer
1194
1531
  * (Phase 4/6) maps it to the right SQL per database — e.g. `"now"` becomes
1195
1532
  * `CURRENT_TIMESTAMP` on SQLite and `now()` on PostgreSQL. Use `{ raw }` as an
1196
- * escape hatch for a verbatim SQL fragment.
1533
+ * escape hatch for a verbatim SQL fragment, or `{ parts }` for a parameterized
1534
+ * fragment built by the `sql.expr` tagged template (one bound parameter per gap
1535
+ * between consecutive parts).
1197
1536
  */
1198
1537
  type PortableExpression = "now" | "current_date" | "current_time" | "uuidv4" | {
1199
1538
  readonly raw: string;
1539
+ } | {
1540
+ readonly parts: readonly string[];
1200
1541
  };
1201
1542
  /**
1202
1543
  * A column default. Either a constant literal value or a server-side expression
@@ -1210,18 +1551,79 @@ type DefaultValue = {
1210
1551
  readonly kind: "expression";
1211
1552
  readonly expression: PortableExpression;
1212
1553
  };
1213
- /** Portable server-side default expressions, à la SQLAlchemy's `func`. */
1554
+ /**
1555
+ * Brand marking a value as a SQL expression rather than a bound parameter.
1556
+ *
1557
+ * A plain object reaching `set()`/`values()` is a mistake (it would be bound as a
1558
+ * parameter and silently written as JSON or null); an object carrying this symbol
1559
+ * is deliberate, and the dialect renders it inline instead of binding it. Mirrors
1560
+ * how `Condition` is branded, so the check is a symbol lookup, not duck typing.
1561
+ */
1562
+ declare const EXPRESSION: unique symbol;
1563
+ /**
1564
+ * A SQL expression, usable both as a column default (`.default(sql.now())`) and
1565
+ * as a write value (`.set({ attempts: sql.raw("attempts + 1") })`). The dialect
1566
+ * renders `expression` inline and binds `params` in the order of the fragment's
1567
+ * gaps.
1568
+ */
1569
+ interface SqlExpression {
1570
+ readonly [EXPRESSION]: true;
1571
+ readonly kind: "expression";
1572
+ readonly expression: PortableExpression;
1573
+ /** Parameters bound into the fragment's gaps, in order (empty for a token). */
1574
+ readonly params: readonly unknown[];
1575
+ }
1576
+ /**
1577
+ * Runtime guard: is this value a branded {@link SqlExpression}?
1578
+ *
1579
+ * @param value Any value handed to `set()`, `values()` or `.default()`.
1580
+ * @returns True when the value carries the expression brand.
1581
+ */
1582
+ declare function isSqlExpression(value: unknown): value is SqlExpression;
1583
+ /**
1584
+ * Portable server-side expressions, à la SQLAlchemy's `func`.
1585
+ *
1586
+ * Every entry doubles as a column default and as a write value, so
1587
+ * `.default(sql.now())` and `.set({ updatedAt: sql.now() })` both work.
1588
+ */
1214
1589
  declare const sql: {
1215
1590
  /** Current timestamp at insert (`CURRENT_TIMESTAMP` / `now()`). */
1216
- readonly now: () => DefaultValue;
1591
+ readonly now: () => SqlExpression;
1217
1592
  /** Current date. */
1218
- readonly currentDate: () => DefaultValue;
1593
+ readonly currentDate: () => SqlExpression;
1219
1594
  /** Current time. */
1220
- readonly currentTime: () => DefaultValue;
1595
+ readonly currentTime: () => SqlExpression;
1221
1596
  /** A freshly generated UUID v4 (`gen_random_uuid()` / portable fallback). */
1222
- readonly uuidv4: () => DefaultValue;
1223
- /** Escape hatch: a verbatim SQL expression rendered as-is. */
1224
- readonly raw: (expression: string) => DefaultValue;
1597
+ readonly uuidv4: () => SqlExpression;
1598
+ /**
1599
+ * Escape hatch: a verbatim SQL expression rendered as-is, with no parameters.
1600
+ *
1601
+ * The fragment is interpolated into the statement untouched, so it must never
1602
+ * carry user input — use {@link sql.expr} when a value has to be bound.
1603
+ *
1604
+ * @param fragment The SQL text (e.g. `"attempts + 1"`).
1605
+ * @returns The expression, usable as a default and as a write value.
1606
+ */
1607
+ readonly raw: (fragment: string) => SqlExpression;
1608
+ /**
1609
+ * A parameterized SQL expression, written as a tagged template. Static text is
1610
+ * SQL; every `${...}` interpolation becomes a bound parameter, so the fragment
1611
+ * is injection-safe by construction.
1612
+ *
1613
+ * Cannot be used as a column default — a `DEFAULT` clause has nowhere to bind
1614
+ * parameters; use {@link sql.raw} there.
1615
+ *
1616
+ * @param parts The static SQL segments supplied by the template tag.
1617
+ * @param values The interpolated values, bound in order.
1618
+ * @returns The expression, usable as a write value.
1619
+ *
1620
+ * @example
1621
+ * ```ts
1622
+ * update(Account).set({ balance: sql.expr`balance - ${amount}` }).where({ id });
1623
+ * // UPDATE "accounts" SET "balance" = balance - $1 WHERE "id" = $2
1624
+ * ```
1625
+ */
1626
+ readonly expr: (parts: TemplateStringsArray, ...values: unknown[]) => SqlExpression;
1225
1627
  };
1226
1628
  /**
1227
1629
  * A referential action for a foreign key's `ON DELETE` / `ON UPDATE` clause.
@@ -1258,6 +1660,8 @@ declare class Column<T, F extends ColumnFlags = ColumnFlags> {
1258
1660
  readonly onUpdateValue: DefaultValue | null;
1259
1661
  /** The foreign-key reference this column points to, or `null` for none. */
1260
1662
  readonly reference: ForeignKeyRef | null;
1663
+ /** An explicit database column name overriding the property name, or `null`. */
1664
+ readonly dbName: string | null;
1261
1665
  /** Phantom: never read at runtime, only inspected by the type system. */
1262
1666
  readonly [TYPE]: T;
1263
1667
  constructor(type: ColumnType, flags: F,
@@ -1266,7 +1670,11 @@ declare class Column<T, F extends ColumnFlags = ColumnFlags> {
1266
1670
  /** The value re-applied on update (e.g. `updated_at`), or `null`. */
1267
1671
  onUpdateValue?: DefaultValue | null,
1268
1672
  /** The foreign-key reference this column points to, or `null` for none. */
1269
- reference?: ForeignKeyRef | null);
1673
+ reference?: ForeignKeyRef | null,
1674
+ /** An explicit database column name overriding the property name, or `null`. */
1675
+ dbName?: string | null);
1676
+ /** Clone this column with one facet replaced, carrying every other over. */
1677
+ private derive;
1270
1678
  primaryKey(): Column<T, F & {
1271
1679
  primaryKey: true;
1272
1680
  hasDefault: true;
@@ -1281,6 +1689,29 @@ declare class Column<T, F extends ColumnFlags = ColumnFlags> {
1281
1689
  unique(): Column<T, F & {
1282
1690
  unique: true;
1283
1691
  }>;
1692
+ /**
1693
+ * Map this property to a differently-named database column, à la SQLAlchemy's
1694
+ * `mapped_column("consumer_name")` (Django's `db_column`, Prisma's `@map`).
1695
+ *
1696
+ * The override applies everywhere the name reaches SQL — select, insert,
1697
+ * update, delete, where, order by, group by, returning, conflict targets, the
1698
+ * migration IR and the drift check — while the TypeScript row keeps the
1699
+ * property name. Use it to keep a `snake_case` schema behind a `camelCase`
1700
+ * model; {@link Model.naming} does the same for a whole table at once.
1701
+ *
1702
+ * @param dbName The real column name in the database.
1703
+ * @returns A new column bound to that name.
1704
+ * @throws Error When `dbName` is empty.
1705
+ *
1706
+ * @example
1707
+ * ```ts
1708
+ * class ApiKey extends Model {
1709
+ * static tablename = "api_keys";
1710
+ * consumerName = column.text().name("consumer_name").notNull();
1711
+ * }
1712
+ * ```
1713
+ */
1714
+ name(dbName: string): Column<T, F>;
1284
1715
  /**
1285
1716
  * Declare a foreign-key reference to another table's column, à la SQLAlchemy's
1286
1717
  * `mapped_column(ForeignKey("table.column", ondelete=...))`. DDL-only — does
@@ -1295,6 +1726,11 @@ declare class Column<T, F extends ColumnFlags = ColumnFlags> {
1295
1726
  /**
1296
1727
  * Set the insert-time default: a constant value of type `T`, or a portable
1297
1728
  * server-side expression from {@link sql} (e.g. `sql.now()`, `sql.uuidv4()`).
1729
+ *
1730
+ * @param value The literal default, or a {@link sql} expression.
1731
+ * @returns A new column carrying the default.
1732
+ * @throws Error When given a `sql.expr` fragment — a `DEFAULT` clause has
1733
+ * nowhere to bind parameters; use `sql.raw()` for a verbatim expression.
1298
1734
  */
1299
1735
  default(value: T | DefaultValue): Column<T, F & {
1300
1736
  hasDefault: true;
@@ -1302,6 +1738,10 @@ declare class Column<T, F extends ColumnFlags = ColumnFlags> {
1302
1738
  /**
1303
1739
  * Re-apply a value whenever the row is updated (e.g. an `updated_at` column
1304
1740
  * with `sql.now()`). Mirrors SQLAlchemy's `onupdate`.
1741
+ *
1742
+ * @param value The literal value, or a {@link sql} expression.
1743
+ * @returns A new column carrying the on-update value.
1744
+ * @throws Error When given a `sql.expr` fragment (see {@link Column.default}).
1305
1745
  */
1306
1746
  onUpdate(value: T | DefaultValue): Column<T, F>;
1307
1747
  }
@@ -1370,6 +1810,26 @@ declare const column: {
1370
1810
  readonly uuid: () => Column<string, ColumnFlags>;
1371
1811
  /** `ENUM(...values)` → a string-literal union of the given values. */
1372
1812
  readonly enum: <const E extends string>(...values: E[]) => Column<E, ColumnFlags>;
1813
+ /**
1814
+ * A PostgreSQL array column (`text[]`, `integer[]`) → `T[]`.
1815
+ *
1816
+ * PostgreSQL only: SQLite and MySQL have no native array type, and rendering
1817
+ * one as JSON there would give the same model different semantics per dialect
1818
+ * (`@>` and `&&` work on one and not the other), so the DDL renderer throws
1819
+ * for those dialects instead of falling back silently.
1820
+ *
1821
+ * @param element The element column (its type, not its flags, is what is used).
1822
+ * @returns A column whose inferred type is an array of the element's type.
1823
+ *
1824
+ * @example
1825
+ * ```ts
1826
+ * class ApiKey extends Model {
1827
+ * static tablename = "api_keys";
1828
+ * scopes = column.array(column.text()).notNull().default(["send"]);
1829
+ * }
1830
+ * ```
1831
+ */
1832
+ readonly array: <T>(element: Column<T, ColumnFlags>) => Column<T[], ColumnFlags>;
1373
1833
  };
1374
1834
  /**
1375
1835
  * A table-level constraint declared via a model's `static tableArgs`. Mirrors
@@ -1414,6 +1874,16 @@ declare function foreignKey(columns: string[], refTable: string, refColumns: str
1414
1874
  onDelete?: FkAction;
1415
1875
  onUpdate?: FkAction;
1416
1876
  }): TableConstraint;
1877
+ /**
1878
+ * How property names map to database column names when a column declares no
1879
+ * explicit {@link Column.name}.
1880
+ *
1881
+ * - `"preserve"` (default) — the column name is the property name, verbatim.
1882
+ * - `"snake_case"` — `consumerName` becomes `consumer_name`.
1883
+ */
1884
+ type NamingStrategy = "preserve" | "snake_case";
1885
+ /** Convert a `camelCase` / `PascalCase` identifier to `snake_case`. */
1886
+ declare function toSnakeCase(name: string): string;
1417
1887
  /** Base class every model extends, SQLAlchemy-declarative style. */
1418
1888
  declare abstract class Model {
1419
1889
  static tablename: string;
@@ -1423,6 +1893,12 @@ declare abstract class Model {
1423
1893
  * `__table_args__`.
1424
1894
  */
1425
1895
  static tableArgs?: () => readonly TableConstraint[];
1896
+ /**
1897
+ * How to derive column names from property names (default `"preserve"`). Set
1898
+ * `"snake_case"` to keep a `snake_case` schema behind a `camelCase` model
1899
+ * without annotating every column; {@link Column.name} overrides it per column.
1900
+ */
1901
+ static naming?: NamingStrategy;
1426
1902
  }
1427
1903
  /**
1428
1904
  * Reflect a model class into its column map at runtime, keyed by column name.
@@ -1438,6 +1914,32 @@ declare abstract class Model {
1438
1914
  * @returns A record of column name → `Column` instance (do not mutate).
1439
1915
  */
1440
1916
  declare function columnsOf(model: ModelClass): Record<string, Column<unknown>>;
1917
+ /** A mapping between property names and database column names. */
1918
+ type NameMap = Readonly<Record<string, string>>;
1919
+ /**
1920
+ * The property → database-column map for a model, or `null` when every column
1921
+ * keeps its property name.
1922
+ *
1923
+ * `null` is the common case and the fast path: builders and the row coercer skip
1924
+ * translation entirely, so a model that renames nothing costs nothing. The map
1925
+ * is memoized per class, like {@link columnsOf}.
1926
+ *
1927
+ * @param model The model class.
1928
+ * @returns The name map, or `null` when no column is renamed.
1929
+ * @throws Error When two properties resolve to the same column name.
1930
+ */
1931
+ declare function columnNamesOf(model: ModelClass): NameMap | null;
1932
+ /**
1933
+ * The database-column → property map for a model, or `null` when every column
1934
+ * keeps its property name. The inverse of {@link columnNamesOf}, used to map
1935
+ * driver rows back into property space.
1936
+ *
1937
+ * @param model The model class.
1938
+ * @returns The inverse name map, or `null` when no column is renamed.
1939
+ */
1940
+ declare function columnPropsOf(model: ModelClass): NameMap | null;
1941
+ /** Resolve one property name to its database column name. */
1942
+ declare function dbColumn(names: NameMap | null | undefined, prop: string): string;
1441
1943
  /** Pull the static type out of a Column. */
1442
1944
  type ColType<C> = C extends Column<infer T, infer _F> ? T : never;
1443
1945
  /** Keys of the model instance whose values are Columns. */
@@ -1448,6 +1950,7 @@ type ColumnKeys<M> = {
1448
1950
  type ModelClass = (new () => Model) & {
1449
1951
  tablename: string;
1450
1952
  tableArgs?: () => readonly TableConstraint[];
1953
+ naming?: NamingStrategy;
1451
1954
  };
1452
1955
  /** Flatten an intersection into a single object literal for clean inference. */
1453
1956
  type Simplify<T> = {
@@ -1485,4 +1988,4 @@ type InferInsert<C extends ModelClass> = Simplify<{
1485
1988
  [K in Exclude<ColumnKeys<InstanceType<C>>, OptionalInsertKeys<InstanceType<C>>>]: ColValue<InstanceType<C>[K]>;
1486
1989
  }>;
1487
1990
 
1488
- export { ActiveRecord, type ActiveRecordManager, Agg, type AggregateTerm, type AsyncDriver, AsyncEngine, AsyncResult, AsyncSession, BaseDialect, BaseRepository, type BelongsTo, type ColRef, type ColType, Column, type ColumnFlags, type ColumnType, type ColumnTypeKind, type ColumnTypeMeta, type CompiledQuery, type CondNode, type Condition, type DefaultValue, DeleteBuilder, type DeleteNode, type Dialect, type DriverResult, type EngineOptions, type Executable, type FkAction, type ForeignKeyOptions, type ForeignKeyRef, type HasMany, type InferInsert, type InferModel, InsertBuilder, type InsertNode, InvalidDatabaseUrl, JoinBuilder, type JoinClause, type JoinNode, type JoinOn, type JoinSelection, type JoinWhereInput, Model, type ModelClass, MysqlDialect, NoResultError, NodeSqliteDriver, OPERATORS, type OnConflict, type Operator, type OperatorsFor, type OrderTerm, type PaginationFilter, type PaginationResult, type ParsedDatabaseUrl, type PoolOptions, type PortableExpression, PostgresDialect, QueryExecutionError, type QueryLogger, type QueryNode, RecordNotFound, type Relation, type RelationValue, type ReservedAsyncDriver, type Returning, type RowOf, SelectBuilder, type SelectNode, type SortDirection, type Sources, SqliteDialect, type SyncDriver, SyncEngine, SyncResult, SyncSession, type TableConstraint, UpdateBuilder, type UpdateNode, ValidationError, type WhereArg, type WhereInput, type WithRelations, activeRecord, and, avg, belongsTo, column, columnsOf, count, createEngine, createSyncEngine, del, detectDialect, foreignKey, fromDict, getDialect, hasMany, insert, isCondition, join, loadRelations, max, min, not, or, parse, parseDatabaseUrl, select, sql, stringify, sum, toCondNode, toDict, toJSON, unique, update };
1991
+ export { ActiveRecord, type ActiveRecordManager, Agg, type AggregateTerm, type AsyncDriver, AsyncEngine, AsyncResult, AsyncSession, BaseDialect, BaseRepository, type BelongsTo, type ColRef, type ColType, Column, type ColumnFlags, type ColumnType, type ColumnTypeKind, type ColumnTypeMeta, type CompiledQuery, type CondNode, type Condition, type DefaultValue, DeleteBuilder, type DeleteNode, type Dialect, type DriverResult, type EngineOptions, type Executable, type FkAction, type ForeignKeyOptions, type ForeignKeyRef, type HasMany, type InferInsert, type InferModel, InsertBuilder, type InsertNode, InvalidDatabaseUrl, JoinBuilder, type JoinClause, type JoinNode, type JoinOn, type JoinSelection, type JoinWhereInput, type LockClause, type LockOptions, Model, type ModelClass, MysqlDialect, type NameMap, type NamingStrategy, NoResultError, NodeSqliteDriver, OPERATORS, type OnConflict, type OnConflictOptions, type OnConflictUpdateOptions, type Operator, type OperatorsFor, type OrderTerm, type PaginationFilter, type PaginationResult, Params, type ParsedDatabaseUrl, type PoolOptions, type PortableExpression, PostgresDialect, QueryExecutionError, type QueryLogger, type QueryNode, RecordNotFound, type Relation, type RelationValue, type ReservedAsyncDriver, type Returning, type RowOf, SelectBuilder, type SelectNode, type SortDirection, type Sources, type SqlExpression, SqliteDialect, type SyncDriver, SyncEngine, SyncResult, SyncSession, type TableConstraint, UpdateBuilder, type UpdateNode, ValidationError, type WhereArg, type WhereInput, type WithRelations, type WritePatch, type WriteValues, activeRecord, and, avg, belongsTo, column, columnNamesOf, columnPropsOf, columnsOf, count, createEngine, createSyncEngine, dbColumn, del, detectDialect, foreignKey, fromDict, getDialect, hasMany, insert, isCondition, isSqlExpression, join, loadRelations, max, min, not, or, parse, parseDatabaseUrl, select, sql, stringify, sum, toCondNode, toDict, toJSON, toSnakeCase, unique, update };