turbine-orm 0.81.0 → 0.90.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 (295) hide show
  1. package/README.md +26 -25
  2. package/dist/checkout.d.ts +27 -2
  3. package/dist/checkout.js +75 -4
  4. package/dist/cjs/checkout.d.ts +27 -2
  5. package/dist/cjs/checkout.js +76 -3
  6. package/dist/cjs/cli/code-first-tags.d.ts +62 -0
  7. package/dist/cjs/cli/code-first-tags.js +124 -0
  8. package/dist/cjs/cli/compile-query.js +9 -0
  9. package/dist/cjs/cli/config.d.ts +35 -6
  10. package/dist/cjs/cli/config.js +17 -1
  11. package/dist/cjs/cli/destructive.d.ts +7 -4
  12. package/dist/cjs/cli/destructive.js +224 -20
  13. package/dist/cjs/cli/error-catalog.js +36 -0
  14. package/dist/cjs/cli/error-text.d.ts +15 -0
  15. package/dist/cjs/cli/error-text.js +40 -0
  16. package/dist/cjs/cli/index.d.ts +62 -4
  17. package/dist/cjs/cli/index.js +568 -108
  18. package/dist/cjs/cli/local-server-guard.d.ts +53 -0
  19. package/dist/cjs/cli/local-server-guard.js +119 -0
  20. package/dist/cjs/cli/local-server-output.d.ts +41 -0
  21. package/dist/cjs/cli/local-server-output.js +103 -0
  22. package/dist/cjs/cli/mcp.d.ts +8 -0
  23. package/dist/cjs/cli/mcp.js +121 -32
  24. package/dist/cjs/cli/migrate.d.ts +113 -5
  25. package/dist/cjs/cli/migrate.js +270 -21
  26. package/dist/cjs/cli/observe.d.ts +6 -1
  27. package/dist/cjs/cli/observe.js +85 -55
  28. package/dist/cjs/cli/pii-predicate-guard.d.ts +43 -23
  29. package/dist/cjs/cli/pii-predicate-guard.js +98 -37
  30. package/dist/cjs/cli/prisma-resolve.js +17 -13
  31. package/dist/cjs/cli/prisma-schema.js +12 -4
  32. package/dist/cjs/cli/studio-ui.generated.js +1 -1
  33. package/dist/cjs/cli/studio.d.ts +14 -2
  34. package/dist/cjs/cli/studio.js +244 -69
  35. package/dist/cjs/cli/ui.d.ts +1 -1
  36. package/dist/cjs/client.d.ts +558 -85
  37. package/dist/cjs/client.js +1270 -395
  38. package/dist/cjs/connection-guard.d.ts +13 -0
  39. package/dist/cjs/connection-guard.js +28 -0
  40. package/dist/cjs/connection-url.d.ts +51 -16
  41. package/dist/cjs/connection-url.js +67 -34
  42. package/dist/cjs/diagnostics.d.ts +81 -0
  43. package/dist/cjs/diagnostics.js +147 -0
  44. package/dist/cjs/dialect.d.ts +449 -20
  45. package/dist/cjs/dialect.js +117 -76
  46. package/dist/cjs/engine-config.d.ts +7 -6
  47. package/dist/cjs/errors.d.ts +126 -6
  48. package/dist/cjs/errors.js +256 -13
  49. package/dist/cjs/generate.d.ts +57 -7
  50. package/dist/cjs/generate.js +635 -279
  51. package/dist/cjs/global-filters-config.d.ts +59 -0
  52. package/dist/cjs/global-filters-config.js +367 -0
  53. package/dist/cjs/index.d.ts +9 -4
  54. package/dist/cjs/index.js +10 -2
  55. package/dist/cjs/introspect.d.ts +31 -6
  56. package/dist/cjs/introspect.js +108 -50
  57. package/dist/cjs/log-codes.d.ts +12 -0
  58. package/dist/cjs/log-codes.js +77 -0
  59. package/dist/cjs/logger.d.ts +87 -0
  60. package/dist/cjs/logger.js +98 -0
  61. package/dist/cjs/mssql.d.ts +8 -5
  62. package/dist/cjs/mssql.js +352 -65
  63. package/dist/cjs/mysql.d.ts +3 -5
  64. package/dist/cjs/mysql.js +420 -70
  65. package/dist/cjs/nested-write.d.ts +3 -0
  66. package/dist/cjs/nested-write.js +179 -114
  67. package/dist/cjs/pipeline-submittable.d.ts +12 -0
  68. package/dist/cjs/pipeline-submittable.js +118 -44
  69. package/dist/cjs/pipeline.js +21 -26
  70. package/dist/cjs/powdb-introspect.d.ts +5 -2
  71. package/dist/cjs/powdb-introspect.js +20 -15
  72. package/dist/cjs/powdb-shared.d.ts +36 -5
  73. package/dist/cjs/powdb-shared.js +67 -8
  74. package/dist/cjs/powdb.d.ts +4 -0
  75. package/dist/cjs/powdb.js +183 -51
  76. package/dist/cjs/powql.d.ts +394 -51
  77. package/dist/cjs/powql.js +1829 -284
  78. package/dist/cjs/prisma-compat.d.ts +23 -15
  79. package/dist/cjs/prisma-compat.js +507 -372
  80. package/dist/cjs/query/aggregates.d.ts +17 -1
  81. package/dist/cjs/query/aggregates.js +261 -29
  82. package/dist/cjs/query/batched-loader.d.ts +25 -6
  83. package/dist/cjs/query/batched-loader.js +103 -20
  84. package/dist/cjs/query/builder.d.ts +325 -184
  85. package/dist/cjs/query/builder.js +1452 -490
  86. package/dist/cjs/query/column-ref.d.ts +61 -0
  87. package/dist/cjs/query/column-ref.js +73 -0
  88. package/dist/cjs/query/compound-unique.d.ts +21 -0
  89. package/dist/cjs/query/compound-unique.js +98 -18
  90. package/dist/cjs/query/deferred.d.ts +53 -16
  91. package/dist/cjs/query/expr.d.ts +217 -0
  92. package/dist/cjs/query/expr.js +859 -0
  93. package/dist/cjs/query/filters.d.ts +155 -53
  94. package/dist/cjs/query/filters.js +613 -76
  95. package/dist/cjs/query/index.d.ts +2 -0
  96. package/dist/cjs/query/index.js +7 -1
  97. package/dist/cjs/query/json-value.d.ts +43 -0
  98. package/dist/cjs/query/json-value.js +59 -0
  99. package/dist/cjs/query/normalize-args.d.ts +87 -0
  100. package/dist/cjs/query/normalize-args.js +527 -0
  101. package/dist/cjs/query/option-surface.d.ts +16 -4
  102. package/dist/cjs/query/option-surface.js +57 -14
  103. package/dist/cjs/query/relation-names.d.ts +14 -0
  104. package/dist/cjs/query/relation-names.js +77 -18
  105. package/dist/cjs/query/relations.d.ts +30 -3
  106. package/dist/cjs/query/relations.js +219 -63
  107. package/dist/cjs/query/row-lock.d.ts +49 -0
  108. package/dist/cjs/query/row-lock.js +138 -0
  109. package/dist/cjs/query/sql-comment.d.ts +161 -0
  110. package/dist/cjs/query/sql-comment.js +381 -0
  111. package/dist/cjs/query/stream-idle.d.ts +132 -0
  112. package/dist/cjs/query/stream-idle.js +212 -0
  113. package/dist/cjs/query/table-client.d.ts +101 -0
  114. package/dist/cjs/query/table-client.js +74 -0
  115. package/dist/cjs/query/types.d.ts +677 -298
  116. package/dist/cjs/query/utils.d.ts +105 -6
  117. package/dist/cjs/query/utils.js +426 -19
  118. package/dist/cjs/query/warn-registry.d.ts +18 -0
  119. package/dist/cjs/query/warn-registry.js +18 -0
  120. package/dist/cjs/query/where-compile.d.ts +138 -14
  121. package/dist/cjs/query/where-compile.js +513 -29
  122. package/dist/cjs/query/where.d.ts +159 -59
  123. package/dist/cjs/query/where.js +716 -246
  124. package/dist/cjs/query/writes.d.ts +112 -50
  125. package/dist/cjs/query/writes.js +1498 -200
  126. package/dist/cjs/query-events.d.ts +4 -2
  127. package/dist/cjs/query-events.js +3 -1
  128. package/dist/cjs/realtime.d.ts +7 -3
  129. package/dist/cjs/realtime.js +13 -2
  130. package/dist/cjs/schema-builder.d.ts +55 -4
  131. package/dist/cjs/schema-builder.js +382 -18
  132. package/dist/cjs/schema-metadata.d.ts +21 -1
  133. package/dist/cjs/schema-metadata.js +29 -7
  134. package/dist/cjs/schema-sql.d.ts +75 -5
  135. package/dist/cjs/schema-sql.js +497 -45
  136. package/dist/cjs/schema.d.ts +26 -5
  137. package/dist/cjs/schema.js +110 -13
  138. package/dist/cjs/sql-placeholders.d.ts +56 -0
  139. package/dist/cjs/sql-placeholders.js +204 -0
  140. package/dist/cjs/sqlite.d.ts +75 -20
  141. package/dist/cjs/sqlite.js +593 -95
  142. package/dist/cjs/supplied-pool-types.d.ts +48 -0
  143. package/dist/cjs/supplied-pool-types.js +256 -0
  144. package/dist/cjs/transaction-control.d.ts +51 -0
  145. package/dist/cjs/transaction-control.js +316 -0
  146. package/dist/cjs/transaction-state.d.ts +342 -0
  147. package/dist/cjs/transaction-state.js +707 -0
  148. package/dist/cjs/typed-sql.d.ts +37 -3
  149. package/dist/cjs/typed-sql.js +102 -8
  150. package/dist/cli/code-first-tags.d.ts +62 -0
  151. package/dist/cli/code-first-tags.js +120 -0
  152. package/dist/cli/compile-query.js +9 -0
  153. package/dist/cli/config.d.ts +35 -6
  154. package/dist/cli/config.js +16 -1
  155. package/dist/cli/destructive.d.ts +7 -4
  156. package/dist/cli/destructive.js +224 -20
  157. package/dist/cli/error-catalog.js +36 -0
  158. package/dist/cli/error-text.d.ts +15 -0
  159. package/dist/cli/error-text.js +37 -0
  160. package/dist/cli/index.d.ts +62 -4
  161. package/dist/cli/index.js +569 -112
  162. package/dist/cli/local-server-guard.d.ts +53 -0
  163. package/dist/cli/local-server-guard.js +113 -0
  164. package/dist/cli/local-server-output.d.ts +41 -0
  165. package/dist/cli/local-server-output.js +98 -0
  166. package/dist/cli/mcp.d.ts +8 -0
  167. package/dist/cli/mcp.js +121 -34
  168. package/dist/cli/migrate.d.ts +113 -5
  169. package/dist/cli/migrate.js +261 -21
  170. package/dist/cli/observe.d.ts +6 -1
  171. package/dist/cli/observe.js +84 -54
  172. package/dist/cli/pii-predicate-guard.d.ts +43 -23
  173. package/dist/cli/pii-predicate-guard.js +100 -35
  174. package/dist/cli/prisma-resolve.js +15 -11
  175. package/dist/cli/prisma-schema.js +12 -4
  176. package/dist/cli/studio-ui.generated.js +1 -1
  177. package/dist/cli/studio.d.ts +14 -2
  178. package/dist/cli/studio.js +246 -71
  179. package/dist/cli/ui.d.ts +1 -1
  180. package/dist/client.d.ts +558 -85
  181. package/dist/client.js +1275 -400
  182. package/dist/connection-guard.d.ts +13 -0
  183. package/dist/connection-guard.js +27 -0
  184. package/dist/connection-url.d.ts +51 -16
  185. package/dist/connection-url.js +63 -34
  186. package/dist/diagnostics.d.ts +81 -0
  187. package/dist/diagnostics.js +144 -0
  188. package/dist/dialect.d.ts +449 -20
  189. package/dist/dialect.js +115 -43
  190. package/dist/engine-config.d.ts +7 -6
  191. package/dist/errors.d.ts +126 -6
  192. package/dist/errors.js +252 -12
  193. package/dist/generate.d.ts +57 -7
  194. package/dist/generate.js +635 -281
  195. package/dist/global-filters-config.d.ts +59 -0
  196. package/dist/global-filters-config.js +361 -0
  197. package/dist/index.d.ts +9 -4
  198. package/dist/index.js +4 -2
  199. package/dist/introspect.d.ts +31 -6
  200. package/dist/introspect.js +106 -50
  201. package/dist/log-codes.d.ts +12 -0
  202. package/dist/log-codes.js +74 -0
  203. package/dist/logger.d.ts +87 -0
  204. package/dist/logger.js +93 -0
  205. package/dist/mssql.d.ts +8 -5
  206. package/dist/mssql.js +354 -67
  207. package/dist/mysql.d.ts +3 -5
  208. package/dist/mysql.js +423 -73
  209. package/dist/nested-write.d.ts +3 -0
  210. package/dist/nested-write.js +177 -112
  211. package/dist/pipeline-submittable.d.ts +12 -0
  212. package/dist/pipeline-submittable.js +117 -44
  213. package/dist/pipeline.js +21 -26
  214. package/dist/powdb-introspect.d.ts +5 -2
  215. package/dist/powdb-introspect.js +21 -16
  216. package/dist/powdb-shared.d.ts +36 -5
  217. package/dist/powdb-shared.js +65 -8
  218. package/dist/powdb.d.ts +4 -0
  219. package/dist/powdb.js +183 -51
  220. package/dist/powql.d.ts +394 -51
  221. package/dist/powql.js +1836 -291
  222. package/dist/prisma-compat.d.ts +23 -15
  223. package/dist/prisma-compat.js +508 -373
  224. package/dist/query/aggregates.d.ts +17 -1
  225. package/dist/query/aggregates.js +263 -32
  226. package/dist/query/batched-loader.d.ts +25 -6
  227. package/dist/query/batched-loader.js +101 -21
  228. package/dist/query/builder.d.ts +325 -184
  229. package/dist/query/builder.js +1458 -495
  230. package/dist/query/column-ref.d.ts +61 -0
  231. package/dist/query/column-ref.js +66 -0
  232. package/dist/query/compound-unique.d.ts +21 -0
  233. package/dist/query/compound-unique.js +97 -19
  234. package/dist/query/deferred.d.ts +53 -16
  235. package/dist/query/expr.d.ts +217 -0
  236. package/dist/query/expr.js +848 -0
  237. package/dist/query/filters.d.ts +155 -53
  238. package/dist/query/filters.js +597 -72
  239. package/dist/query/index.d.ts +2 -0
  240. package/dist/query/index.js +4 -0
  241. package/dist/query/json-value.d.ts +43 -0
  242. package/dist/query/json-value.js +54 -0
  243. package/dist/query/normalize-args.d.ts +87 -0
  244. package/dist/query/normalize-args.js +517 -0
  245. package/dist/query/option-surface.d.ts +16 -4
  246. package/dist/query/option-surface.js +56 -13
  247. package/dist/query/relation-names.d.ts +14 -0
  248. package/dist/query/relation-names.js +77 -19
  249. package/dist/query/relations.d.ts +30 -3
  250. package/dist/query/relations.js +220 -67
  251. package/dist/query/row-lock.d.ts +49 -0
  252. package/dist/query/row-lock.js +131 -0
  253. package/dist/query/sql-comment.d.ts +161 -0
  254. package/dist/query/sql-comment.js +374 -0
  255. package/dist/query/stream-idle.d.ts +132 -0
  256. package/dist/query/stream-idle.js +203 -0
  257. package/dist/query/table-client.d.ts +101 -0
  258. package/dist/query/table-client.js +70 -0
  259. package/dist/query/types.d.ts +677 -298
  260. package/dist/query/utils.d.ts +105 -6
  261. package/dist/query/utils.js +414 -18
  262. package/dist/query/warn-registry.d.ts +18 -0
  263. package/dist/query/warn-registry.js +18 -0
  264. package/dist/query/where-compile.d.ts +138 -14
  265. package/dist/query/where-compile.js +508 -31
  266. package/dist/query/where.d.ts +159 -59
  267. package/dist/query/where.js +711 -248
  268. package/dist/query/writes.d.ts +112 -50
  269. package/dist/query/writes.js +1496 -202
  270. package/dist/query-events.d.ts +4 -2
  271. package/dist/query-events.js +3 -1
  272. package/dist/realtime.d.ts +7 -3
  273. package/dist/realtime.js +13 -2
  274. package/dist/schema-builder.d.ts +55 -4
  275. package/dist/schema-builder.js +381 -18
  276. package/dist/schema-metadata.d.ts +21 -1
  277. package/dist/schema-metadata.js +28 -7
  278. package/dist/schema-sql.d.ts +75 -5
  279. package/dist/schema-sql.js +494 -44
  280. package/dist/schema.d.ts +26 -5
  281. package/dist/schema.js +109 -13
  282. package/dist/sql-placeholders.d.ts +56 -0
  283. package/dist/sql-placeholders.js +200 -0
  284. package/dist/sqlite.d.ts +75 -20
  285. package/dist/sqlite.js +597 -99
  286. package/dist/supplied-pool-types.d.ts +48 -0
  287. package/dist/supplied-pool-types.js +247 -0
  288. package/dist/transaction-control.d.ts +51 -0
  289. package/dist/transaction-control.js +311 -0
  290. package/dist/transaction-state.d.ts +342 -0
  291. package/dist/transaction-state.js +696 -0
  292. package/dist/typed-sql.d.ts +37 -3
  293. package/dist/typed-sql.js +100 -8
  294. package/package.json +7 -4
  295. package/skills/turbine-orm/SKILL.md +56 -6
