uql-orm 0.64.0 → 0.65.1

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 (77) hide show
  1. package/dist/bunSql/bunSqlQuerier.d.ts +3 -10
  2. package/dist/bunSql/bunSqlQuerier.js +2 -16
  3. package/dist/bunSql/bunSqlQuerierPool.d.ts +0 -2
  4. package/dist/bunSql/bunSqlQuerierPool.js +14 -16
  5. package/dist/d1/d1Querier.d.ts +13 -34
  6. package/dist/d1/d1Querier.js +1 -1
  7. package/dist/d1/d1QuerierPool.d.ts +3 -3
  8. package/dist/dialect/abstractDialect.d.ts +4 -9
  9. package/dist/dialect/abstractDialect.js +4 -5
  10. package/dist/dialect/abstractSqlDialect.d.ts +2 -2
  11. package/dist/dialect/index.d.ts +0 -1
  12. package/dist/dialect/index.js +2 -3
  13. package/dist/dialect/mysqlLikeSqlDialect.js +0 -3
  14. package/dist/dialect/pgLikeSqlDialect.d.ts +9 -1
  15. package/dist/dialect/pgLikeSqlDialect.js +8 -5
  16. package/dist/dialect/queryContext.d.ts +3 -3
  17. package/dist/entity/metadata/definition.d.ts +6 -0
  18. package/dist/entity/metadata/definition.js +139 -94
  19. package/dist/migrate/cli.d.ts +1 -1
  20. package/dist/migrate/cli.js +20 -34
  21. package/dist/migrate/codegen/entityCodeGenerator.d.ts +5 -0
  22. package/dist/migrate/codegen/entityCodeGenerator.js +29 -7
  23. package/dist/migrate/codegen/indexDecoratorSource.js +1 -5
  24. package/dist/migrate/codegen/sourceLiteral.d.ts +2 -0
  25. package/dist/migrate/codegen/sourceLiteral.js +4 -0
  26. package/dist/migrate/index.d.ts +1 -1
  27. package/dist/migrate/index.js +1 -1
  28. package/dist/migrate/introspection/registry.d.ts +2 -2
  29. package/dist/migrate/introspection/registry.js +6 -11
  30. package/dist/migrate/migrationTarget.d.ts +6 -6
  31. package/dist/migrate/migrationTarget.js +18 -16
  32. package/dist/migrate/migrator.d.ts +3 -7
  33. package/dist/migrate/migrator.js +10 -31
  34. package/dist/migrate/schemaGenerator.d.ts +1 -3
  35. package/dist/migrate/schemaGenerator.js +0 -4
  36. package/dist/mongo/mongoDialect.d.ts +1 -1
  37. package/dist/mongo/mongoDialect.js +1 -4
  38. package/dist/mssql/mssqlDialect.js +0 -3
  39. package/dist/pglite/pgliteQuerier.d.ts +2 -6
  40. package/dist/pglite/pgliteQuerier.js +2 -9
  41. package/dist/postgres/index.d.ts +0 -1
  42. package/dist/postgres/index.js +0 -1
  43. package/dist/querier/abstractSharedHandleQuerierPool.d.ts +2 -5
  44. package/dist/querier/abstractSharedHandleQuerierPool.js +2 -5
  45. package/dist/querier/abstractSqlQuerier.d.ts +2 -3
  46. package/dist/querier/abstractSqlQuerier.js +8 -4
  47. package/dist/querier/cursorStream.d.ts +13 -0
  48. package/dist/{postgres/pgCursorStream.js → querier/cursorStream.js} +4 -13
  49. package/dist/schema/canonicalType.js +1 -1
  50. package/dist/schema/schemaASTBuilder.js +34 -40
  51. package/dist/sqlite/abstractSqliteQuerier.d.ts +7 -3
  52. package/dist/sqlite/abstractSqliteQuerier.js +18 -4
  53. package/dist/sqlite/hranaQuerier.d.ts +1 -1
  54. package/dist/sqlite/localSqliteQuerierPool.d.ts +7 -0
  55. package/dist/sqlite/localSqliteQuerierPool.js +19 -0
  56. package/dist/sqlite/nodeSqliteQuerierPool.js +2 -3
  57. package/dist/sqlite/sqliteDialect.js +0 -3
  58. package/dist/sqlite/sqliteQuerier.d.ts +8 -5
  59. package/dist/sqlite/sqliteQuerier.js +4 -13
  60. package/dist/sqlite/sqliteQuerierPool.js +4 -4
  61. package/dist/turso/tursoSessionQuerier.d.ts +2 -2
  62. package/dist/turso/tursoSessionQuerier.js +16 -18
  63. package/dist/type/dialect.d.ts +25 -35
  64. package/dist/type/entity.d.ts +29 -32
  65. package/dist/type/migratorDialect.d.ts +0 -9
  66. package/dist/type/migratorDialect.js +1 -16
  67. package/dist/type/querierPool.d.ts +0 -4
  68. package/dist/type/queryRaw.d.ts +2 -2
  69. package/dist/type/universalQuerier.d.ts +2 -2
  70. package/package.json +1 -3
  71. package/dist/postgres/pgCursorStream.d.ts +0 -20
  72. package/dist/postgres/postgresWireDriverCapabilities.d.ts +0 -21
  73. package/dist/postgres/postgresWireDriverCapabilities.js +0 -21
  74. package/dist/sqlite/bunSqliteAdapter.bun.d.ts +0 -27
  75. package/dist/sqlite/bunSqliteAdapter.bun.js +0 -25
  76. package/dist/sqlite/nodeSqliteAdapter.d.ts +0 -33
  77. package/dist/sqlite/nodeSqliteAdapter.js +0 -25
