uql-orm 0.54.0 → 0.56.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/README.md +2 -2
  2. package/dist/browser/uql-browser.min.js +2 -2
  3. package/dist/browser/uql-browser.min.js.map +4 -4
  4. package/dist/bunSql/bunSql.util.d.ts +3 -14
  5. package/dist/bunSql/bunSql.util.js +33 -56
  6. package/dist/bunSql/bunSqlQuerier.d.ts +3 -6
  7. package/dist/bunSql/bunSqlQuerier.js +7 -13
  8. package/dist/bunSql/bunSqlQuerierPool.d.ts +10 -5
  9. package/dist/bunSql/bunSqlQuerierPool.js +25 -10
  10. package/dist/cockroachdb/crdbQuerierPool.d.ts +1 -3
  11. package/dist/cockroachdb/crdbQuerierPool.js +0 -4
  12. package/dist/cockroachdb/index.d.ts +0 -1
  13. package/dist/cockroachdb/index.js +0 -1
  14. package/dist/d1/d1SqliteDialect.d.ts +5 -0
  15. package/dist/d1/d1SqliteDialect.js +7 -0
  16. package/dist/dialect/abstractSqlDialect.d.ts +9 -9
  17. package/dist/dialect/abstractSqlDialect.js +38 -51
  18. package/dist/dialect/hydrateColumn.js +2 -2
  19. package/dist/dialect/mergeSqlDialect.d.ts +2 -2
  20. package/dist/dialect/mergeSqlDialect.js +0 -4
  21. package/dist/dialect/mysqlLikeSqlDialect.js +2 -3
  22. package/dist/dialect/pgLikeSqlDialect.d.ts +5 -0
  23. package/dist/dialect/pgLikeSqlDialect.js +14 -4
  24. package/dist/dialect/queryJoins.js +2 -4
  25. package/dist/entity/index.d.ts +1 -1
  26. package/dist/entity/index.js +1 -1
  27. package/dist/entity/metadata/definition.d.ts +5 -1
  28. package/dist/entity/metadata/definition.js +32 -26
  29. package/dist/libsql/index.d.ts +0 -1
  30. package/dist/libsql/index.js +0 -1
  31. package/dist/libsql/libsqlQuerierPool.d.ts +3 -5
  32. package/dist/libsql/libsqlQuerierPool.js +2 -5
  33. package/dist/maria/mariadbQuerier.d.ts +0 -3
  34. package/dist/maria/mariadbQuerier.js +6 -7
  35. package/dist/maria/mariadbQuerierPool.js +4 -7
  36. package/dist/migrate/builder/splitSqlStatements.js +2 -2
  37. package/dist/migrate/cli.js +2 -9
  38. package/dist/migrate/codegen/fieldOptionsSource.js +1 -1
  39. package/dist/migrate/ddl/index.d.ts +3 -3
  40. package/dist/migrate/ddl/index.js +3 -3
  41. package/dist/migrate/ddl/pgIndexDdl.d.ts +5 -0
  42. package/dist/migrate/ddl/pgIndexDdl.js +9 -0
  43. package/dist/migrate/drift/driftDetector.js +21 -8
  44. package/dist/migrate/generator/mongoSchemaGenerator.js +1 -1
  45. package/dist/migrate/introspection/baseSqlIntrospector.d.ts +1 -1
  46. package/dist/migrate/introspection/baseSqlIntrospector.js +65 -76
  47. package/dist/migrate/introspection/mssqlIntrospector.js +2 -1
  48. package/dist/migrate/introspection/mysqlIntrospector.js +5 -8
  49. package/dist/migrate/introspection/sqliteIntrospector.js +2 -5
  50. package/dist/migrate/migrator.d.ts +5 -2
  51. package/dist/migrate/migrator.js +9 -14
  52. package/dist/migrate/schemaGenerator.js +2 -6
  53. package/dist/mongo/index.d.ts +0 -1
  54. package/dist/mongo/index.js +0 -1
  55. package/dist/mongo/mongoDialect.d.ts +1 -2
  56. package/dist/mongo/mongoDialect.js +7 -21
  57. package/dist/mongo/mongodbQuerier.js +12 -11
  58. package/dist/mongo/mongodbQuerierPool.d.ts +2 -2
  59. package/dist/mongo/mongodbQuerierPool.js +2 -2
  60. package/dist/mssql/mssqlDialect.d.ts +3 -5
  61. package/dist/mssql/mssqlDialect.js +9 -8
  62. package/dist/mssql/mssqlQuerier.d.ts +13 -6
  63. package/dist/mssql/mssqlQuerier.js +30 -75
  64. package/dist/mssql/mssqlQuerierPool.js +2 -0
  65. package/dist/mssql/mssqlWireTypes.d.ts +3 -4
  66. package/dist/mssql/mssqlWireTypes.js +5 -8
  67. package/dist/mysql/index.d.ts +0 -1
  68. package/dist/mysql/index.js +0 -1
  69. package/dist/mysql/mysql2Querier.d.ts +1 -4
  70. package/dist/mysql/mysql2Querier.js +0 -3
  71. package/dist/mysql/mysql2QuerierPool.d.ts +2 -2
  72. package/dist/mysql/mysql2QuerierPool.js +5 -3
  73. package/dist/neon/index.d.ts +0 -2
  74. package/dist/neon/index.js +0 -2
  75. package/dist/neon/neonQuerierPool.d.ts +2 -4
  76. package/dist/neon/neonQuerierPool.js +2 -6
  77. package/dist/pglite/index.d.ts +0 -1
  78. package/dist/pglite/index.js +0 -1
  79. package/dist/pglite/pgliteQuerier.d.ts +3 -3
  80. package/dist/pglite/pgliteQuerier.js +1 -1
  81. package/dist/pglite/pgliteQuerierPool.d.ts +7 -2
  82. package/dist/pglite/pgliteQuerierPool.js +16 -6
  83. package/dist/postgres/abstractPgQuerierPool.d.ts +8 -12
  84. package/dist/postgres/abstractPgQuerierPool.js +8 -6
  85. package/dist/postgres/index.d.ts +0 -1
  86. package/dist/postgres/index.js +0 -1
  87. package/dist/postgres/pgNumericTypes.d.ts +5 -5
  88. package/dist/postgres/pgNumericTypes.js +11 -7
  89. package/dist/postgres/pgQuerier.d.ts +22 -4
  90. package/dist/postgres/pgQuerier.js +29 -2
  91. package/dist/postgres/pgQuerierPool.d.ts +2 -4
  92. package/dist/postgres/pgQuerierPool.js +2 -6
  93. package/dist/postgres/postgresDialect.d.ts +5 -5
  94. package/dist/postgres/postgresDialect.js +5 -5
  95. package/dist/postgres/postgresWireDriverCapabilities.d.ts +2 -2
  96. package/dist/postgres/postgresWireDriverCapabilities.js +2 -2
  97. package/dist/querier/abstractPoolQuerier.d.ts +1 -1
  98. package/dist/querier/abstractPoolQuerier.js +1 -1
  99. package/dist/querier/abstractQuerier.js +17 -22
  100. package/dist/querier/abstractSqlQuerier.d.ts +21 -12
  101. package/dist/querier/abstractSqlQuerier.js +61 -43
  102. package/dist/schema/canonicalType.js +0 -2
  103. package/dist/schema/dependencyGraph.js +2 -4
  104. package/dist/schema/indexDifferences.js +2 -2
  105. package/dist/schema/schemaASTBuilder.js +3 -10
  106. package/dist/schema/schemaASTDiffer.d.ts +10 -2
  107. package/dist/schema/schemaASTDiffer.js +12 -11
  108. package/dist/schema/types.d.ts +1 -1
  109. package/dist/sqlite/hranaQuerier.d.ts +6 -8
  110. package/dist/sqlite/hranaQuerier.js +13 -30
  111. package/dist/sqlite/hranaQuerierPool.d.ts +3 -4
  112. package/dist/sqlite/hranaQuerierPool.js +2 -1
  113. package/dist/sqlite/localSqliteQuerierPool.d.ts +3 -3
  114. package/dist/sqlite/localSqliteQuerierPool.js +4 -2
  115. package/dist/sqlite/nodeSqliteAdapter.d.ts +0 -1
  116. package/dist/sqlite/nodeSqliteQuerierPool.js +0 -2
  117. package/dist/sqlite/sqliteDialect.js +2 -1
  118. package/dist/sqlite/sqlitePragmas.d.ts +12 -0
  119. package/dist/sqlite/sqlitePragmas.js +15 -0
  120. package/dist/sqlite/sqliteQuerierPool.d.ts +0 -5
  121. package/dist/sqlite/sqliteQuerierPool.js +2 -13
  122. package/dist/turso/index.d.ts +0 -1
  123. package/dist/turso/index.js +0 -1
  124. package/dist/turso/tursoLocalQuerier.d.ts +0 -1
  125. package/dist/turso/tursoLocalQuerierPool.js +2 -2
  126. package/dist/turso/tursoQuerierPool.d.ts +1 -3
  127. package/dist/turso/tursoQuerierPool.js +0 -4
  128. package/dist/type/dialect.d.ts +1 -1
  129. package/dist/util/dialect.util.d.ts +8 -2
  130. package/dist/util/dialect.util.js +20 -1
  131. package/dist/util/logger.d.ts +17 -9
  132. package/dist/util/logger.js +36 -11
  133. package/dist/util/object.util.d.ts +2 -0
  134. package/dist/util/object.util.js +4 -0
  135. package/dist/util/raw.js +3 -3
  136. package/dist/util/relationQuery.util.d.ts +3 -3
  137. package/dist/util/relationQuery.util.js +8 -2
  138. package/dist/util/sqlLiteral.js +3 -8
  139. package/dist/util/string.util.js +2 -6
  140. package/dist/util/wideNumber.d.ts +14 -0
  141. package/dist/util/wideNumber.js +24 -0
  142. package/package.json +1 -1
  143. package/dist/cockroachdb/crdbQuerier.d.ts +0 -8
  144. package/dist/cockroachdb/crdbQuerier.js +0 -6
  145. package/dist/libsql/libsqlQuerier.d.ts +0 -10
  146. package/dist/libsql/libsqlQuerier.js +0 -10
  147. package/dist/mongo/mongodbNativeDialect.d.ts +0 -9
  148. package/dist/mongo/mongodbNativeDialect.js +0 -9
  149. package/dist/mysql/mysql2Dialect.d.ts +0 -9
  150. package/dist/mysql/mysql2Dialect.js +0 -9
  151. package/dist/neon/neonDialect.d.ts +0 -10
  152. package/dist/neon/neonDialect.js +0 -10
  153. package/dist/neon/neonQuerier.d.ts +0 -5
  154. package/dist/neon/neonQuerier.js +0 -3
  155. package/dist/pglite/pgliteDialect.d.ts +0 -14
  156. package/dist/pglite/pgliteDialect.js +0 -14
  157. package/dist/postgres/abstractPgQuerier.d.ts +0 -24
  158. package/dist/postgres/abstractPgQuerier.js +0 -32
  159. package/dist/postgres/pgDialect.d.ts +0 -10
  160. package/dist/postgres/pgDialect.js +0 -10
  161. package/dist/turso/tursoQuerier.d.ts +0 -10
  162. package/dist/turso/tursoQuerier.js +0 -10