@@ -12,16 +12,7 @@
12
12
  */
13
13
  import type { PgCompatPool } from '../pg-types.js';
14
14
  import type { SchemaMetadata } from '../schema.js';
15
- import type { AggregateArgs, AggregateResult, CountArgs, CreateArgs, CreateManyArgs, DeleteArgs, DeleteManyArgs, FieldResult, FindManyArgs, FindManyStreamArgs, FindUniqueArgs, GroupByArgs, GroupByResult, QueryResult, TypedWithClause, UpdateArgs, UpdateManyArgs, UpsertArgs, WithClause } from './types.js';
16
- /**
17
- * Discard the memoized cross-check environment so the next cache hit re-reads
18
- * `process.env`.
19
- *
20
- * @internal Exposed for the tests that toggle these variables in-process (see
21
- * {@link crossCheckEnv}). Production code sets them before the first query and
22
- * never again.
23
- */
24
- export declare function resetCacheCrossCheckEnv(): void;
15
+ import type { AggregateArgs, AggregateResultOf, CountArgs, CreateArgs, CreateManyArgs, DefaultInputTypes, DeleteArgs, DeleteManyArgs, FieldResult, FindManyArgs, FindManyStreamArgs, FindUniqueArgs, GroupByArgs, GroupByResult, QueryResult, TableInputTypes, TypedWithClause, UpdateArgs, UpdateManyArgs, UpsertArgs, WithClause } from './types.js';
25
16
  /**
26
17
  * Marginal cost of keeping a to-one relation on the JOIN plan, per parent row.
27
18
  *
@@ -188,7 +179,7 @@ export declare function unlockNestedWriteTx<X extends {
188
179
  }>(tx: X): X;
189
180
  export type { DeferredQuery, MiddlewareFn, QueryEvent, QueryEventListener, QueryInterfaceOptions, ReselectExecutor, TemporalInfinityReading, } from './deferred.js';
190
181
  import type { DeferredQuery, MiddlewareFn, QueryInterfaceOptions } from './deferred.js';
191
- export declare class QueryInterface<T extends object, R extends object = {}> {
182
+ export declare class QueryInterface<T extends object, R extends object = {}, M extends TableInputTypes = DefaultInputTypes<T, R>> {
192
183
  private readonly pool;
193
184
  private readonly table;
194
185
  private readonly schema;
@@ -208,6 +199,13 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
208
199
  * inline, not through the top-level cache).
209
200
  */