@@ -4,19 +4,12 @@ import { type BunSqlConn } from './bunSql.util.js';
4
4
  * Querier for `bun:sql`, Bun's built-in driver for Postgres, MySQL, MariaDB and CockroachDB.
5
5
  *
6
6
  * @remarks Exposes no `SQL` of its own: the pool's would run a statement on any connection, outside
7
- * the transaction this one's reserved connection holds. Raw access is `pool.sql`.
7
+ * the transaction this one's reserved connection holds. Raw access is `pool.sql`. It streams through the
8
+ * base class, `bun:sql` having no cursor API ([oven-sh/bun#17181](https://github.com/oven-sh/bun/issues/17181)).
8
9
  */
9
10
  export declare class BunSqlQuerier extends AbstractPoolQuerier<BunSqlConn> {
10
11
  internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
11
- internalRun(query: string, values?: unknown[]): Promise<import("../type/query.js").QueryUpdateResult>;
12
- /**
13
- * A server-side cursor where the engine has one, the base class's buffering where it does not.
14
- *
15
- * Bun's `SQL.Query` is a `Promise` with no cursor or async-iterator API
16
- * ([oven-sh/bun#17181](https://github.com/oven-sh/bun/issues/17181)), so the rows have to be paged
17
- * in SQL instead - which the Postgres wire family can do and MySQL cannot.
18
- */
19
- protected internalStream<T>(query: string, values?: unknown[]): AsyncGenerator<Awaited<T>, void, any>;
12
+ internalRun(query: string, values?: unknown[]): Promise<import("../index.js").QueryUpdateResult>;
20
13
  private execute;
21
14
  protected releaseConn(conn: BunSqlConn): Promise<void>;
22
15
  }
@@ -1,4 +1,3 @@
1
- import { streamViaCursor } from '../postgres/pgCursorStream.js';
2
1
  import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
3
2
  import { decodeBigInts } from '../util/wideNumber.js';
4
3
  import { getAffectedRows, getInsertId } from './bunSql.util.js';
@@ -6,7 +5,8 @@ import { getAffectedRows, getInsertId } from './bunSql.util.js';
6
5
  * Querier for `bun:sql`, Bun's built-in driver for Postgres, MySQL, MariaDB and CockroachDB.
7
6
  *
8
7
  * @remarks Exposes no `SQL` of its own: the pool's would run a statement on any connection, outside
9
- * the transaction this one's reserved connection holds. Raw access is `pool.sql`.
8
+ * the transaction this one's reserved connection holds. Raw access is `pool.sql`. It streams through the
9
+ * base class, `bun:sql` having no cursor API ([oven-sh/bun#17181](https://github.com/oven-sh/bun/issues/17181)).
10
10
  */
11
11
  export class BunSqlQuerier extends AbstractPoolQuerier {
12
12
  async internalAll(query, values) {
@@ -21,20 +21,6 @@ export class BunSqlQuerier extends AbstractPoolQuerier {
21
21
  upsertStatus: res.affectedRows ?? undefined,
22
22
  });
23
23
  }
24
- /**
25
- * A server-side cursor where the engine has one, the base class's buffering where it does not.
26
- *
27
- * Bun's `SQL.Query` is a `Promise` with no cursor or async-iterator API
28
- * ([oven-sh/bun#17181](https://github.com/oven-sh/bun/issues/17181)), so the rows have to be paged
29
- * in SQL instead - which the Postgres wire family can do and MySQL cannot.
30
- */
31
- async *internalStream(query, values) {
32
- if (!this.dialect.features.serverSideCursors) {
33
- yield* super.internalStream(query, values);
34
- return;
35
- }
36
- yield* streamViaCursor((sql, params) => this.internalAll(sql, params), query, values, this.hasOpenTransaction);
37
- }
38
24
  async execute(query, values) {
39
25
  // Safe: UQL parameters are strictly bound. .unsafe() correctly bypasses Bun's tagged template
40
26
  // literal parsing requirement so we can execute our dynamically compiled AST strings natively.
@@ -2,12 +2,10 @@ import { SQL } from 'bun';
2
2
  import type { AbstractSqlDialect } from '../dialect/abstractSqlDialect.js';
3
3
  import { AbstractSqlQuerierPool } from '../querier/index.js';
4
4
  import type { ExtraOptions, SqlPoolCompat } from '../type/index.js';
5
- import { type BunSqlDialectName } from './bunSql.util.js';
6
5
  import { BunSqlQuerier } from './bunSqlQuerier.js';
7
6
  export declare class BunSqlQuerierPool extends AbstractSqlQuerierPool<BunSqlQuerier, AbstractSqlDialect> {
8
7
  readonly config: SQL.Options;
9
8
  readonly sql: SQL;
10
- readonly sqlDialectName: BunSqlDialectName;
11
9
  /** @param config Bun's own `SQL.Options`, from which the engine is inferred. */
12
10
  constructor(config: SQL.Options, extra?: ExtraOptions);
13
11
  /**
@@ -4,36 +4,34 @@ import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
4
4
  import { MariaDialect } from '../maria/mariaDialect.js';
5
5
  import { MySqlDialect } from '../mysql/mysqlDialect.js';
6
6
  import { PostgresDialect } from '../postgres/postgresDialect.js';
7
- import { POSTGRES_WIRE_DRIVER_CAPABILITIES } from '../postgres/postgresWireDriverCapabilities.js';
8
7
  import { AbstractSqlQuerierPool } from '../querier/index.js';
9
8
  import { decodeBigInts } from '../util/wideNumber.js';
10
9
  import { getAffectedRows, inferDialectName, normalizeBunOpts, } from './bunSql.util.js';
11
10
  import { BunSqlQuerier } from './bunSqlQuerier.js';
12
11
  /**
13
- * The dialect each engine `bun:sql` drives is given, and how this driver shapes its parameters.
14
- *
15
- * The engine dialects themselves, not `bun:sql` subclasses of them: what Bun changes is the binding,
16
- * never the SQL, and a per-instance `driverCapabilities` is where the base class already takes that -
17
- * so the Postgres and CockroachDB entries differ from `PgQuerierPool`'s only by naming the same
18
- * constant. Total over {@link BunSqlDialectName}, so a new Bun adapter has to be answered here.
12
+ * How `bun:sql` binds on the Postgres wire, measured live on Postgres and CockroachDB alike: an array
13
+ * as its literal, since `unsafe()` binds no JS array, and JSON re-cast through text, without which a
14
+ * JSONB `$set`/`$push` writes the wrong value or throws.
19
15
  */
20
- const DialectMap = {
21
- postgres: [PostgresDialect, POSTGRES_WIRE_DRIVER_CAPABILITIES],
22
- cockroachdb: [CockroachDialect, POSTGRES_WIRE_DRIVER_CAPABILITIES],
23
- mysql: [MySqlDialect],
24
- mariadb: [MariaDialect],
16
+ const POSTGRES_WIRE = { nativeArrays: false, explicitJsonCast: true };
17
+ /**
18
+ * The dialect of each engine `bun:sql` drives: the engine's own, since Bun changes how a parameter binds,
19
+ * never the SQL. Total over {@link BunSqlDialectName}, so a new Bun adapter has to be answered here.
20
+ */
21
+ const DIALECTS = {
22
+ postgres: (options) => new PostgresDialect({ ...options, driverCapabilities: POSTGRES_WIRE }),
23
+ cockroachdb: (options) => new CockroachDialect({ ...options, driverCapabilities: POSTGRES_WIRE }),
24
+ mysql: (options) => new MySqlDialect(options),
25
+ mariadb: (options) => new MariaDialect(options),
25
26
  };
26
27
  export class BunSqlQuerierPool extends AbstractSqlQuerierPool {
27
28
  config;
28
29
  sql;
29
- sqlDialectName;
30
30
  /** @param config Bun's own `SQL.Options`, from which the engine is inferred. */
31
31
  constructor(config, extra) {
32
32
  const dialectName = inferDialectName(config);
33
- const [Dialect, driverCapabilities] = DialectMap[dialectName];
34
- super(new Dialect({ ...dialectOptionsFrom(extra), driverCapabilities }), extra);
33
+ super(DIALECTS[dialectName](dialectOptionsFrom(extra)), extra);
35
34
  this.config = config;
36
- this.sqlDialectName = dialectName;
37
35
  this.sql = new SQL(normalizeBunOpts(config, dialectName));
38
36
  }
39
37
  /**
@@ -1,51 +1,30 @@
1
- import { AbstractSqliteQuerier } from '../sqlite/abstractSqliteQuerier.js';
1
+ import { AbstractSqliteQuerier, type SqliteBindValue } from '../sqlite/abstractSqliteQuerier.js';
2
2
  import type { SqliteDialect } from '../sqlite/sqliteDialect.js';
3
3
  import type { ExtraOptions, RawRow } from '../type/index.js';
4
- export interface D1Meta {
5
- duration?: number;
6
- size_after?: number;
7
- rows_read?: number;
8
- rows_written?: number;
9
- last_row_id?: number;
10
- changed_db?: boolean;
11
- changes?: number;
12
- [key: string]: unknown;
13
- }
4
+ /** What a statement answers on D1: the rows it read, and how many rows it changed. */
14
5
  export interface D1Result<T = unknown> {
15
6
  results: T[];
16
- success: boolean;
17
- meta: D1Meta;
18
- error?: string;
19
- }
20
- export interface D1ExecResult {
21
- count: number;
22
- duration: number;
23
- meta?: D1Meta;
7
+ meta: {
8
+ changes?: number;
9
+ };
24
10
  }
25
11
  export interface D1PreparedStatement {
26
12
  bind(...values: unknown[]): D1PreparedStatement;
27
- first<T = unknown>(colName?: string): Promise<T | null>;
28
- /** Documented by D1 as an alias of {@link all}: both answer the rows and `meta.changes`. */
29
- run<T = unknown>(): Promise<D1Result<T>>;
13
+ /** Documented by D1 as the same call as `run()`: both answer the rows and `meta.changes`. */
30
14
  all<T = unknown>(): Promise<D1Result<T>>;
31
- raw<T = unknown>(): Promise<T[]>;
32
15
  }
16
+ /**
17
+ * The part of a D1 binding uql calls, which a session from `withSession()` - how a read-replicated
18
+ * database is read - has too. The rest of a binding is typed by `@cloudflare/workers-types`.
19
+ */
33
20
  export interface D1Database {
34
21
  prepare(query: string): D1PreparedStatement;
35
- dump(): Promise<ArrayBuffer>;
36
- batch<T = unknown>(statements: D1PreparedStatement[]): Promise<D1Result<T>[]>;
37
- exec(query: string): Promise<D1ExecResult>;
38
22
  }
39
- /**
40
- * The only part of a D1 binding the querier uses: what a {@link D1Database} and a session from
41
- * `withSession()`, which a read-replicated database is read through, both have.
42
- */
43
- export type D1Preparer = Pick<D1Database, 'prepare'>;
44
23
  export declare class D1Querier extends AbstractSqliteQuerier {
45
- readonly db: D1Preparer;
24
+ readonly db: D1Database;
46
25
  readonly extra?: ExtraOptions | undefined;
47
- constructor(db: D1Preparer, dialect: SqliteDialect, extra?: ExtraOptions | undefined);
48
- protected execute(query: string, values?: unknown[]): Promise<{
26
+ constructor(db: D1Database, dialect: SqliteDialect, extra?: ExtraOptions | undefined);
27
+ protected execute(query: string, values: SqliteBindValue[]): Promise<{
49
28
  rows: RawRow[];
50
29
  changes: number;
51
30
  }>;
@@ -9,7 +9,7 @@ export class D1Querier extends AbstractSqliteQuerier {
9
9
  }
10
10
  async execute(query, values) {
11
11
  const stmt = this.db.prepare(query);
12
- const { results, meta } = await (values?.length ? stmt.bind(...values) : stmt).all();
12
+ const { results, meta } = await (values.length ? stmt.bind(...values) : stmt).all();
13
13
  return { rows: results, changes: meta.changes ?? 0 };
14
14
  }
15
15
  /** D1 answers `BEGIN` with `D1_ERROR: not authorized`: a single statement is its only atomic unit. */
@@ -1,14 +1,14 @@
1
1
  import { AbstractSqlQuerierPool } from '../querier/index.js';
2
2
  import type { ExtraOptions } from '../type/index.js';
3
- import { type D1Preparer, D1Querier } from './d1Querier.js';
3
+ import { type D1Database, D1Querier } from './d1Querier.js';
4
4
  import { D1SqliteDialect } from './d1SqliteDialect.js';
5
5
  /**
6
6
  * Pool for Cloudflare D1. It holds nothing: every querier runs on what it was given, `env.DB` or a
7
7
  * session from `env.DB.withSession()`, the way a read-replicated database is read consistently.
8
8
  */
9
9
  export declare class D1QuerierPool extends AbstractSqlQuerierPool<D1Querier, D1SqliteDialect> {
10
- readonly db: D1Preparer;
11
- constructor(db: D1Preparer, extra?: ExtraOptions);
10
+ readonly db: D1Database;
11
+ constructor(db: D1Database, extra?: ExtraOptions);
12
12
  getQuerier(): Promise<D1Querier>;
13
13
  end(): Promise<void>;
14
14
  }
@@ -6,12 +6,11 @@ export interface DialectOptions {
6
6
  readonly namingStrategy?: NamingStrategy;
7
7
  /** Default schema for entities naming none; unset leaves them unqualified. See {@link AbstractDialect.resolveSchema}. */
8
8
  readonly schema?: string;
9
- readonly driverCapabilities?: Partial<DialectFeatures>;
10
9
  }
11
10
  /**
12
11
  * The dialect's share of a pool's {@link ExtraOptions}: what changes the SQL rather than the
13
12
  * connection. Every pool builds its dialect through this, so a new option lands here instead of in
14
- * each of the thirteen constructors.
13
+ * each pool's constructor.
15
14
  */
16
15
  export declare function dialectOptionsFrom(extra: ExtraOptions | undefined): DialectOptions;
17
16
  /**
@@ -23,10 +22,7 @@ export declare abstract class AbstractDialect {
23
22
  abstract readonly dialectName: DialectName;
24
23
  /** How this dialect surfaces the IDs generated by an INSERT (see {@link InsertIdSource}). */
25
24
  abstract readonly insertIdSource: InsertIdSource;
26
- /**
27
- * Engine/driver feature defaults for this dialect, before per-instance
28
- * {@link DialectOptions.driverCapabilities} overrides. Each concrete dialect declares its own.
29
- */
25
+ /** What the engine has, as this dialect's family has it. Each concrete dialect declares its own. */
30
26
  protected abstract readonly featureDefaults: DialectFeatures;
31
27
  /**
32
28
  * How this dialect differs from the family it extends, so a subclass states only its deltas rather
@@ -36,9 +32,8 @@ export declare abstract class AbstractDialect {
36
32
  readonly namingStrategy: NamingStrategy | undefined;
37
33
  constructor(options?: DialectOptions);
38
34
  /**
39
- * Effective features: {@link featureDefaults}, then this dialect's {@link featureOverrides}, then
40
- * any per-instance {@link DialectOptions.driverCapabilities}. Computed lazily (and memoized)
41
- * because both are subclass fields, initialized only after `super()` returns.
35
+ * Effective features: {@link featureDefaults}, then this dialect's {@link featureOverrides}. Computed
36
+ * lazily (and memoized) because both are subclass fields, initialized only after `super()` returns.
42
37
  */
43
38
  get features(): DialectFeatures;
44
39
  /**
@@ -4,7 +4,7 @@ import { qualifyName } from '../util/sql.util.js';
4
4
  /**
5
5
  * The dialect's share of a pool's {@link ExtraOptions}: what changes the SQL rather than the
6
6
  * connection. Every pool builds its dialect through this, so a new option lands here instead of in
7
- * each of the thirteen constructors.
7
+ * each pool's constructor.
8
8
  */
9
9
  export function dialectOptionsFrom(extra) {
10
10
  return { namingStrategy: extra?.namingStrategy, schema: extra?.schema };
@@ -26,12 +26,11 @@ export class AbstractDialect {
26
26
  this.namingStrategy = options.namingStrategy;
27
27
  }
28
28
  /**
29
- * Effective features: {@link featureDefaults}, then this dialect's {@link featureOverrides}, then
30
- * any per-instance {@link DialectOptions.driverCapabilities}. Computed lazily (and memoized)
31
- * because both are subclass fields, initialized only after `super()` returns.
29
+ * Effective features: {@link featureDefaults}, then this dialect's {@link featureOverrides}. Computed
30
+ * lazily (and memoized) because both are subclass fields, initialized only after `super()` returns.
32
31
  */
33
32
  get features() {
34
- this.#features ??= { ...this.featureDefaults, ...this.featureOverrides, ...this.options.driverCapabilities };
33
+ this.#features ??= { ...this.featureDefaults, ...this.featureOverrides };
35
34
  return this.#features;
36
35
  }
37
36
  /**
@@ -1,4 +1,4 @@
1
- import { type EntityData, type EntityMeta, type EntityWhereMeta, type FieldKey, type FieldOptions, type IsolationLevel, type JsonColumnType, type JsonUpdateOp, type Query, type QueryAggMap, type QueryAggregate, type QueryBuildFn, type QueryComparisonOptions, type QueryConflictPaths, type QueryContext, type QueryContextOptions, type QueryDialect, type QueryExclude, type QueryFilter, type QueryGroupMap, type QueryGroupOp, type QueryHavingMap, type QueryOptions, type QueryPager, QueryRaw, type QueryRawFnOptions, type QuerySearch, type QuerySelectValue, type QuerySizeComparisonOps, type QuerySortMap, type QueryTextSearchOptions, type QueryVectorNear, type QueryWhere, type QueryWhereArray, type QueryWhereFieldOperatorMap, type QueryWhereOptions, type RelationMeta, type SqlDialectName, type SqlQueryDialect, type Type, type UpdatePayload } from '../type/index.js';
1
+ import { type EntityData, type EntityMeta, type EntityWhereMeta, type FieldKey, type FieldOptions, type IsolationLevel, type JsonColumnType, type JsonUpdateOp, type Query, type QueryAggMap, type QueryAggregate, type QueryBuildFn, type QueryComparisonOptions, type QueryConflictPaths, type QueryContext, type QueryContextOptions, type QueryExclude, type QueryFilter, type QueryGroupMap, type QueryGroupOp, type QueryHavingMap, type QueryOptions, type QueryPager, QueryRaw, type QueryRawFnOptions, type QuerySearch, type QuerySelectValue, type QuerySizeComparisonOps, type QuerySortMap, type QueryTextSearchOptions, type QueryVectorNear, type QueryWhere, type QueryWhereArray, type QueryWhereFieldOperatorMap, type QueryWhereOptions, type RelationMeta, type SqlDialectName, type SqlQueryDialect, type Type, type UpdatePayload } from '../type/index.js';
2
2
  import { type ColumnFamily } from '../util/field.util.js';
3
3
  import type { HydrateKind } from './hydrateColumn.js';
4
4
  import { type JsonAccessMode } from './jsonSql.js';
@@ -80,7 +80,7 @@ export type CarriedFields = {
80
80
  /** The key a term answers under in a populated relation's row, which a raw expression has only once aliased. */
81
81
  export declare function relationTermKey({ sql, key }: SelectTerm): string;
82
82
  export type { HydrateKind };
83
- export declare abstract class AbstractSqlDialect extends VectorSqlDialect implements QueryDialect, SqlQueryDialect {
83
+ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implements SqlQueryDialect {
84
84
  abstract readonly dialectName: SqlDialectName;
85
85
  abstract readonly escapeIdChar: '"' | '`';
86
86
  /**
@@ -1,4 +1,3 @@
1
1
  export * from './abstractDialect.js';
2
2
  export * from './abstractSqlDialect.js';
3
- export * from './mysqlLikeSqlDialect.js';
4
3
  export * from './queryContext.js';
@@ -1,6 +1,5 @@
1
- // The concrete dialects are behind their own entries (`uql-orm/postgres`, `/mysql`, `/maria`,
2
- // `/sqlite`, `/cockroachdb`): importing the root should not carry four engines' worth of SQL.
1
+ // Each engine's dialect is behind its own entry, and the family bases they extend behind none: the root
2
+ // carries no engine's SQL.
3
3
  export * from './abstractDialect.js';
4
4
  export * from './abstractSqlDialect.js';
5
- export * from './mysqlLikeSqlDialect.js';
6
5
  export * from './queryContext.js';
@@ -24,9 +24,6 @@ const MAX_LIMIT = BigInt.asUintN(64, -1n);
24
24
  export class MysqlLikeSqlDialect extends AbstractSqlDialect {
25
25
  /** Default {@link DialectFeatures} for MySQL-compatible SQL dialects. */
26
26
  featureDefaults = {
27
- explicitJsonCast: false,
28
- nativeArrays: false,
29
- supportsJsonb: false,
30
27
  ifNotExists: true,
31
28
  indexIfNotExists: false,
32
29
  schemas: true,
@@ -1,5 +1,10 @@
1
- import { type DialectFeatures, type EntityMeta, type FieldOptions, type JsonColumnType, type Query, type QueryContext, type QuerySizeComparisonOps, type QueryTextSearchOptions, type Type } from '../type/index.js';
1
+ import { type DialectFeatures, type DriverCapabilities, type EntityMeta, type FieldOptions, type JsonColumnType, type Query, type QueryContext, type QuerySizeComparisonOps, type QueryTextSearchOptions, type Type } from '../type/index.js';
2
+ import type { DialectOptions } from './abstractDialect.js';
2
3
  import { AbstractSqlDialect, type RelationRows } from './abstractSqlDialect.js';
4
+ /** A Postgres-wire dialect's options: the base's, and how its driver binds a parameter. */
5
+ export type PgLikeDialectOptions = DialectOptions & {
6
+ readonly driverCapabilities?: Partial<DriverCapabilities>;
7
+ };
3
8
  /**
4
9
  * Shared AST/quoting/JSONB/full-text-search/vector-search implementation between Postgres and
5
10
  * CockroachDB (wire- and SQL-compatible for everything below, including `TO_TSVECTOR`/`TO_TSQUERY`
@@ -10,6 +15,9 @@ import { AbstractSqlDialect, type RelationRows } from './abstractSqlDialect.js';
10
15
  * syntax; CockroachDB's vector type and `CREATE VECTOR INDEX` syntax are both native).
11
16
  */
12
17
  export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
18
+ /** How the driver binds a parameter: node-`pg`'s, unless the pool states its own. */
19
+ readonly driverCapabilities: DriverCapabilities;
20
+ constructor(options?: PgLikeDialectOptions);
13
21
  /** `FOR UPDATE` and a window function cannot share a statement here. See the base declaration. */
14
22
  readonly supportsWindowWithRowLock = false;
15
23
  /** Default {@link DialectFeatures} for Postgres-wire dialects. */
@@ -17,13 +17,16 @@ import { resolveVectorCast, toSparsevecLiteral } from './vectorCast.js';
17
17
  * syntax; CockroachDB's vector type and `CREATE VECTOR INDEX` syntax are both native).
18
18
  */
19
19
  export class PgLikeSqlDialect extends AbstractSqlDialect {
20
+ /** How the driver binds a parameter: node-`pg`'s, unless the pool states its own. */
21
+ driverCapabilities;
22
+ constructor(options = {}) {
23
+ super(options);
24
+ this.driverCapabilities = { nativeArrays: true, explicitJsonCast: false, ...options.driverCapabilities };
25
+ }
20
26
  /** `FOR UPDATE` and a window function cannot share a statement here. See the base declaration. */
21
27
  supportsWindowWithRowLock = false;
22
28
  /** Default {@link DialectFeatures} for Postgres-wire dialects. */
23
29
  featureDefaults = {
24
- explicitJsonCast: false,
25
- nativeArrays: true,
26
- supportsJsonb: true,
27
30
  ifNotExists: true,
28
31
  indexIfNotExists: true,
29
32
  schemas: true,
@@ -109,7 +112,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
109
112
  }
110
113
  normalizeValue(value) {
111
114
  if (value != null && typeof value === 'object' && Array.isArray(value)) {
112
- return this.features.nativeArrays ? value : toPgArray(value);
115
+ return this.driverCapabilities.nativeArrays ? value : toPgArray(value);
113
116
  }
114
117
  return super.normalizeValue(value);
115
118
  }
@@ -227,7 +230,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
227
230
  return `${this.addValue(ctx, null)}::${type}`;
228
231
  const json = JSON.stringify(value);
229
232
  const ph = this.addValue(ctx, json);
230
- return this.features.explicitJsonCast ? `(${ph}::text)::${type}` : `${ph}::${type}`;
233
+ return this.driverCapabilities.explicitJsonCast ? `(${ph}::text)::${type}` : `${ph}::${type}`;
231
234
  }
232
235
  }
233
236
  /**
@@ -1,4 +1,4 @@
1
- import type { QueryContext, QueryDialect } from '../type/index.js';
1
+ import type { QueryContext, SqlQueryDialect } from '../type/index.js';
2
2
  /**
3
3
  * SqlQueryContext is an implementation of the QueryContext interface specifically for SQL-based dialects.
4
4
  * It follows the "Accumulator" or "Builder" pattern to construct SQL queries and their corresponding parameters.
@@ -7,7 +7,7 @@ import type { QueryContext, QueryDialect } from '../type/index.js';
7
7
  * preventing SQL injection and handling dialect-specific parameter placeholders (e.g., '?' for MySQL, '$n' for PostgreSQL).
8
8
  */
9
9
  export declare class SqlQueryContext implements QueryContext {
10
- readonly dialect: QueryDialect;
10
+ readonly dialect: SqlQueryDialect;
11
11
  private readonly statement?;
12
12
  readonly inlineValues: boolean;
13
13
  private readonly sqlChunks;
@@ -23,7 +23,7 @@ export declare class SqlQueryContext implements QueryContext {
23
23
  * fragment is part of one statement, so its aliases have to be unique across the whole of it.
24
24
  * @param inlineValues See {@link QueryContext.inlineValues}; a fragment takes its statement's.
25
25
  */
26
- constructor(dialect: QueryDialect, params?: unknown[], statement?: SqlQueryContext | undefined, inlineValues?: boolean);
26
+ constructor(dialect: SqlQueryDialect, params?: unknown[], statement?: SqlQueryContext | undefined, inlineValues?: boolean);
27
27
  createFragment(): QueryContext;
28
28
  /**
29
29
  * Appends raw SQL string fragments to the query.
@@ -68,3 +68,9 @@ export declare function idOf<E>(meta: EntityMeta<E>, row: EntityData<E>): Writte
68
68
  export declare function removeEntity<E>(entity: Type<E>): boolean;
69
69
  export declare function getEntities(): Type<object>[];
70
70
  export declare function getMeta<E>(entity: Type<E>): EntityMeta<E>;
71
+ /**
72
+ * The foreign keys an entity holds: each owning to-one's columns, and each `@Field({ references })` no
73
+ * relation joins on, as the many-to-one it describes, once its target has registered a key. What the
74
+ * schema build constrains and a junction joins by, read once the relations holding them are settled.
75
+ */
76
+ export declare function foreignKeysOf<E>(meta: EntityMeta<E>): RelationMeta[];