@@ -7,6 +7,13 @@ import { SqliteDialect } from '../sqlite/sqliteDialect.js';
7
7
  export class D1SqliteDialect extends SqliteDialect {
8
8
  // Cloudflare D1 caps bound parameters at 100 per query.
9
9
  maxBindValues = 100;
10
+ /**
11
+ * D1's Worker API refuses a `bigint` bind ([workerd#4195](https://github.com/cloudflare/workerd/issues/4195)),
12
+ * so one goes as its exact text, which SQLite's INTEGER affinity stores as the same integer.
13
+ */
14
+ normalizeValue(value) {
15
+ return typeof value === 'bigint' ? String(value) : super.normalizeValue(value);
16
+ }
10
17
  /**
11
18
  * D1 loads no extensions (its allowlist is FTS5, JSON and the math functions) and has no vector
12
19
  * functions of its own, so the sqlite-vec names inherited from {@link SqliteDialect} would compile
@@ -84,6 +84,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
84
84
  * shared for the same reason - see {@link SqlQueryContext}.
85
85
  */
86
86
  protected buildFragment(ctx: QueryContext, build: QueryBuildFn): string;
87
+ /** A `raw()` operand, rendered in place: bound, it would reach the driver as the object itself. */
88
+ protected rawFragment(ctx: QueryContext, value: QueryRaw): string;
87
89
  /**
88
90
  * Each operand rendered into its own fragment, keeping only those that emitted SQL.
89
91
  *
@@ -95,10 +97,9 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
95
97
  protected renderOperands<T>(ctx: QueryContext, operands: readonly T[], render: (ctx: QueryContext, operand: T) => void): string[];
96
98
  addValue(values: unknown[], value: unknown): string;
97
99
  /**
98
- * Normalizes a parameter value for the database driver.
99
- * Handles bigint, boolean, and serializes plain objects/arrays to JSON strings.
100
- * Date values are preserved so SQL drivers can apply native date/time binding.
101
- * Postgres overrides to pass objects through to its native JSONB driver.
100
+ * A parameter value as this engine's driver takes it: a boolean as the integer an engine with no
101
+ * boolean type stores, and everything else as it is - a `bigint` included, which every driver here
102
+ * binds exactly, where a number would round it past 2^53. A driver that refuses one (D1) overrides.
102
103
  */
103
104
  normalizeValue(value: unknown): unknown;
104
105
  /**
@@ -354,10 +355,8 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
354
355
  * caller reached for this to avoid, and only say so by taking a long time.
355
356
  */
356
357
  estimatedCount<E>(_ctx: QueryContext, _entity: Type<E>): void;
357
- /** `$group` aggregate operator → SQL function name. An allowlist, not a formatter: the op key
358
- * comes from query data, so anything outside this map must be rejected rather than passed
359
- * through as a raw SQL function name. */
360
- private static readonly AGGREGATE_FN_MAP;
358
+ /** `$group` aggregate operator to SQL function name, over ops `resolveAggregateOp` has already allowlisted. */
359
+ private static readonly AGGREGATE_FN;
361
360
  aggregate<E, G extends QueryGroupMap<E>, A extends QueryAggMap<E>>(ctx: QueryContext, entity: Type<E>, q: QueryAggregate<E, G, A>, opts?: QueryOptions): void;
362
361
  /**
363
362
  * ORDER BY for aggregate queries - handles both entity-field and alias references. A grouped
@@ -658,6 +657,7 @@ export declare abstract class AbstractSqlDialect extends VectorSqlDialect implem
658
657
  * Postgres overrides to use `= ANY($1)` / `<> ALL($1)` with a single array parameter.
659
658
  */
660
659
  protected formatIn(ctx: QueryContext, values: unknown[], negate: boolean): string;
661
- protected numericCast(expr: string): string;
660
+ /** Reads extracted JSON text as a number, which every engine spells its own way. */
661
+ protected abstract numericCast(expr: string): string;
662
662
  toString(): string;
663
663
  }