210
201
  private lastCacheHit;
202
+ /**
203
+ * The params the build closure pushed on the most recent MISS, held until
204
+ * {@link crossCheckCache} compares them with the collected params and clears
205
+ * them. `undefined` after a hit. Same single-flag reasoning as
206
+ * {@link lastCacheHit}.
207
+ */
208
+ private lastMissParams;
211
209
  /**
212
210
  * Set while a build closure runs when the statement's WHERE (or HAVING)
213
211
  * carries a caller-written `AND`/`OR` combinator array, i.e. when its SQL text
@@ -219,6 +217,21 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
219
217
  */
220
218
  private variableArityShape;
221
219
  private readonly middlewares;
220
+ /** The client's resolved `diagnostics` (see diagnostics.ts), fixed for this instance's life. */
221
+ private readonly diagnostics;
222
+ /** `streamIdleTimeoutMs`: how long a cursor stream may wait for its consumer. `0` disables. */
223
+ private readonly streamIdleTimeoutMs;
224
+ /** `sqlComment`, resolved; `undefined` when statements carry no comment (one falsy check per send). */
225
+ private readonly sqlCommenter;
226
+ /** Where this instance's log lines go: the client's `logger`, else the console logger. */
227
+ private readonly logger;
228
+ /**
229
+ * {@link logger} when `diagnostics.advice` is on, else `undefined`. Every
230
+ * per-query advice site starts with `const log = this.advice; if (!log)
231
+ * return;`, so with advice off a site costs one property read and builds no
232
+ * message.
233
+ */
234
+ private readonly advice;
222
235
  private readonly defaultLimit?;
223
236
  private readonly warnOnUnlimited;
224
237
  private readonly scopedConnect;
@@ -320,7 +333,6 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
320
333
  * the audit's "Set<string>" guidance and leaves room for future
321
334
  * cross-table sharing.
322
335
  */
323
- private readonly warnedTables;
324
336
  /** Cache hit/miss counters for diagnostics */
325
337
  private cacheHits;
326
338
  private cacheMisses;
@@ -341,6 +353,10 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
341
353
  * to Date as well (otherwise nested dates leak through as strings).
342
354
  */
343
355
  private readonly camelDateFieldCache;
356
+ /** Per-table memo of {@link cellKindOf}, keyed by column name and field name. */
357
+ private readonly cellKindCache;
358
+ /** The dialect decode of each {@link CELL_DIALECT} column, by table, then by column and field name. */
359
+ private readonly dialectDecodeCache;
344
360
  /**
345
361
  * Per-table memo of `Object.entries(meta.relations)`, consumed by the nested
346
362
  * row parser (see `getRelationEntries` in relations.ts). Same rationale and
@@ -406,7 +422,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
406
422
  private readonly ctx;
407
423
  constructor(pool: PgCompatPool, table: string, schema: SchemaMetadata, middlewares?: MiddlewareFn[], options?: QueryInterfaceOptions);
408
424
  /**
409
- * Dev-only, once per table: the columns whose database type is absent from
425
+ * Advice (`diagnostics.advice`), once per table: the columns whose database type is absent from
410
426
  * BOTH the column entry and the table-level type maps, the residual case
411
427
  * after the two-source resolution above.
412
428
  *
@@ -431,17 +447,17 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
431
447
  * Postgres rejects with `22007 invalid input syntax for type time`.
432
448
  * - `timestamptz` and every non-temporal type: unaffected.
433
449
  *
434
- * PostgreSQL only: the UTC bind rewrite is Postgres-gated (see
435
- * `utcDateTimeWrites` in writes.ts), so on the other engines a missing type
436
- * changes nothing about how a `Date` is bound. Suppressed under
437
- * `NODE_ENV=production` like the other dev diagnostics and deduped through
438
- * the shared registry, so a hot table logs one line for the process.
450
+ * PostgreSQL only: the zone-less `timestamp` rewrite is Postgres-gated (see
451
+ * `utcDateTimeRewrite` in where.ts), so on the other engines a missing type
452
+ * costs only the `date` rewrite. Silent when `diagnostics.advice` is off
453
+ * (the production default) like the other advice, and deduped through the
454
+ * shared registry, so a hot table logs one line for the process.
439
455
  *
440
456
  * Cannot throw on odd metadata: it walks `tableMeta.columns`, the array the
441
457
  * constructor loop above has already iterated (and that client.ts validates
442
458
  * as an array), never `dateColumns`, which is a `Set` in every first-party
443
459
  * metadata path but arrives as a plain object from JSON-round-tripped
444
- * metadata. A dev-only diagnostic that crashes a shape production would serve
460
+ * metadata. An advisory diagnostic that crashes a shape production would serve
445
461
  * is worse than the bug it reports.
446
462
  */
447
463
  private warnUntypedColumns;
@@ -552,23 +568,52 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
552
568
  */
553
569
  private withDeclaredRelationNames;
554
570
  /**
555
- * Caller args in canonical form: declared relation spellings, and the Prisma
556
- * pagination aliases folded into `limit` / `offset`.
571
+ * `args` with `take` / `skip` folded into `limit` / `offset` at every `with`
572
+ * level (see `normalizeWithPagination` in query/relation-names.ts). Runs after
573
+ * the relation-name pass, so it resolves the declared spelling.
574
+ */
575
+ private withRelationPagination;
576
+ /**
577
+ * Caller args in canonical form: `undefined` pruned (query/normalize-args.ts),
578
+ * declared relation spellings, and the Prisma pagination aliases folded into
579
+ * `limit` / `offset`, with `take` / `skip` folded inside every `with` level too.
580
+ *
581
+ * Called at the seam of EVERY public operation and its `build*` twin, so the
582
+ * guards, the fingerprint, the build and the collect all read one shape. Each
583
+ * step returns its input by reference when there was nothing to change, so a
584
+ * second call on already-normalized args is free and the common path
585
+ * allocates nothing.
557
586
  *
558
- * ONE method rather than two calls at each seam, because the two
559
- * normalizations have the same requirement and the same failure mode: both
560
- * must happen before `withFingerprint` / the cache key, and a seam that
561
- * applies one but not the other is a seam where the alias survives into a
562
- * fingerprint. Both return their input by reference when there was nothing to
563
- * change, so the common path still allocates nothing.
587
+ * `refuseEmptiedWhere` names the single-row read (`findFirst`,
588
+ * `findFirstOrThrow`) that refuses a `where` whose every key was `undefined`.
564
589
  */
565
590
  private normalizeArgs;
591
+ /**
592
+ * Validate the per-query options whose bad values used to be ignored or
593
+ * misread: `timeout` (Node clamps a non-positive, non-finite or oversized
594
+ * delay to 1 ms) and `relationLoadStrategy`.
595
+ */
596
+ private assertQueryOptions;
566
597
  /**
567
598
  * Refuse a `findUnique` whose `where` names no unique key. The rule and the
568
599
  * message live in query/compound-unique.ts, beside the definition of what
569
600
  * counts as unique and shared with the PowDB engine.
570
601
  */
571
602
  private assertFindUniqueKey;
603
+ /**
604
+ * Refuse a locking read that is not inside a transaction, at the execute
605
+ * entry of each find method and before any strategy runs. The `build*`
606
+ * methods accept `lock` (the SQL is right wherever it runs); executing it
607
+ * in autocommit releases the lock before the caller sees the rows.
608
+ *
609
+ * The value is validated first, so an engine with no row locks answers
610
+ * E017 rather than asking for a transaction it would also refuse.
611
+ * "Inside a transaction" is `_txScoped`: the accessors a TransactionClient
612
+ * hands out, at any nesting depth.
613
+ */
614
+ private assertLockInTransaction;
615
+ /** Refuse `lock` on a streaming read (a cursor is not a locking read). */
616
+ private assertNoStreamLock;
572
617
  /**
573
618
  * Fill a PK-ascending `orderBy` into every to-many `with` relation that has no
574
619
  * explicit one, recursing into nested `with`. Returns a CLONED clause (user
@@ -587,94 +632,88 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
587
632
  * through the normal column mapping.
588
633
  */
589
634
  private pkOrderBy;