@@ -1,4 +1,4 @@
1
- import { getMeta, soleIdOf } from '../entity/index.js';
1
+ import { fieldOf, getMeta, soleIdOf } from '../entity/index.js';
2
2
  import { parseQueryLock, QueryRaw, RAW_ALIAS, RAW_VALUE, VECTOR_QUERY_KEYS, } from '../type/index.js';
3
3
  import { isInlinedExpression } from '../util/field.util.js';
4
4
  import { asSelectMap, assertNonNegativeInteger, escapeSqlId, fillOnFields, filterFieldKeys, getInsertFieldKeys, getKeys, getSoftDeleteValue, hasKeys, columnFamily, isJsonUpdateOp, isOperatorMap, isOperatorObject, isOperatorOnlyObject, isVectorSearch, normalizeScalarFieldSelection, parentJoins, targetKeyColumns, parseGroupMap, parseRelationSize, parseSortByCount, populatesRelations, queryChildrenOf, raw, someValue, throwUnknownAggregateColumn, withoutSoftDeleteFilter, } from '../util/index.js';
@@ -10,6 +10,13 @@ import { SqlQueryContext } from './queryContext.js';
10
10
  import { NO_JOINS, resolveQueryJoins, resolveSortableJoin, } from './queryJoins.js';
11
11
  import { resolveVectorCast } from './vectorCast.js';
12
12
  import { VectorSqlDialect } from './vectorSqlDialect.js';
13
+ /** An `$in`/`$nin` operand, which the types require to be an array but `/http` hands over untyped. */
14
+ function inOperands(op, value) {
15
+ if (!Array.isArray(value)) {
16
+ throw TypeError(`${op} expects an array, got ${value === null ? 'null' : typeof value}`);
17
+ }
18
+ return value;
19
+ }
13
20
  export class AbstractSqlDialect extends VectorSqlDialect {
14
21
  /**
15
22
  * Whether {@link autoIncrementSuffix} states `PRIMARY KEY` itself, so the table must not state it again.
@@ -99,6 +106,10 @@ export class AbstractSqlDialect extends VectorSqlDialect {
99
106
  build(fragmentCtx);
100
107
  return fragmentCtx.sql;
101
108
  }
109
+ /** A `raw()` operand, rendered in place: bound, it would reach the driver as the object itself. */
110
+ rawFragment(ctx, value) {
111
+ return this.buildFragment(ctx, (fragmentCtx) => this.getRawValue(fragmentCtx, { value }));
112
+ }
102
113
  /**
103
114
  * Each operand rendered into its own fragment, keeping only those that emitted SQL.
104
115
  *
@@ -117,20 +128,13 @@ export class AbstractSqlDialect extends VectorSqlDialect {
117
128
  return this.placeholder(values.length);
118
129
  }
119
130
  /**
120
- * Normalizes a parameter value for the database driver.
121
- * Handles bigint, boolean, and serializes plain objects/arrays to JSON strings.
122
- * Date values are preserved so SQL drivers can apply native date/time binding.
123
- * Postgres overrides to pass objects through to its native JSONB driver.
131
+ * A parameter value as this engine's driver takes it: a boolean as the integer an engine with no
132
+ * boolean type stores, and everything else as it is - a `bigint` included, which every driver here
133
+ * binds exactly, where a number would round it past 2^53. A driver that refuses one (D1) overrides.
124
134
  */
125
135
  normalizeValue(value) {
126
- if (value == null || value instanceof Date || value instanceof Uint8Array || value instanceof QueryRaw) {
127
- return value;
128
- }
129
- if (typeof value === 'bigint') {
130
- return Number(value);
131
- }
132
- if (typeof value === 'boolean') {
133
- return this.booleanLiteral === 'native' ? value : value ? 1 : 0;
136
+ if (typeof value === 'boolean' && this.booleanLiteral !== 'native') {
137
+ return value ? 1 : 0;
134
138
  }
135
139
  return value;
136
140
  }
@@ -198,9 +202,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
198
202
  });