590
- /**
591
- * The field names a `cursor` actually seeks on (its own keys with a defined
592
- * value), in canonical sorted order. This is the diagnostic / implicit-
593
- * ordering view; the seek itself orders the fields by their `orderBy`
594
- * precedence (see {@link cursorSeekEntries}). Empty for a missing cursor or
595
- * one whose every value is `undefined` (which emits no seek condition at
596
- * all, so it does not paginate).
597
- */
598
- private cursorFields;
599
- /**
600
- * The ascending ordering implied by a `cursor`, or `undefined` when the shape
601
- * is too ambiguous to order safely.
602
- *
603
- * A cursor seek compares against the cursor's own field(s) (`col > $n`, `<`
604
- * when the orderBy says desc), so the ONLY ordering coherent with it is on
605
- * those fields: ordering a seek on column X by column Y walks the table in an
606
- * order the seek does not follow, which skips and repeats rows just as badly
607
- * as no order at all. That is why this orders on the cursor field rather than
608
- * blindly on the primary key when the two differ.
609
- *
610
- * Returns `undefined` (warn, inject nothing) for two shapes:
611
- * - a MULTI-field cursor. The seek is a proper keyset predicate, but its
612
- * column PRECEDENCE comes from the `orderBy` ({@link cursorSeekEntries}),
613
- * and with no orderBy there is nothing to derive it from: the cursor
614
- * object's key order is canonicalized away, so `(a asc, b asc)` would be a
615
- * guess at which key the caller meant to lead. The caller must state the
616
- * order, and the unordered-page warning says so.
617
- * - a field that does not resolve to a real column. Column validation belongs
618
- * to the normal build path, which raises a precise error; synthesizing an
619
- * ORDER BY on it here would only change which error the caller sees.
620
- */
621
- private cursorOrderBy;
622
- /**
623
- * The fields a `cursor` seeks on, in KEYSET order with their seek direction.
624
- * THE single authority the cache fingerprint (`cur=`), the SQL build and the
625
- * cache-hit param collect all consume, so the three cannot disagree about
626
- * which value binds to which `$n`.
627
- *
628
- * Keyset order is the `orderBy` precedence: the predicate for
629
- * `orderBy: [{ viewCount }, { id }]` must test `view_count` first and `id`
630
- * only within equal `view_count`, whatever order the caller wrote the cursor
631
- * object in (its keys are canonicalized for the cache anyway). A cursor field
632
- * the orderBy does not name trails the named ones in sorted key order and
633
- * seeks ascending, the same default a single-field cursor with no orderBy has
634
- * always had.
635
- *
636
- * Directions are indexed by the RESOLVED COLUMN, never the caller's key: both
637
- * `cursor` and `orderBy` take either spelling, so a cursor written
638
- * `{ created_at }` against `orderBy: { createdAt: 'desc' }` used to miss the
639
- * lookup, default to ascending, and seek the wrong side of the page. The
640
- * `{ sort, nulls }` spec form is normalized for the same reason. A relation /
641
- * JSON-path / vector orderBy key resolves to no column and is skipped.
642
- *
643
- * An unknown cursor field throws the same E003 here that the build path
644
- * threw before this helper existed; the fingerprint simply meets it first.
645
- */
646
- private cursorSeekEntries;
647
- /**
648
- * The keyset predicate for cursor terms in keyset order.
649
- *
650
- * One field is the plain `col > $1` (byte-identical to every single-field
651
- * cursor ever emitted). Two or more expand to
652
- * `(c1 > $1 OR (c1 = $1 AND c2 > $2) OR (c1 = $1 AND c2 = $2 AND c3 > $3))`,
653
- * with `<` for a `desc` field: the row-value form `(c1, c2) > ($1, $2)` is
654
- * shorter, but it cannot express a MIXED direction at all and SQL Server has
655
- * no row-value comparison, so the expanded form is the one path every engine
656
- * and every direction set share. Each value is bound ONCE and its `$n` is
657
- * referenced by every branch that needs it (legal on every supported
658
- * placeholder syntax), which is what keeps the param count equal to the field
659
- * count on both the build and the collect side.
660
- *
661
- * The former `c1 > $1 AND c2 > $2` was a conjunction, not a seek: it skipped
662
- * every row whose leading key EQUALED the cursor's, so a table with few
663
- * distinct leading values lost most of its rows across a page walk, silently.
664
- */
665
- private keysetPredicate;
666
- /**
667
- * Whether a findMany paginates (`limit` / `take` / `offset` / `cursor`) but
668
- * declares no ordering, which makes the returned page NON-DETERMINISTIC:
669
- * Postgres is free to return different rows for the same unordered `LIMIT`
670
- * once the heap changes underneath it, so a row can appear on two pages or on
671
- * none.
672
- *
673
- * `cursor` counts, and is the worst case rather than an exception: a keyset
674
- * seek with no ORDER BY is exactly this bug (`WHERE id > $1 LIMIT $2` walks
675
- * the heap in whatever order the plan happens to produce). An empty orderBy
676
- * (`[]`, or an object whose every value is `undefined`) counts as absent,
677
- * because it emits no ordering.
635
+ /** Memo for {@link totalOrderKeys}; table metadata is immutable. */
636
+ private totalOrderKeysMemo;
637
+ /**
638
+ * The unique keys whose columns are all NOT NULL, primary key first: the
639
+ * column sets that make an order total (no two rows can tie on them).
640
+ */
641
+ private totalOrderKeys;
642
+ /**
643
+ * THE tiebreaker rule, shared by cursor pages ({@link planCursor}) and the
644
+ * pages before them ({@link completePageOrder}), so every page of one walk
645
+ * is cut from the same total order: the columns to append to an order over
646
+ * `ordered` so that no two rows tie. `[]` when the order already contains a
647
+ * unique NOT NULL key; the first such key's missing columns otherwise;
648
+ * `undefined` when the table has none.
649
+ */
650
+ private tiebreakColumns;
651
+ /**
652
+ * A paginated `findMany` (`limit` / `offset`) whose `orderBy` can tie gets
653
+ * the tiebreaker appended, in the last term's direction, so a page boundary
654
+ * cannot fall between tied rows in a different order on each page (skipping
655
+ * or repeating one), and the first page of a cursor walk uses the order its
656
+ * cursor pages use. Returns `args` itself when the order is already total,
657
+ * the query is not paginated, or it pages by `cursor` or `distinct`, which
658
+ * order themselves. A `findFirst` with no `offset` is one row, not a page,
659
+ * and is left alone.
660
+ *
661
+ * An order containing a vector distance gets no tiebreaker: a KNN index
662
+ * serves only `ORDER BY <distance> LIMIT k`, a compound order turns that
663
+ * into a scan and sort of the whole table, and two equal distances are
664
+ * rare. A `cursor` still refuses such an order (see {@link planCursor}).
665
+ */
666
+ private completePageOrder;
667
+ /**
668
+ * Plan a `cursor` page: THE single authority the cache key, the SQL build and
669
+ * the cache-hit param collect all read, so the three cannot disagree.
670
+ *
671
+ * The page is ordered by the EFFECTIVE order: the caller's `orderBy` plus a
672
+ * tiebreaker (the primary key, else a unique key on NOT NULL columns) when
673
+ * the orderBy does not already end in one, in the last term's direction. A
674
+ * cursor query is always ordered, because a seek over rows the engine may
675
+ * return in any order skips and repeats rows. `args.orderBy` is rewritten to
676
+ * that order (by reference when nothing changes).
677
+ *
678
+ * Two ways to place the page, picked from what the cursor carries:
679
+ * - VALUES: the cursor has a value for every column of the effective order,
680
+ * so the seek compares against them directly (`col > $1`, expanded to a
681
+ * keyset across several columns). Extra cursor fields are ignored.
682
+ * - ROW: otherwise the cursor must identify one row by a unique key (the
683
+ * findUnique rule), and the seek reads that row's ordered values in
684
+ * scalar subqueries, guarded by `EXISTS` so a deleted cursor row gives an
685
+ * empty page rather than a wrong one.
686
+ * Anything else is refused (E003) naming the missing fields.
687
+ *
688
+ * NULL sort keys are placed where the engine sorts them (PostgreSQL: last
689
+ * ascending, first descending; SQLite / MySQL / SQL Server: NULL is smallest)
690
+ * or where an explicit `nulls` puts them, and each row is visited exactly
691
+ * once. On PostgreSQL a nullable ordered column has its placement written
692
+ * out, so a Postgres-compatible engine with a different default reads the
693
+ * same order the seek assumes.
694
+ */
695
+ private planCursor;
696
+ /**
697
+ * Render a {@link CursorPlan}'s seek predicate, pushing its params. Run by
698
+ * the build AND by the cache-hit collect (which discards the SQL), so the two
699
+ * cannot bind different params.
700
+ *
701
+ * Each value is bound once and referenced by every branch that needs it. One
702
+ * non-null column is the plain `col > $1`; several expand to
703
+ * `(c1 > $1 OR (c1 = $1 AND c2 > $2) OR ...)`, with `<` for a descending
704
+ * column (a row-value comparison cannot mix directions, and SQL Server has
705
+ * none). A nullable column gets NULL-aware equality and "after" terms.
706
+ */
707
+ private renderCursorPredicate;
708
+ /**
709
+ * Whether a findMany paginates (`limit` / `take` / `offset`) but declares no
710
+ * ordering, which makes the returned page NON-DETERMINISTIC: Postgres is
711
+ * free to return different rows for the same unordered `LIMIT` once the heap
712
+ * changes underneath it, so a row can appear on two pages or on none.
713
+ *
714
+ * A `cursor` page never counts: it is always ordered by its effective order
715
+ * (see {@link planCursor}). An empty orderBy (`[]`, or an object whose every
716
+ * value is `undefined`) counts as absent, because it emits no ordering.
678
717
  *
679
718
  * `distinct` is still excluded: that path re-orders in an outer wrapper around
680
719
  * a `DISTINCT ON` whose ordering picks the representative row, so an implicit
@@ -687,36 +726,32 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
687
726
  *
688
727
  * OFF by default in CORE, deliberately: turning it on would add an `ORDER BY`
689
728
  * to SQL that existing applications already emit, changing both the rows a
690
- * given page returns and the plan the engine picks. That is a breaking change
691
- * in everything but the type signature, so it waits for a major. The
729
+ * given page returns and the plan the engine picks. The
692
730
  * `turbine-orm/prisma-compat` layer defaults it ON instead, because reproducing
693
731
  * Prisma's semantics is that layer's whole contract.
694
732
  *
695
733
  * An explicit `orderBy` always wins, a PK-less table is left alone (nothing
696
734
  * stable to order by), and a composite PK orders on every column in
697
- * declaration order. A `cursor` query orders on the CURSOR's field instead
698
- * (see {@link cursorOrderBy}), and is left alone when that shape is ambiguous.
735
+ * declaration order. A `cursor` page is ordered by its own plan, not here, and
699
736
  * `distinct` shapes are skipped (see {@link isUnorderedPage}). With the flag
700
- * off this returns `undefined` before touching anything, so the emitted SQL is
701
- * byte-identical to before.
737
+ * off this returns `undefined` before touching anything.
702
738
  */
703
739
  private implicitPkOrderBy;
704
740
  /**
705
- * Dev-only, once per query shape: an unordered paginating findMany returns a
741
+ * Advice (`diagnostics.advice`), once per query shape: an unordered paginating findMany returns a
706
742
  * non-deterministic page (see {@link isUnorderedPage}), and on real data it is
707
743
  * also usually the slower plan (an unordered `LIMIT` can discard tens of
708
744
  * thousands of heap rows that an index scan on the key would have skipped).
709
745
  *
710
- * Gated exactly like the other dev diagnostics (silent under
711
- * `NODE_ENV=production`) and consistent with `warnOnUnlimited`: a per-call
746
+ * Gated exactly like the other advice (silent when `diagnostics.advice` is
747
+ * off) and consistent with `warnOnUnlimited`: a per-call
712
748
  * `warnOnUnlimited: false` silences it, `true` forces it past a config-level
713
749
  * opt-out, and a config/per-table `warnOnUnlimited: false` silences it. Deduped
714
750
  * process-wide through the shared warn registry, so it can never spam.
715
751
  *
716
752
  * Suppressed only when `implicitPkOrdering` will ACTUALLY order this query.
717
- * The flag being on is not enough: a PK-less table and an ambiguous
718
- * multi-field cursor both get no injected ordering, and those are precisely
719
- * the shapes that still need saying out loud.
753
+ * The flag being on is not enough: a PK-less table gets no injected
754
+ * ordering, and that is precisely the shape that still needs saying out loud.
720
755
  */
721
756
  private maybeWarnUnorderedPage;
722
757
  /**
@@ -807,7 +842,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
807
842
  */
808
843
  private planAuto;
809
844
  /**
810
- * Dev-only once-per-relation note that `'auto'` engaged the batched fallback.
845
+ * Advice, once per relation: `'auto'` engaged the batched fallback.
811
846
  *
812
847
  * Both lines follow the same four parts: the CONDITION that tripped the rule,
813
848
  * the MECHANISM (which plan shape was replaced by which, and what that costs),
@@ -885,15 +920,14 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
885
920
  *
886
921
  * When `sqlCache` is disabled, always calls `build()` without caching.
887
922
  *
888
- * `build` receives a fresh `$N` param scratch array. On a miss those params
889
- * are discarded (the returned params come from each call site's dedicated
890
- * collect path); the array exists so the build path can number placeholders
891
- * via `params.length` exactly as it does today. On a HIT, `build` is skipped
892
- * here but re-run by {@link crossCheckCache} (dev only) with a fresh array to
893
- * verify the collect path stayed in lockstep with the build path.
923
+ * `build` receives a fresh `$N` param scratch array. The executed params
924
+ * always come from each call site's dedicated collect path; on a miss the
925
+ * scratch params are kept in {@link lastMissParams} so `crossCheckCache` can
926
+ * compare the two. On a HIT, `build` is skipped here and re-run by
927
+ * {@link crossCheckCache} only when `diagnostics.cacheCheck` asks for it.
894
928
  *
895
- * Sets {@link lastCacheHit} so the caller's `crossCheckCache` knows whether a
896
- * cross-check is warranted.
929
+ * Sets {@link lastCacheHit} so the caller's `crossCheckCache` knows which
930
+ * comparison applies.
897
931
  */
898
932
  private acquireSql;
899
933
  /**
@@ -918,36 +952,54 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
918
952
  */
919
953
  private buildCacheEntry;
920
954
  /**
921
- * Dev-mode SQL-cache lockstep cross-check (see {@link cacheCrossCheckEnabled}).
955
+ * The SQL-cache lockstep checks (see the comment above `CACHE_MISMATCH_WARN_NS`).
922
956
  *
923
- * Runs only when the most recent {@link acquireSql} was a cache HIT and the
924
- * check is enabled. Rebuilds the SQL + `$N` params fresh via the same `build`
925
- * closure the caller passed to `acquireSql`, then compares:
957
+ * On a MISS: the collected params must equal the params the build pushed.
958
+ * On a HIT: the collected param count must equal the entry's, always; then,
959
+ * when `diagnostics.cacheCheck` selects this hit, the SQL and params are
960
+ * rebuilt fresh through the same closure and compared:
926
961
  * (a) the cached SQL string byte-for-byte against the fresh SQL, and
927
- * (b) the params the cache-hit collect path produced against the fresh
928
- * build-path params (length and element-wise strict deep-equal).
962
+ * (b) the collected params against the fresh build-path params (length
963
+ * and element-wise strict deep-equal).
929
964
  *
930
965
  * A mismatch means the fingerprint / build / collect paths have drifted out
931
966
  * of lockstep (the exact class of bug that has silently corrupted results
932
- * before), so it throws a {@link ValidationError} (E003) naming the
933
- * fingerprint, the operation, and both SQL strings (truncated). Failing loud
934
- * in dev/test is the point. Production never reaches the comparison.
967
+ * before), so it throws an {@link InvariantError} (E020) naming the
968
+ * fingerprint, the operation, and both SQL strings (truncated), never a
969
+ * parameter value.
935
970
  *
936
971
  * @param op human label of the calling build method (for the error message).
937
- * @param cacheKey the cache fingerprint that HIT.
938
- * @param entry the cached SQL entry that will be executed.
972
+ * @param cacheKey the cache fingerprint.
973
+ * @param entry the SQL entry that will be executed.
939
974
  * @param build the same closure passed to `acquireSql`; re-run here to
940
975
  * capture the fresh build-path SQL + params.
941
976
  * @param collectedParams the params the caller's collect path produced.
942
977
  */
943
978
  private crossCheckCache;
944
979
  /**
945
- * Reset the per-instance unlimited-query warning dedupe set.
946
- * Exposed for tests so a single test process can verify the warning fires
947
- * exactly once per table without bleeding state between assertions.
980
+ * The `sql-cache-lockstep` {@link InvariantError}. When `log` is set (the
981
+ * sampled hit path) the failure is also logged once per table and shape, so
982
+ * it is durably recorded in the server log before the throw unwinds the
983
+ * query; the other paths throw straight away.
984
+ */
985
+ private lockstepError;
986
+ /**
987
+ * Reset the unlimited-query warning dedupe, which is process-wide (see
988
+ * {@link maybeWarnUnlimited}). Exposed for tests so a single test process can
989
+ * verify the warning fires once per table without bleeding state between
990
+ * assertions.
948
991
  */
949
992
  resetUnlimitedWarnings(): void;
950
993
  private emitQueryEvent;
994
+ /**
995
+ * The statement `sql` as it goes out under `preparedName`: with the
996
+ * `sqlComment` appended, and under the name that comment calls for (see
997
+ * query/sql-comment.ts). This is the one place a comment is added, at the
998
+ * execute seam and after the SQL-template cache, so the cache, its keys and
999
+ * its lockstep checks only ever see commentless text. Without `sqlComment`
1000
+ * it is the statement unchanged.
1001
+ */
1002
+ private outgoing;
951
1003
  /**
952
1004
  * Resolve the prepared-statement name a read should execute under, honouring
953
1005
  * the per-query {@link FindManyArgs.forceCustomPlan} opt-in.
@@ -1018,11 +1070,61 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1018
1070
  private readWithTimeout;
1019
1071
  /**
1020
1072
  * Execute a pool.query with an optional timeout.
1021
- * If timeout is set, races the query against a timer and rejects on expiry.
1073
+ *
1074
+ * On a node-postgres pool outside a transaction the timeout is enforced on
1075
+ * the SERVER ({@link queryCancellable}). Anywhere else (a transaction's
1076
+ * connection, an engine shim, an HTTP pool) it races the query against a
1077
+ * timer: the call rejects on time but the statement keeps running, so the
1078
+ * error's `outcome` is `'unknown'`.
1079
+ *
1022
1080
  * pg driver errors are translated to typed Turbine errors via wrapPgError.
1023
1081
  * `retryIfStale` is {@link readWithTimeout}'s; nothing else sets it.
1024
1082
  */
1025
1083
  private queryWithTimeout;