199
203
  }
200
204
  else {
201
- const field = meta.fields[key];
202
- if (!field)
203
- return;
205
+ const field = fieldOf(meta, key);
204
206
  if (isInlinedExpression(field)) {
205
207
  // Qualified even when nothing else in this statement is: the expression is spliced in, and
206
208
  // one that opens a correlated subquery has the inner table's columns in scope, so a bare
@@ -427,7 +429,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
427
429
  if (entry instanceof QueryRaw) {
428
430
  this.getRawValue(fragmentCtx, { value: entry });
429
431
  }
430
- else if (entry) {
432
+ else {
431
433
  this.renderWhere(fragmentCtx, entity, entry, { prefix: opts.prefix, operand: childOperand, clause: false });
432
434
  }
433
435
  });
@@ -589,13 +591,8 @@ export class AbstractSqlDialect extends VectorSqlDialect {
589
591
  case '$regex':
590
592
  return this.regexCondition(operand, this.addValue(ctx.values, val));
591
593
  case '$in':
592
- case '$nin': {
593
- if (!Array.isArray(val)) {
594
- // Not covered by the types: `/http` casts client JSON straight to `Query`, so this arrives untyped.
595
- throw TypeError(`${op} expects an array, got ${val === null ? 'null' : typeof val}`);
596
- }
597
- return operand + this.formatIn(ctx, val, op === '$nin');
598
- }
594
+ case '$nin':
595
+ return operand + this.formatIn(ctx, inOperands(op, val), op === '$nin');
599
596
  case '$between': {
600
597
  const [min, max] = val;
601
598
  return `${operand} BETWEEN ${this.addValue(ctx.values, min)} AND ${this.addValue(ctx.values, max)}`;
@@ -663,7 +660,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
663
660
  }
664
661
  }
665
662
  jsonInNin(ctx, jsonField, comparand, op, value, asJson) {
666
- const values = Array.isArray(value) ? value : [];
663
+ const values = inOperands(op, value);
667
664
  const negate = op === '$nin';
668
665
  if (!asJson) {
669
666
  return `${comparand(values)}${this.formatIn(ctx, values, negate)}`;
@@ -739,7 +736,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
739
736
  */
740
737
  jsonScalarParam(ctx, value) {
741
738
  if (value instanceof QueryRaw) {
742
- return this.addValue(ctx.values, value);
739
+ return this.rawFragment(ctx, value);
743
740
  }
744
741
  ctx.pushValue(JSON.stringify(value));
745
742
  // The placeholder for the value just pushed, so a named or numbered one is spelled correctly.
@@ -917,16 +914,14 @@ export class AbstractSqlDialect extends VectorSqlDialect {
917
914
  estimatedCount(_ctx, _entity) {
918
915
  throw new TypeError(`${this.dialectName} does not support estimatedCount`);
919
916
  }
920
- /** `$group` aggregate operator → SQL function name. An allowlist, not a formatter: the op key
921
- * comes from query data, so anything outside this map must be rejected rather than passed
922
- * through as a raw SQL function name. */
923
- static AGGREGATE_FN_MAP = new Map([
924
- ['$count', 'COUNT'],
925
- ['$sum', 'SUM'],
926
- ['$avg', 'AVG'],
927
- ['$min', 'MIN'],
928
- ['$max', 'MAX'],
929
- ]);
917
+ /** `$group` aggregate operator to SQL function name, over ops `resolveAggregateOp` has already allowlisted. */
918
+ static AGGREGATE_FN = {
919
+ $count: 'COUNT',
920
+ $sum: 'SUM',
921
+ $avg: 'AVG',
922
+ $min: 'MIN',
923
+ $max: 'MAX',
924
+ };
930
925
  aggregate(ctx, entity, q, opts = {}) {
931
926
  const meta = getMeta(entity);
932
927
  const tableName = this.escapedTableName(meta);
@@ -946,10 +941,7 @@ export class AbstractSqlDialect extends VectorSqlDialect {
946
941
  selectParts.push(columnName !== entry.alias ? `${escaped} ${this.escapeId(entry.alias)}` : escaped);
947
942
  }
948
943
  else {
949
- const sqlFn = AbstractSqlDialect.AGGREGATE_FN_MAP.get(entry.op);
950
- if (!sqlFn) {
951
- throw TypeError(`unsupported aggregate operator: ${entry.op}`);
952
- }
944
+ const sqlFn = AbstractSqlDialect.AGGREGATE_FN[entry.op];
953
945
  const sqlArg = entry.fieldRef === '*' ? '*' : this.escapeId(this.columnOf(meta, entry.fieldRef));
954
946
  const expr = `${sqlFn}(${entry.distinct ? 'DISTINCT ' : ''}${sqlArg})`;
955
947
  emittedColumns[entry.alias] = expr;
@@ -1238,14 +1230,12 @@ export class AbstractSqlDialect extends VectorSqlDialect {
1238
1230
  // Soft-delete (stamp only live rows) unless `hardDelete` is requested or the entity has no
1239
1231
  // soft-delete field (e.g. a cascade onto a non-soft-deletable child).
1240
1232
  if (!opts.hardDelete && meta.softDelete) {
1241
- const field = meta.fields[meta.softDelete];
1242
- if (field) {
1243
- const columnName = this.resolveColumnName(meta.softDelete, field);
1244
- ctx.append(`UPDATE ${tableName} SET ${this.escapeId(columnName)} = `);
1245
- this.formatPersistableValue(ctx, field, getSoftDeleteValue(field));
1246
- this.search(ctx, entity, q, opts);
1247
- return;
1248
- }
1233
+ const field = fieldOf(meta, meta.softDelete);
1234
+ const columnName = this.resolveColumnName(meta.softDelete, field);
1235
+ ctx.append(`UPDATE ${tableName} SET ${this.escapeId(columnName)} = `);
1236
+ this.formatPersistableValue(ctx, field, getSoftDeleteValue(field));
1237
+ this.search(ctx, entity, q, opts);
1238
+ return;
1249
1239
  }
1250
1240
  // Hard delete removes matching rows regardless of soft-delete state (keeps other filters, e.g. tenant).
1251
1241
  // Only rewrite the filters when there is a soft-delete filter to disable.
@@ -1764,9 +1754,6 @@ export class AbstractSqlDialect extends VectorSqlDialect {
1764
1754
  const phs = values.map((v) => this.addValue(ctx.values, v)).join(', ');
1765
1755
  return ` ${negate ? 'NOT IN' : 'IN'} (${phs})`;
1766
1756
  }
1767
- numericCast(expr) {
1768
- return expr;
1769
- }
1770
1757
  toString() {
1771
1758
  return this.dialectName;
1772
1759
  }
@@ -1,3 +1,4 @@
1
+ import { decodeWideNumber } from '../util/wideNumber.js';
1
2
  import { parseVectorLiteral } from './vectorCast.js';
2
3
  /**
3
4
  * Decode one non-null cell. Kept beside {@link HydrateKind} rather than inlined into the querier's
@@ -31,8 +32,7 @@ export function decodeColumn(value, kind) {
31
32
  return value;
32
33
  }
33
34
  if (kind === 'number') {
34
- const decoded = Number(text);
35
- return Number.isNaN(decoded) ? value : decoded;
35
+ return Number.isNaN(Number(text)) ? value : decodeWideNumber(text);
36
36
  }
37
37
  if (kind === 'json') {
38
38
  try {
@@ -38,8 +38,8 @@ export declare abstract class MergeSqlDialect extends AbstractSqlDialect {
38
38
  * holds it across both. Empty on Oracle, which does not have the hint and does not need it.
39
39
  */
40
40
  protected readonly mergeTargetHint: string;
41
- /** How the merge reports the row it wrote. Oracle has no such clause on a `MERGE` and omits it. */
42
- protected mergeReturning(expression: string): string;
41
+ /** How the merge reports the row it wrote: SQL Server's `OUTPUT`. Oracle has no such clause on a `MERGE`. */
42
+ protected abstract mergeReturning(expression: string): string;
43
43
  /** `MERGE` must be terminated on SQL Server; nothing else here cares. */
44
44
  protected readonly statementTerminator: string;
45
45
  }
@@ -80,10 +80,6 @@ export class MergeSqlDialect extends AbstractSqlDialect {
80
80
  * holds it across both. Empty on Oracle, which does not have the hint and does not need it.
81
81
  */
82
82
  mergeTargetHint = '';
83
- /** How the merge reports the row it wrote. Oracle has no such clause on a `MERGE` and omits it. */
84
- mergeReturning(expression) {
85
- return `RETURNING ${expression}`;
86
- }
87
83
  /** `MERGE` must be terminated on SQL Server; nothing else here cares. */
88
84
  statementTerminator = '';
89
85
  }
@@ -1,5 +1,5 @@
1
1
  import { getMeta } from '../entity/index.js';
2
- import { getFieldKeys } from '../util/index.js';
2
+ import { textSearchFields } from '../util/index.js';
3
3
  import { escapeMysqlSqlLiteral, escapeSingleQuotes } from '../util/sqlLiteral.js';
4
4
  import { AbstractSqlDialect } from './abstractSqlDialect.js';
5
5
  import { COUNT_ALIAS, JSON_PULL_ALIAS } from './aliases.js';
@@ -135,8 +135,7 @@ export class MysqlLikeSqlDialect extends AbstractSqlDialect {
135
135
  * `@Index([...], { type: 'fulltext' })`.
136
136
  */
137
137
  appendTextSearch(ctx, _entity, meta, search) {
138
- const searchFields = search.$fields ?? getFieldKeys(meta.fields);
139
- const columns = searchFields.map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])));
138
+ const columns = textSearchFields(meta, search).map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])));
140
139
  ctx.append(`MATCH(${columns.join(', ')}) AGAINST(`);
141
140
  ctx.addValue(search.$value);
142
141
  ctx.append(')');
@@ -93,6 +93,11 @@ export declare abstract class PgLikeSqlDialect extends AbstractSqlDialect {
93
93
  * ORDINALITY` keeps the surviving elements in their original order.
94
94
  */
95
95
  protected jsonPullKey(ctx: QueryContext, expr: string, escapedCol: string, key: string, value: unknown): string;
96
+ /**
97
+ * The plain values merge as one bound object; a `raw()` one is an SQL expression rather than JSON,
98
+ * so it merges through `JSONB_BUILD_OBJECT` and is evaluated in place - stringified with the rest,
99
+ * it would land as `{}`.
100
+ */
96
101
  protected jsonSet(ctx: QueryContext, expr: string, set: Record<string, unknown>, field?: FieldOptions): string;
97
102
  /** The only fragment that references `expr` twice - safe here because placeholders are numbered. */
98
103
  protected jsonPush(ctx: QueryContext, expr: string, push: Record<string, unknown>): string;
@@ -1,6 +1,6 @@
1
1
  import { canonicalToSql, fieldOptionsToCanonical } from '../schema/canonicalType.js';
2
2
  import { QueryRaw, } from '../type/index.js';
3
- import { hasVectorNear } from '../util/dialect.util.js';
3
+ import { hasVectorNear, textSearchFields } from '../util/dialect.util.js';
4
4
  import { raw } from '../util/raw.js';
5
5
  import { queryNarrowedTo } from '../util/relationQuery.util.js';
6
6
  import { escapeSingleQuotes } from '../util/sqlLiteral.js';
@@ -147,7 +147,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
147
147
  * rejects anything unparseable - including a plain two-word search.
148
148
  */
149
149
  appendTextSearch(ctx, _entity, meta, search) {
150
- const fields = (search.$fields ?? [])
150
+ const fields = textSearchFields(meta, search)
151
151
  .map((key) => this.escapeId(this.resolveColumnName(key, meta.fields[key])))
152
152
  .join(` || ' ' || `);
153
153
  // The config is bound once and its numbered placeholder reused by both calls.
@@ -213,8 +213,18 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
213
213
  const kept = `SELECT JSONB_AGG(${JSON_PULL_ALIAS}.val ORDER BY ${JSON_PULL_ALIAS}.ord) FROM JSONB_ARRAY_ELEMENTS(${escapedCol}->'${escapedKey}') WITH ORDINALITY AS ${JSON_PULL_ALIAS}(val, ord) WHERE ${JSON_PULL_ALIAS}.val <> ${this.jsonVal(ctx, value)}`;
214
214
  return `JSONB_SET(${expr}, '{${escapedKey}}', COALESCE((${kept}), '[]'::jsonb), false)`;
215
215
  }
216
+ /**
217
+ * The plain values merge as one bound object; a `raw()` one is an SQL expression rather than JSON,
218
+ * so it merges through `JSONB_BUILD_OBJECT` and is evaluated in place - stringified with the rest,
219
+ * it would land as `{}`.
220
+ */
216
221
  jsonSet(ctx, expr, set, field) {
217
- return `${jsonSetTarget(expr, field, `'{}'::jsonb`)} || ${this.jsonVal(ctx, set)}`;
222
+ const entries = Object.entries(set);
223
+ const merged = this.jsonVal(ctx, Object.fromEntries(entries.filter(([, value]) => !(value instanceof QueryRaw))));
224
+ const raws = entries.flatMap(([key, value]) => value instanceof QueryRaw
225
+ ? [` || JSONB_BUILD_OBJECT('${escapeSingleQuotes(key)}', ${this.rawFragment(ctx, value)})`]
226
+ : []);
227
+ return `${jsonSetTarget(expr, field, `'{}'::jsonb`)} || ${merged}${raws.join('')}`;
218
228
  }
219
229
  /** The only fragment that references `expr` twice - safe here because placeholders are numbered. */
220
230
  jsonPush(ctx, expr, push) {
@@ -236,7 +246,7 @@ export class PgLikeSqlDialect extends AbstractSqlDialect {
236
246
  */
237
247
  jsonVal(ctx, value, type = 'jsonb') {
238
248
  if (value instanceof QueryRaw)
239
- return this.addValue(ctx.values, value);
249
+ return this.rawFragment(ctx, value);
240
250
  if (value == null)
241
251
  return `${this.addValue(ctx.values, null)}::${type}`;
242
252
  const json = JSON.stringify(value);
@@ -1,4 +1,4 @@
1
- import { getMeta } from '../entity/index.js';
1
+ import { getMeta, relationOf } from '../entity/index.js';
2
2
  import { getKeys, getRelationRequestSummary, isToManyRelation, parseRelationAtKey, } from '../util/index.js';
3
3
  export const NO_JOINS = new Map();
4
4
  /**
@@ -54,9 +54,7 @@ function addJoin(joins, parent, key, relation, query, required, projected) {
54
54
  }
55
55
  function addPopulateJoins(joins, meta, populate, parent) {
56
56
  for (const key of getRelationRequestSummary(meta, populate).joinableKeys) {
57
- const relation = meta.relations[key];
58
- if (!relation)
59
- continue;
57
+ const relation = relationOf(meta, key);
60
58
  const { query, required } = parseRelationAtKey(key, populate);
61
59
  const join = addJoin(joins, parent, key, relation, query, required, true);
62
60
  addPopulateJoins(joins, join.meta, query.$populate, join);
@@ -1,3 +1,3 @@
1
1
  export * from './decorator/entity.js';
2
2
  export * from './decorator/members.js';
3
- export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, idOf, namesKey, soleIdOf, } from './metadata/definition.js';
3
+ export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, fieldOf, idOf, namesKey, relationOf, soleIdOf, } from './metadata/definition.js';
@@ -1,3 +1,3 @@
1
1
  export * from './decorator/entity.js';
2
2
  export * from './decorator/members.js';
3
- export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, idOf, namesKey, soleIdOf, } from './metadata/definition.js';
3
+ export { defineEntity, defineField, defineFilter, defineHook, defineId, defineIndex, defineRelation, getEntities, getMeta, removeEntity, assertSoleId, fieldOf, idOf, namesKey, relationOf, soleIdOf, } from './metadata/definition.js';
@@ -1,4 +1,4 @@
1
- import type { EntityData, EntityIndexInput, EntityMembers, EntityMeta, EntityOptions, FieldKey, FieldOptions, FilterOptions, HookEvent, IdKey, RelationOptions, Type, WrittenId } from '../../type/index.js';
1
+ import type { EntityData, EntityIndexInput, EntityMembers, EntityMeta, EntityOptions, FieldKey, FieldMeta, FieldOptions, FilterOptions, HookEvent, IdKey, RelationKey, RelationMeta, RelationOptions, Type, WrittenId } from '../../type/index.js';
2
2
  export declare function defineField<E>(entity: Type<E>, key: string, opts?: FieldOptions): EntityMeta<E>;
3
3
  export declare function defineId<E>(entity: Type<E>, key: string, opts: FieldOptions): EntityMeta<E>;
4
4
  export declare function defineRelation<E>(entity: Type<E>, key: string, opts: RelationOptions): EntityMeta<E>;
@@ -30,6 +30,10 @@ export declare function defineEntity<E>(entity: Type<E>, opts?: EntityOptions<E>
30
30
  export declare function assertSoleId<E>(meta: EntityMeta<E>, what: string): void;
31
31
  /** The entity's one primary key, for a path that cannot express a composite. See {@link assertSoleId}. */
32
32
  export declare function soleIdOf<E>(meta: EntityMeta<E>, what: string): IdKey<E>;
33
+ /** The field `key` names, for a caller that took `key` from the metadata itself. */
34
+ export declare function fieldOf<E>(meta: EntityMeta<E>, key: FieldKey<E>): FieldMeta;
35
+ /** The relation `key` names, for a caller that took `key` from the metadata itself. */
36
+ export declare function relationOf<E>(meta: EntityMeta<E>, key: RelationKey<E>): RelationMeta;
33
37
  /**
34
38
  * Whether the caller named every column of the row's primary key, so {@link idOf} can name the row.
35
39
  *
@@ -1,6 +1,6 @@
1
1
  import { SOFT_DELETE_FILTER } from '../../type/index.js';
2
2
  import { isInlinedExpression } from '../../util/field.util.js';
3
- import { entityName, fieldOptionConflict, getKeys, ddlText, hasKeys, isToManyRelation, lowerFirst, normalizeIndexColumn, upperFirst, } from '../../util/index.js';
3
+ import { entityName, fieldOptionConflict, getKeys, ddlText, hasKeys, isToManyRelation, lowerFirst, normalizeIndexColumn, upperFirst, definedEntries, } from '../../util/index.js';
4
4
  import { ownRegistrations } from '../decorator/bag.js';
5
5
  /**
6
6
  * A map held on `globalThis` through the global symbol registry, so a single one survives multiple
@@ -95,9 +95,7 @@ export function defineFilter(entity, name, opts) {
95
95
  * API converge on one registration path before anything is finalized.
96
96
  */
97
97
  export function applyMembers(entity, specs) {
98
- for (const [key, spec] of Object.entries(specs?.fields ?? {})) {
99
- if (!spec)
100
- continue;
98
+ for (const [key, spec] of definedEntries(specs?.fields ?? {})) {
101
99
  if (spec.isId) {
102
100
  defineId(entity, key, spec);
103
101
  }
@@ -105,12 +103,11 @@ export function applyMembers(entity, specs) {
105
103
  defineField(entity, key, spec);
106
104
  }
107
105
  }
108
- for (const [key, spec] of Object.entries(specs?.relations ?? {})) {
109
- if (spec)
110
- defineRelation(entity, key, spec);
106
+ for (const [key, spec] of definedEntries(specs?.relations ?? {})) {
107
+ defineRelation(entity, key, spec);
111
108
  }
112
- for (const [event, methodNames] of Object.entries(specs?.hooks ?? {})) {
113
- for (const methodName of methodNames ?? []) {
109
+ for (const [event, methodNames] of definedEntries(specs?.hooks ?? {})) {
110
+ for (const methodName of methodNames) {
114
111
  defineHook(entity, methodName, event);
115
112
  }
116
113
  }
@@ -143,9 +140,8 @@ export function defineEntity(entity, opts = {}) {
143
140
  for (const index of opts.indexes ?? []) {
144
141
  defineIndex(entity, index);
145
142
  }
146
- for (const [name, filter] of Object.entries(opts.filters ?? {})) {
147
- if (filter)
148
- defineFilter(entity, name, filter);
143
+ for (const [name, filter] of definedEntries(opts.filters ?? {})) {
144
+ defineFilter(entity, name, filter);
149
145
  }
150
146
  if (!hasKeys(meta.fields)) {
151
147
  throw TypeError(`'${entity.name}' must have fields`);
@@ -219,6 +215,22 @@ export function soleIdOf(meta, what) {
219
215
  assertSoleId(meta, what);
220
216
  return meta.ids[0];
221
217
  }
218
+ /** The field `key` names, for a caller that took `key` from the metadata itself. */
219
+ export function fieldOf(meta, key) {
220
+ const field = meta.fields[key];
221
+ if (!field) {
222
+ throw new TypeError(`'${meta.entity.name}' has no field '${key}'`);
223
+ }
224
+ return field;
225
+ }
226
+ /** The relation `key` names, for a caller that took `key` from the metadata itself. */
227
+ export function relationOf(meta, key) {
228
+ const relation = meta.relations[key];
229
+ if (!relation) {
230
+ throw new TypeError(`'${meta.entity.name}' has no relation '${key}'`);
231
+ }
232
+ return relation;
233
+ }
222
234
  /**
223
235
  * Whether the caller named every column of the row's primary key, so {@link idOf} can name the row.
224
236
  *
@@ -295,11 +307,9 @@ export function getMeta(entity) {
295
307
  return fillRelations(meta);
296
308
  }
297
309
  function fillRelations(meta) {
298
- for (const relKey in meta.relations) {
310
+ for (const [relKey, relation] of definedEntries(meta.relations)) {
299
311
  // The authored view: `mappedBy` may still be the callback and `references` unset until this settles them.
300
- const relOpts = meta.relations[relKey];
301
- if (!relOpts)
302
- continue;
312
+ const relOpts = relation;
303
313
  const at = `'${meta.entity.name}.${relKey}'`;
304
314
  if (relOpts.mappedBy) {
305
315
  fillInverseSide(at, meta, relOpts);
@@ -355,7 +365,7 @@ function fillOwningSide(at, meta, relKey, relOpts) {
355
365
  for (const { local, foreign } of relOpts.references) {
356
366
  fields[local] ??= {
357
367
  name: local,
358
- type: relMeta.fields[foreign]?.type ?? Number,
368
+ type: fieldOf(relMeta, foreign).type ?? Number,
359
369
  references: relOpts.entity,
360
370
  referencedKey: foreign,
361
371
  typeFromReference: true,
@@ -405,9 +415,8 @@ function fillInverseSide(at, meta, relOpts) {
405
415
  * own cardinality and `cascade`.
406
416
  */
407
417
  function fillForeignKeyRelations(meta) {
408
- const joined = new Set(getKeys(meta.relations).flatMap((key) => meta.relations[key]?.references.map(({ local }) => local) ?? []));
409
- for (const fieldKey of getKeys(meta.fields)) {
410
- const references = meta.fields[fieldKey]?.references;
418
+ const joined = new Set(definedEntries(meta.relations).flatMap(([, relation]) => relation.references.map(({ local }) => local)));
419
+ for (const [fieldKey, { references }] of definedEntries(meta.fields)) {
411
420
  if (!references || joined.has(fieldKey))
412
421
  continue;
413
422
  const target = ensureMeta(references());
@@ -437,7 +446,7 @@ function fillForeignKeyRelations(meta) {
437
446
  }
438
447
  /** `<entityName><IdColumn>`, not the `<relationKey>Id` an owning to-one derives: a junction row has no relation key to borrow from. */
439
448
  function junctionColumn(meta, idKey) {
440
- return lowerFirst(entityName(meta)) + upperFirst(meta.fields[idKey]?.name ?? idKey);
449
+ return lowerFirst(entityName(meta)) + upperFirst(fieldOf(meta, idKey).name ?? idKey);
441
450
  }
442
451
  /** A callback only reads one property off the key map, and that property is the key, so one serves every entity. */
443
452
  const RELATION_KEY_MAP = new Proxy({}, { get: (_, key) => key });
@@ -470,11 +479,8 @@ function extendMeta(target, source) {
470
479
  if (source.hooks) {
471
480
  if (!target.hooks)
472
481
  target.hooks = {};
473
- for (const event of Object.keys(source.hooks)) {
474
- const sourceList = source.hooks[event];
475
- if (sourceList?.length) {
476
- target.hooks[event] = [...sourceList, ...(target.hooks[event] ?? [])];
477
- }
482
+ for (const [event, sourceList] of definedEntries(source.hooks)) {
483
+ target.hooks[event] = [...sourceList, ...(target.hooks[event] ?? [])];
478
484
  }
479
485
  }
480
486
  }
@@ -1,3 +1,2 @@
1
1
  export * from './libsqlDialect.js';
2
- export * from './libsqlQuerier.js';
3
2
  export * from './libsqlQuerierPool.js';
@@ -1,3 +1,2 @@
1
1
  export * from './libsqlDialect.js';
2
- export * from './libsqlQuerier.js';
3
2
  export * from './libsqlQuerierPool.js';
@@ -1,21 +1,19 @@
1
1
  import type { Config } from '@libsql/client';
2
- import type { HranaClient, HranaQuerierConnectionOptions } from '../sqlite/hranaQuerier.js';
2
+ import { type HranaClient, HranaQuerier } from '../sqlite/hranaQuerier.js';
3
3
  import { AbstractHranaQuerierPool } from '../sqlite/hranaQuerierPool.js';
4
4
  import type { ExtraOptions } from '../type/index.js';
5
5
  import { LibsqlDialect } from './libsqlDialect.js';
6
- import { LibsqlQuerier } from './libsqlQuerier.js';
7
6
  /** Embedded replica: local `file:` DB + `syncUrl` remote - DDL should run on the remote (sqld). */
8
7
  export declare function libsqlUseRemoteForMigrations(config: Pick<Config, 'url' | 'syncUrl'>): boolean;
9
- export declare class LibsqlQuerierPool extends AbstractHranaQuerierPool<LibsqlQuerier, LibsqlDialect> {
8
+ export declare class LibsqlQuerierPool extends AbstractHranaQuerierPool<LibsqlDialect> {
10
9
  private readonly conf;
11
10
  constructor(conf: Config, extra?: ExtraOptions);
12
11
  protected openClient(): Promise<HranaClient>;
13
- protected buildQuerier(client: HranaClient, connection?: HranaQuerierConnectionOptions): LibsqlQuerier;
14
12
  /**
15
13
  * For embedded replicas (`file:` + `syncUrl`), returns a querier connected to `syncUrl` so migrations hit sqld.
16
14
  * Otherwise same as `getQuerier`. The migrator calls this for `up`/`down`, `syncForce`, and `autoSync` DDL.
17
15
  */
18
- getMigrationQuerier(): Promise<LibsqlQuerier>;
16
+ getMigrationQuerier(): Promise<HranaQuerier>;
19
17
  /** Imported on use, so `uql-orm/libsql` loads without the optional `@libsql/client` peer installed. */
20
18
  private createClient;
21
19
  }
@@ -1,7 +1,7 @@
1
1
  import { dialectOptionsFrom } from '../dialect/abstractDialect.js';
2
+ import { HranaQuerier } from '../sqlite/hranaQuerier.js';
2
3
  import { AbstractHranaQuerierPool } from '../sqlite/hranaQuerierPool.js';
3
4
  import { LibsqlDialect } from './libsqlDialect.js';
4
- import { LibsqlQuerier } from './libsqlQuerier.js';
5
5
  /** Embedded replica: local `file:` DB + `syncUrl` remote - DDL should run on the remote (sqld). */
6
6
  export function libsqlUseRemoteForMigrations(config) {
7
7
  return Boolean(config.syncUrl && config.url.startsWith('file:'));
@@ -20,9 +20,6 @@ export class LibsqlQuerierPool extends AbstractHranaQuerierPool {
20
20
  openClient() {
21
21
  return this.createClient(this.conf);
22
22
  }
23
- buildQuerier(client, connection) {
24
- return new LibsqlQuerier(client, this.dialect, this.extra, connection);
25
- }
26
23
  /**
27
24
  * For embedded replicas (`file:` + `syncUrl`), returns a querier connected to `syncUrl` so migrations hit sqld.
28
25
  * Otherwise same as `getQuerier`. The migrator calls this for `up`/`down`, `syncForce`, and `autoSync` DDL.
@@ -32,7 +29,7 @@ export class LibsqlQuerierPool extends AbstractHranaQuerierPool {
32
29
  return this.getQuerier();
33
30
  }
34
31
  const remote = await this.createClient(remoteMigrationClientConfig(this.conf));
35
- return this.buildQuerier(remote, { closeClientOnRelease: true });
32
+ return new HranaQuerier(remote, this.dialect, this.extra, { closeClientOnRelease: true });
36
33
  }
37
34
  /** Imported on use, so `uql-orm/libsql` loads without the optional `@libsql/client` peer installed. */
38
35
  async createClient(conf) {
@@ -1,9 +1,6 @@
1
1
  import type { PoolConnection } from 'mariadb';
2
2
  import { AbstractPoolQuerier } from '../querier/abstractPoolQuerier.js';
3
- import type { ExtraOptions } from '../type/index.js';
4
- import type { MariaDialect } from './mariaDialect.js';
5
3
  export declare class MariadbQuerier extends AbstractPoolQuerier<PoolConnection> {
6
- constructor(connect: () => Promise<PoolConnection>, dialect: MariaDialect, extra?: ExtraOptions);
7
4
  internalAll<T>(query: string, values?: unknown[]): Promise<T[]>;
8
5
  internalRun(query: string, values?: unknown[]): Promise<import("../type/query.js").QueryUpdateResult>;
9
6
  internalStream<T>(query: string, values?: unknown[]): AsyncGenerator<Awaited<T>, void, unknown>;