1084
+ /**
1085
+ * Whether a timed statement can be stopped on the server: an engine with a
1086
+ * protocol cancel (PostgreSQL) on a node-postgres pool, outside a transaction
1087
+ * (inside one, the connection belongs to the transaction and is not this
1088
+ * method's to cancel or destroy).
1089
+ */
1090
+ private cancelsOnTimeout;
1091
+ /**
1092
+ * {@link queryWithTimeout} with a timeout the server enforces. The statement
1093
+ * runs on a connection checked out for it, so when the deadline passes the
1094
+ * backend running it is known and gets a protocol cancel request.
1095
+ *
1096
+ * The call then waits, at most {@link CANCEL_GRACE_MS}, for the statement to
1097
+ * answer, and the answer decides the result:
1098
+ * - cancelled (57014): TimeoutError, `outcome: 'not-executed'`;
1099
+ * - finished first: the result, returned late, because reporting a write
1100
+ * that committed as a timeout invites a retry that applies it twice;
1101
+ * - failed: that error;
1102
+ * - no answer: TimeoutError, `outcome: 'unknown'`, and the connection is
1103
+ * destroyed rather than handed to the next caller still busy.
1104
+ * A deadline that passes while still waiting for a connection sends nothing
1105
+ * (`'not-executed'`). Either way the connection goes back to the pool only
1106
+ * once its backend is idle, so timed-out statements cannot hold the pool.
1107
+ */
1108
+ private queryCancellable;
1109
+ /**
1110
+ * A timed statement inside a transaction, cancelled on the server when the
1111
+ * deadline passes, on the transaction's own connection.
1112
+ *
1113
+ * A cancelled statement made no change, but PostgreSQL aborts the
1114
+ * transaction it ran in, so the timeout ends the transaction too: it is
1115
+ * marked to roll back ({@link TransactionState.abort}), which also covers a
1116
+ * cancel that arrived after the statement finished. The error is
1117
+ * `outcome: 'not-executed'` either way, because nothing it did can commit.
1118
+ * A statement that finishes before the deadline is returned as usual.
1119
+ */
1120
+ private queryCancellableInTransaction;
1121
+ /** Cancel a timed-out statement in a transaction and end the transaction. See {@link queryCancellableInTransaction}. */
1122
+ private cancelInTransaction;
1123
+ /**
1124
+ * Cancel a statement that outlived its timeout, wait for it to answer, and
1125
+ * release its connection accordingly. See {@link queryCancellable}.
1126
+ */
1127
+ private cancelTimedOut;
1026
1128
  /**
1027
1129
  * Execute a write `DeferredQuery` (create/update/delete/upsert) according to
1028
1130
  * the active dialect's {@link Dialect.resultStrategy}, then apply its
@@ -1037,7 +1139,23 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1037
1139
  * write and a follow-up SELECT; the SELECT's rows feed the transform.
1038
1140
  */
1039
1141
  private executeMutation;
1040
- buildCreate<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateArgs<T, R, S, O>): DeferredQuery<FieldResult<T, S, O>>;
1142
+ /**
1143
+ * The executor for a write's statements, sharing one deadline: each one gets
1144
+ * what is left of `timeout`, so a chunked `createMany` or a lock, write and
1145
+ * re-read cannot run for N times the timeout. A statement due past the
1146
+ * deadline is not sent. `onClient` routes them to a held connection.
1147
+ */
1148
+ private deadlineExec;
1149
+ /**
1150
+ * Run a write that takes several statements as one transaction on one
1151
+ * connection: the caller's transaction when there is one, else one opened
1152
+ * here. A statement that times out is cancelled where the engine allows it,
1153
+ * and its connection is closed rather than rolled back (a ROLLBACK would wait
1154
+ * behind it); the transaction never commits, so the write made no change.
1155
+ * `timeout` is one deadline for every statement (see {@link deadlineExec}).
1156
+ */
1157
+ private inOneTransaction;
1158
+ buildCreate<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateArgs<T, R, S, O, M['create']>): DeferredQuery<FieldResult<T, S, O>>;
1041
1159
  /**
1042
1160
  * A single-row write's `select` / `omit`, resolved through the SAME
1043
1161
  * `resolveProjection` reads use (see WriteProjection in writes.ts), or
@@ -1045,14 +1163,14 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1045
1163
  * writes.ts because relations.ts imports writes.ts.
1046
1164
  */
1047
1165
  private resolveWriteProjection;
1048
- buildCreateMany(args: CreateManyArgs<T>): DeferredQuery<T[]>;
1049
- buildUpdate<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpdateArgs<T, R, S, O>): DeferredQuery<FieldResult<T, S, O>>;
1166
+ buildCreateMany<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateManyArgs<T, M['createMany'], S, O>): DeferredQuery<FieldResult<T, S, O>[]>;
1167
+ buildUpdate<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpdateArgs<T, R, S, O, M['update']>): DeferredQuery<FieldResult<T, S, O>>;
1050
1168
  buildDelete<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: DeleteArgs<T, R, S, O>): DeferredQuery<FieldResult<T, S, O>>;
1051
- buildUpsert<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpsertArgs<T, R, S, O>): DeferredQuery<FieldResult<T, S, O>>;
1052
- buildUpdateMany(args: UpdateManyArgs<T>): DeferredQuery<{
1169
+ buildUpsert<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpsertArgs<T, R, S, O, M['whereUnique'], M['createMany'], M['updateMany']>): DeferredQuery<FieldResult<T, S, O>>;
1170
+ buildUpdateMany(args: UpdateManyArgs<T, R, M['updateMany']>): DeferredQuery<{
1053
1171
  count: number;
1054
1172
  }>;
1055
- buildDeleteMany(args: DeleteManyArgs<T>): DeferredQuery<{
1173
+ buildDeleteMany(args: DeleteManyArgs<T, R>): DeferredQuery<{
1056
1174
  count: number;
1057
1175
  }>;
1058
1176
  /**
@@ -1066,14 +1184,13 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1066
1184
  * If no middlewares are registered, executes directly.
1067
1185
  *
1068
1186
  * Middleware can inspect and log query parameters, measure timing, and
1069
- * transform the result returned by `next()`. Note: query SQL is generated
1070
- * BEFORE middleware runs, `params.args` is a read-only snapshot, and
1071
- * mutating it does NOT change the executed SQL. Cross-cutting filters
1072
- * (e.g. soft deletes) belong in the query itself: pass an explicit
1073
- * `where: { deletedAt: null }` or wrap the table accessor in a small helper.
1187
+ * transform the result returned by `next()`. `params.args` is a plain copy
1188
+ * (see `readOnlyMiddlewareParams`): the query is compiled from the caller's
1189
+ * args, so `next()` throws a TypeError when the copy was changed. Cross-cutting
1190
+ * filters (e.g. soft deletes) belong in the query itself, or in `globalFilters`.
1074
1191
  */
1075
1192
  private executeWithMiddleware;
1076
- findUnique<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O>): Promise<QueryResult<T, R, W, S, O> | null>;
1193
+ findUnique<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O, M['whereUnique']>): Promise<QueryResult<T, R, W, S, O> | null>;
1077
1194
  /**
1078
1195
  * Batched-strategy findUnique: fetch the single base row without relation
1079
1196
  * subqueries (adding any parent stitch keys the projection excluded), then load
@@ -1081,7 +1198,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1081
1198
  * strategy's shape for the one row.
1082
1199
  */
1083
1200
  private runFindUniqueBatched;
1084
- buildFindUnique<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O>): DeferredQuery<QueryResult<T, R, W, S, O> | null>;
1201
+ buildFindUnique<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O, M['whereUnique']>): DeferredQuery<QueryResult<T, R, W, S, O> | null>;
1085
1202
  findMany<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): Promise<QueryResult<T, R, W, S, O>[]>;
1086
1203
  /**
1087
1204
  * Return the engine's query plan for a {@link findMany}-shaped query as plain
@@ -1114,11 +1231,13 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1114
1231
  */
1115
1232
  private withSqlCacheDisabled;
1116
1233
  /**
1117
- * Emit a one-time `console.warn` when {@link findMany} is called without an
1234
+ * Emit a one-time warning when {@link findMany} is called without an
1118
1235
  * explicit `limit`/`take` and `warnOnUnlimited` has not been disabled.
1119
1236
  *
1120
- * Deduped per QueryInterface instance via {@link warnedTables} so a busy
1121
- * loop calling `db.users.findMany()` thousands of times only logs once.
1237
+ * Said once per table per process (`WARN_NS.unlimitedFindMany`), so a busy
1238
+ * loop calling `db.users.findMany()` thousands of times logs once, and so
1239
+ * does the same call inside every `$transaction`, which builds its own
1240
+ * query interfaces.
1122
1241
  * Suppressed when `defaultLimit` is configured (the caller has already
1123
1242
  * opted in to a bounded query) and when the user passed an explicit
1124
1243
  * `limit`, `take`, or `cursor`. A per-call `warnOnUnlimited` overrides the
@@ -1146,7 +1265,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1146
1265
  private whereMatchesAtMostOneRow;
1147
1266
  /**
1148
1267
  * Recursively measure the maximum depth of a `with` clause tree.
1149
- * Used by the dev-only deep-with warning guard.
1268
+ * Used by the deep-with advice.
1150
1269
  */
1151
1270
  private measureWithDepth;
1152
1271
  buildFindMany<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): DeferredQuery<QueryResult<T, R, W, S, O>[]>;
@@ -1189,6 +1308,14 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1189
1308
  * non-empty.
1190
1309
  */
1191
1310
  private streamRaw;
1311
+ /**
1312
+ * Close a stream whose consumer asked for nothing within its idle timeout:
1313
+ * run the dialect's own cleanup (PostgreSQL: CLOSE, COMMIT), release the
1314
+ * connection (with the cleanup's error, if any, so the pool discards it), and
1315
+ * log `stream-idle-timeout`. The log line matters: an abandoned consumer
1316
+ * never pulls again, so it never sees the E002 waiting for it.
1317
+ */
1318
+ private expireIdleStream;
1192
1319
  /**
1193
1320
  * Stream rows from a findMany query using PostgreSQL cursors, one BATCH of
1194
1321
  * rows at a time.
@@ -1262,13 +1389,18 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1262
1389
  findManyStream<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyStreamArgs<T, R, W, S, O>): AsyncGenerator<QueryResult<T, R, W, S, O>, void, undefined>;
1263
1390
  findFirst<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): Promise<QueryResult<T, R, W, S, O> | null>;
1264
1391
  buildFindFirst<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): DeferredQuery<QueryResult<T, R, W, S, O> | null>;
1392
+ /**
1393
+ * findFirst / findFirstOrThrow over findMany's builder with `LIMIT 1`.
1394
+ * `operation` names the method in the refusal of an all-undefined `where`.
1395
+ */
1396
+ private buildFindFirstAs;
1265
1397
  findFirstOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): Promise<QueryResult<T, R, W, S, O>>;
1266
1398
  buildFindFirstOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args?: FindManyArgs<T, R, W, S, O>): DeferredQuery<QueryResult<T, R, W, S, O>>;
1267
- findUniqueOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O>): Promise<QueryResult<T, R, W, S, O>>;
1268
- buildFindUniqueOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O>): DeferredQuery<QueryResult<T, R, W, S, O>>;
1269
- create<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateArgs<T, R, S, O>): Promise<FieldResult<T, S, O>>;
1270
- createMany(args: CreateManyArgs<T>): Promise<T[]>;
1271
- update<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpdateArgs<T, R, S, O>): Promise<FieldResult<T, S, O>>;
1399
+ findUniqueOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O, M['whereUnique']>): Promise<QueryResult<T, R, W, S, O>>;
1400
+ buildFindUniqueOrThrow<W extends TypedWithClause<R> = {}, S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: FindUniqueArgs<T, R, W, S, O, M['whereUnique']>): DeferredQuery<QueryResult<T, R, W, S, O>>;
1401
+ create<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateArgs<T, R, S, O, M['create']>): Promise<FieldResult<T, S, O>>;
1402
+ createMany<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: CreateManyArgs<T, M['createMany'], S, O>): Promise<FieldResult<T, S, O>[]>;
1403
+ update<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpdateArgs<T, R, S, O, M['update']>): Promise<FieldResult<T, S, O>>;
1272
1404
  private nestedCreate;
1273
1405
  private nestedUpdate;
1274
1406
  /**
@@ -1282,7 +1414,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1282
1414
  private buildNestedCtx;
1283
1415
  private makeTxProxy;
1284
1416
  delete<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: DeleteArgs<T, R, S, O>): Promise<FieldResult<T, S, O>>;
1285
- upsert<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpsertArgs<T, R, S, O>): Promise<FieldResult<T, S, O>>;
1417
+ upsert<S extends Record<string, boolean> | undefined = undefined, O extends Record<string, boolean> | undefined = undefined>(args: UpsertArgs<T, R, S, O, M['whereUnique'], M['createMany'], M['updateMany']>): Promise<FieldResult<T, S, O>>;
1286
1418
  /**
1287
1419
  * @internal Whether `upsert()` looks the row up rather than running one
1288
1420
  * statement, which is also exactly when `buildUpsert` refuses these args.
@@ -1312,14 +1444,14 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1312
1444
  * never writes two rows over one key the database enforces.
1313
1445
  */
1314
1446
  private upsertLookupFirst;
1315
- updateMany(args: UpdateManyArgs<T, R>): Promise<{
1447
+ updateMany(args: UpdateManyArgs<T, R, M['updateMany']>): Promise<{
1316
1448
  count: number;
1317
1449
  }>;
1318
1450
  deleteMany(args: DeleteManyArgs<T, R>): Promise<{
1319
1451
  count: number;
1320
1452
  }>;
1321
1453
  count(args?: CountArgs<T, R>): Promise<number>;
1322
- buildCount(args?: CountArgs<T>): DeferredQuery<number>;
1454
+ buildCount(args?: CountArgs<T, R>): DeferredQuery<number>;
1323
1455
  /**
1324
1456
  * Group rows and compute per-group aggregates (Prisma-style). The result row
1325
1457
  * type is INFERRED from the args: each `by` field carries its entity field
@@ -1329,9 +1461,9 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1329
1461
  * that cannot be typed, so those columns are not projected onto the row type.
1330
1462
  */
1331
1463
  groupBy<A extends GroupByArgs<T, R>>(args: A): Promise<GroupByResult<T, A>[]>;
1332
- buildGroupBy(args: GroupByArgs<T>): DeferredQuery<Record<string, unknown>[]>;
1333
- buildAggregate(args: AggregateArgs<T>): DeferredQuery<AggregateResult<T>>;
1334
- aggregate(args: AggregateArgs<T, R>): Promise<AggregateResult<T>>;
1464
+ buildGroupBy<A extends GroupByArgs<T, R>>(args: A): DeferredQuery<GroupByResult<T, A>[]>;
1465
+ buildAggregate<A extends AggregateArgs<T, R>>(args: A): DeferredQuery<AggregateResultOf<T, A>>;
1466
+ aggregate<A extends AggregateArgs<T, R>>(args: A): Promise<AggregateResultOf<T, A>>;
1335
1467
  private resolveColumns;
1336
1468
  withFingerprint(withClause: WithClause | undefined, table?: string, depth?: number): string;
1337
1469
  private collectWithParams;
@@ -1385,7 +1517,7 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1385
1517
  * the default path.
1386
1518
  */
1387
1519
  private planFlatten;
1388
- /** Dev-only once-only note that `'flatten'` was refused for the whole query. */
1520
+ /** Advice, once per reason: `'flatten'` was refused for the whole query. */
1389
1521
  private warnFlattenBlocked;
1390
1522
  /**
1391
1523
  * Convert a field name to its snake_case column name (unquoted, for non-SQL
@@ -1482,10 +1614,10 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1482
1614
  * one, is the acknowledgement, and the warning exists to surface an
1483
1615
  * unacknowledged trade rather than to nag.
1484
1616
  *
1485
- * NOT DEV-ONLY, unlike every other warning in this codebase, and deliberately
1486
- * so. Production is exactly where a destructive write commits and where the
1487
- * row cannot be recovered afterwards, so a warning that goes quiet under
1488
- * `NODE_ENV=production` is silent in the only place it matters. The cost is
1617
+ * NOT ADVICE: it fires whatever `diagnostics` says, deliberately. Production
1618
+ * is exactly where a destructive write commits and where the row cannot be
1619
+ * recovered afterwards, so a warning that goes quiet in production mode is
1620
+ * silent in the only place it matters. The cost is
1489
1621
  * bounded to the point of irrelevance: once per process per field, and only
1490
1622
  * on a row that actually held an infinity.
1491
1623
  *
@@ -1516,6 +1648,15 @@ export declare class QueryInterface<T extends object, R extends object = {}> {
1516
1648
  * pre-plan code spelled inline.
1517
1649
  */
1518
1650
  private decodeTemporalCell;
1651
+ /** The non-temporal decode kinds of `table`'s columns, by column and by field name. */
1652
+ private getCellKinds;
1653
+ /** One cell's decode, for every kind but {@link CELL_PLAIN}. */
1654
+ private decodeCell;
1655
+ /**
1656
+ * A {@link CELL_DIALECT} cell: the dialect's decode for the column's declared
1657
+ * type, recorded by {@link getCellKinds} when it classified the column.
1658
+ */
1659
+ private decodeDialectCell;
1519
1660
  /**
1520
1661
  * Build the decode plan for one exact column list, and remember it as this
1521
1662
  * table's most recent shape so the next row of the same result set hits the