turbine-orm 0.56.0 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -1
- package/dist/cjs/cli/index.js +254 -37
- package/dist/cjs/client.js +3 -39
- package/dist/cjs/plan-divergence.d.ts +305 -38
- package/dist/cjs/plan-divergence.js +413 -67
- package/dist/cjs/prisma-compat.d.ts +32 -1
- package/dist/cjs/prisma-compat.js +297 -41
- package/dist/cjs/query/index.d.ts +2 -0
- package/dist/cjs/query/index.js +18 -1
- package/dist/cjs/query/option-surface.d.ts +100 -0
- package/dist/cjs/query/option-surface.js +214 -0
- package/dist/cjs/query/utils.d.ts +16 -0
- package/dist/cjs/query/utils.js +50 -0
- package/dist/cjs/query/warn-registry.d.ts +8 -0
- package/dist/cjs/query/warn-registry.js +8 -0
- package/dist/cli/index.js +255 -38
- package/dist/client.js +4 -40
- package/dist/plan-divergence.d.ts +305 -38
- package/dist/plan-divergence.js +412 -67
- package/dist/prisma-compat.d.ts +32 -1
- package/dist/prisma-compat.js +297 -41
- package/dist/query/index.d.ts +2 -0
- package/dist/query/index.js +1 -0
- package/dist/query/option-surface.d.ts +100 -0
- package/dist/query/option-surface.js +209 -0
- package/dist/query/utils.d.ts +16 -0
- package/dist/query/utils.js +49 -0
- package/dist/query/warn-registry.d.ts +8 -0
- package/dist/query/warn-registry.js +8 -0
- package/package.json +1 -1
package/dist/prisma-compat.d.ts
CHANGED
|
@@ -31,6 +31,15 @@
|
|
|
31
31
|
* atomic.
|
|
32
32
|
* - **Result reshaping**: `_count` objects keyed back to Prisma relation names,
|
|
33
33
|
* and to-one relations surfaced as `object | null`.
|
|
34
|
+
* - **Turbine-native query options** (`timeout`, `forceCustomPlan`,
|
|
35
|
+
* `warnOnUnlimited`, `skipGlobalFilters`, `stableRelationOrder`,
|
|
36
|
+
* `allowFullTableScan`, `includePii`, `optimisticLock`, `distinctOn`) reach
|
|
37
|
+
* core on every operation whose arg surface declares them. The set is not a
|
|
38
|
+
* hand-maintained list here: it comes from the compiler-checked tables in
|
|
39
|
+
* `query/option-surface.ts`, so a new core option cannot be silently stranded
|
|
40
|
+
* by this layer, and a key that is neither a Prisma arg nor a turbine option
|
|
41
|
+
* gets a dev-mode warning instead of vanishing (see
|
|
42
|
+
* {@link PRISMA_ARG_KEYS} and `warnUnknownQueryOptions`).
|
|
34
43
|
*
|
|
35
44
|
* ## What it deliberately does NOT do (documented divergences)
|
|
36
45
|
*
|
|
@@ -63,6 +72,14 @@
|
|
|
63
72
|
* exclusive-cursor + `offset` translation.
|
|
64
73
|
* - **Negative `take`** (take-from-end) and **`skip` on a nested relation
|
|
65
74
|
* include** throw, Turbine's `with` clause has no offset and no reverse-take.
|
|
75
|
+
* - **`limit` on `updateMany` / `deleteMany`** (Prisma 6.7+) throws. Turbine has
|
|
76
|
+
* no row-bounded mass mutation, and dropping a SAFETY BOUND with a warning
|
|
77
|
+
* would turn "change at most 10 rows" into "change every matching row".
|
|
78
|
+
* - **Write projections** (`select` / `include` / `omit` on
|
|
79
|
+
* create/update/delete/upsert), **`select` on `count`**, and
|
|
80
|
+
* **`orderBy` / `cursor` / `take` / `skip` on `aggregate`** are accepted and
|
|
81
|
+
* IGNORED (they are legitimate Prisma, so they never warn); the full row / a
|
|
82
|
+
* plain number comes back.
|
|
66
83
|
*
|
|
67
84
|
* ## Type dependencies (0.41.0)
|
|
68
85
|
*
|
|
@@ -93,7 +110,7 @@
|
|
|
93
110
|
* ```
|
|
94
111
|
*/
|
|
95
112
|
import type { TurbineClient } from './client.js';
|
|
96
|
-
import type
|
|
113
|
+
import { type DeferredQuery } from './query/index.js';
|
|
97
114
|
import type { PrismaCompatMap, SchemaMetadata } from './schema.js';
|
|
98
115
|
/** A build-only query object with the `build*` methods the adapter drives. */
|
|
99
116
|
export interface CompatQueryInterface {
|
|
@@ -237,6 +254,20 @@ export interface PrismaCompatOptions {
|
|
|
237
254
|
*/
|
|
238
255
|
prismaErrorCodes?: boolean;
|
|
239
256
|
}
|
|
257
|
+
/** The delegate operations this adapter exposes. */
|
|
258
|
+
export type CompatOperation = 'findMany' | 'findFirst' | 'findFirstOrThrow' | 'findUnique' | 'findUniqueOrThrow' | 'create' | 'createMany' | 'update' | 'updateMany' | 'delete' | 'deleteMany' | 'upsert' | 'count' | 'aggregate' | 'groupBy';
|
|
259
|
+
/**
|
|
260
|
+
* Every argument key Prisma itself accepts, per operation.
|
|
261
|
+
*
|
|
262
|
+
* Extracted from a generated `@prisma/client` 7.9.0 `index.d.ts` (the
|
|
263
|
+
* `<Model><Op>Args` blocks). It must stay the UNION across the Prisma majors
|
|
264
|
+
* this adapter supports, never one version's set: a key a newer major
|
|
265
|
+
* introduces should degrade to one noisy dev line, never to a throw, and a key
|
|
266
|
+
* an older major had must keep working. The drift test in
|
|
267
|
+
* `src/test/prisma-compat-option-surface.test.ts` re-extracts from a generated
|
|
268
|
+
* client when one is present and asserts this stays a superset.
|
|
269
|
+
*/
|
|
270
|
+
export declare const PRISMA_ARG_KEYS: Record<CompatOperation, readonly string[]>;
|
|
240
271
|
/** Symbol under which a lazy delegate call exposes its batchable plan. */
|
|
241
272
|
export declare const COMPAT_DEFERRED: unique symbol;
|
|
242
273
|
/**
|
package/dist/prisma-compat.js
CHANGED
|
@@ -31,6 +31,15 @@
|
|
|
31
31
|
* atomic.
|
|
32
32
|
* - **Result reshaping**: `_count` objects keyed back to Prisma relation names,
|
|
33
33
|
* and to-one relations surfaced as `object | null`.
|
|
34
|
+
* - **Turbine-native query options** (`timeout`, `forceCustomPlan`,
|
|
35
|
+
* `warnOnUnlimited`, `skipGlobalFilters`, `stableRelationOrder`,
|
|
36
|
+
* `allowFullTableScan`, `includePii`, `optimisticLock`, `distinctOn`) reach
|
|
37
|
+
* core on every operation whose arg surface declares them. The set is not a
|
|
38
|
+
* hand-maintained list here: it comes from the compiler-checked tables in
|
|
39
|
+
* `query/option-surface.ts`, so a new core option cannot be silently stranded
|
|
40
|
+
* by this layer, and a key that is neither a Prisma arg nor a turbine option
|
|
41
|
+
* gets a dev-mode warning instead of vanishing (see
|
|
42
|
+
* {@link PRISMA_ARG_KEYS} and `warnUnknownQueryOptions`).
|
|
34
43
|
*
|
|
35
44
|
* ## What it deliberately does NOT do (documented divergences)
|
|
36
45
|
*
|
|
@@ -63,6 +72,14 @@
|
|
|
63
72
|
* exclusive-cursor + `offset` translation.
|
|
64
73
|
* - **Negative `take`** (take-from-end) and **`skip` on a nested relation
|
|
65
74
|
* include** throw, Turbine's `with` clause has no offset and no reverse-take.
|
|
75
|
+
* - **`limit` on `updateMany` / `deleteMany`** (Prisma 6.7+) throws. Turbine has
|
|
76
|
+
* no row-bounded mass mutation, and dropping a SAFETY BOUND with a warning
|
|
77
|
+
* would turn "change at most 10 rows" into "change every matching row".
|
|
78
|
+
* - **Write projections** (`select` / `include` / `omit` on
|
|
79
|
+
* create/update/delete/upsert), **`select` on `count`**, and
|
|
80
|
+
* **`orderBy` / `cursor` / `take` / `skip` on `aggregate`** are accepted and
|
|
81
|
+
* IGNORED (they are legitimate Prisma, so they never warn); the full row / a
|
|
82
|
+
* plain number comes back.
|
|
66
83
|
*
|
|
67
84
|
* ## Type dependencies (0.41.0)
|
|
68
85
|
*
|
|
@@ -94,7 +111,9 @@
|
|
|
94
111
|
*/
|
|
95
112
|
import { TurbineError, TurbineErrorCode, UnsupportedFeatureError, ValidationError, wrapPgError } from './errors.js';
|
|
96
113
|
import { createManyShapeRuns } from './nested-write.js';
|
|
97
|
-
import {
|
|
114
|
+
import { AGGREGATE_OPTIONS, applyNativeOptions, COUNT_OPTIONS, CREATE_MANY_OPTIONS, CREATE_OPTIONS, DELETE_MANY_OPTIONS, DELETE_OPTIONS, FIND_MANY_OPTIONS, FIND_UNIQUE_OPTIONS, GROUP_BY_OPTIONS, optionKeysOfKind, UPDATE_MANY_OPTIONS, UPDATE_OPTIONS, UPSERT_OPTIONS, } from './query/index.js';
|
|
115
|
+
import { suggestKey } from './query/utils.js';
|
|
116
|
+
import { shouldWarnOnce, WARN_NS } from './query/warn-registry.js';
|
|
98
117
|
// ---------------------------------------------------------------------------
|
|
99
118
|
// Prisma.sql-style raw fragments (local, minimal, never imports @prisma/client)
|
|
100
119
|
// ---------------------------------------------------------------------------
|
|
@@ -252,6 +271,199 @@ function isPlainObject(v) {
|
|
|
252
271
|
function renameField(mm, prismaField) {
|
|
253
272
|
return mm.fields[prismaField] ?? prismaField;
|
|
254
273
|
}
|
|
274
|
+
/** The turbine arg surface each operation compiles into. */
|
|
275
|
+
const OPERATION_TABLES = {
|
|
276
|
+
findMany: FIND_MANY_OPTIONS,
|
|
277
|
+
findFirst: FIND_MANY_OPTIONS,
|
|
278
|
+
findFirstOrThrow: FIND_MANY_OPTIONS,
|
|
279
|
+
findUnique: FIND_UNIQUE_OPTIONS,
|
|
280
|
+
findUniqueOrThrow: FIND_UNIQUE_OPTIONS,
|
|
281
|
+
create: CREATE_OPTIONS,
|
|
282
|
+
createMany: CREATE_MANY_OPTIONS,
|
|
283
|
+
update: UPDATE_OPTIONS,
|
|
284
|
+
updateMany: UPDATE_MANY_OPTIONS,
|
|
285
|
+
delete: DELETE_OPTIONS,
|
|
286
|
+
deleteMany: DELETE_MANY_OPTIONS,
|
|
287
|
+
upsert: UPSERT_OPTIONS,
|
|
288
|
+
count: COUNT_OPTIONS,
|
|
289
|
+
aggregate: AGGREGATE_OPTIONS,
|
|
290
|
+
groupBy: GROUP_BY_OPTIONS,
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* Every argument key Prisma itself accepts, per operation.
|
|
294
|
+
*
|
|
295
|
+
* Extracted from a generated `@prisma/client` 7.9.0 `index.d.ts` (the
|
|
296
|
+
* `<Model><Op>Args` blocks). It must stay the UNION across the Prisma majors
|
|
297
|
+
* this adapter supports, never one version's set: a key a newer major
|
|
298
|
+
* introduces should degrade to one noisy dev line, never to a throw, and a key
|
|
299
|
+
* an older major had must keep working. The drift test in
|
|
300
|
+
* `src/test/prisma-compat-option-surface.test.ts` re-extracts from a generated
|
|
301
|
+
* client when one is present and asserts this stays a superset.
|
|
302
|
+
*/
|
|
303
|
+
export const PRISMA_ARG_KEYS = {
|
|
304
|
+
findMany: [
|
|
305
|
+
'select',
|
|
306
|
+
'omit',
|
|
307
|
+
'include',
|
|
308
|
+
'where',
|
|
309
|
+
'orderBy',
|
|
310
|
+
'cursor',
|
|
311
|
+
'take',
|
|
312
|
+
'skip',
|
|
313
|
+
'distinct',
|
|
314
|
+
'relationLoadStrategy',
|
|
315
|
+
],
|
|
316
|
+
findFirst: [
|
|
317
|
+
'select',
|
|
318
|
+
'omit',
|
|
319
|
+
'include',
|
|
320
|
+
'where',
|
|
321
|
+
'orderBy',
|
|
322
|
+
'cursor',
|
|
323
|
+
'take',
|
|
324
|
+
'skip',
|
|
325
|
+
'distinct',
|
|
326
|
+
'relationLoadStrategy',
|
|
327
|
+
],
|
|
328
|
+
findFirstOrThrow: [
|
|
329
|
+
'select',
|
|
330
|
+
'omit',
|
|
331
|
+
'include',
|
|
332
|
+
'where',
|
|
333
|
+
'orderBy',
|
|
334
|
+
'cursor',
|
|
335
|
+
'take',
|
|
336
|
+
'skip',
|
|
337
|
+
'distinct',
|
|
338
|
+
'relationLoadStrategy',
|
|
339
|
+
],
|
|
340
|
+
findUnique: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
341
|
+
findUniqueOrThrow: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
342
|
+
create: ['select', 'omit', 'include', 'data', 'relationLoadStrategy'],
|
|
343
|
+
createMany: ['data', 'skipDuplicates'],
|
|
344
|
+
update: ['select', 'omit', 'include', 'data', 'where', 'relationLoadStrategy'],
|
|
345
|
+
updateMany: ['data', 'where', 'limit'],
|
|
346
|
+
delete: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
347
|
+
deleteMany: ['where', 'limit'],
|
|
348
|
+
upsert: ['select', 'omit', 'include', 'where', 'create', 'update', 'relationLoadStrategy'],
|
|
349
|
+
count: ['where', 'orderBy', 'cursor', 'take', 'skip', 'select'],
|
|
350
|
+
aggregate: ['where', 'orderBy', 'cursor', 'take', 'skip', '_count', '_avg', '_sum', '_min', '_max'],
|
|
351
|
+
groupBy: ['where', 'orderBy', 'by', 'having', 'take', 'skip', '_count', '_avg', '_sum', '_min', '_max'],
|
|
352
|
+
};
|
|
353
|
+
/**
|
|
354
|
+
* Turbine spellings whose Prisma equivalent is spelled differently. A caller
|
|
355
|
+
* who reaches for one of these is not confused about the NAME, they are
|
|
356
|
+
* confused about which surface they are on, so they get a specific message
|
|
357
|
+
* rather than a fuzzy did-you-mean.
|
|
358
|
+
*/
|
|
359
|
+
const ALIAS_HINT = {
|
|
360
|
+
limit: 'take',
|
|
361
|
+
offset: 'skip',
|
|
362
|
+
with: 'include',
|
|
363
|
+
};
|
|
364
|
+
/**
|
|
365
|
+
* Known(op) = Prisma's own keys for that operation, plus every key the
|
|
366
|
+
* operation's turbine arg surface declares except the `'internal'` ones.
|
|
367
|
+
*
|
|
368
|
+
* The second half is NOT just the `'native'` keys. Two turbine-only options are
|
|
369
|
+
* classified `'prisma'` because their values carry field names and so must be
|
|
370
|
+
* hand-translated (`optimisticLock`, `distinctOn`); they are fully honoured, and
|
|
371
|
+
* warning about a key the adapter just acted on would be the worst possible
|
|
372
|
+
* diagnostic. `'nativeAlias'` members are in the set on purpose too: `limit` on
|
|
373
|
+
* `findMany` IS recognized, it simply gets the alias message rather than the
|
|
374
|
+
* generic one. Only `'internal'` is excluded, because nothing on this surface
|
|
375
|
+
* can reach it.
|
|
376
|
+
*
|
|
377
|
+
* A `Set` rather than an `in` test on a record, so an inherited
|
|
378
|
+
* `Object.prototype` name (`toString`, `constructor`) is treated as the unknown
|
|
379
|
+
* key it is.
|
|
380
|
+
*/
|
|
381
|
+
const KNOWN_KEYS = (() => {
|
|
382
|
+
const out = {};
|
|
383
|
+
for (const op of Object.keys(OPERATION_TABLES)) {
|
|
384
|
+
out[op] = new Set([
|
|
385
|
+
...PRISMA_ARG_KEYS[op],
|
|
386
|
+
...optionKeysOfKind(OPERATION_TABLES[op], 'prisma', 'native', 'nativeAlias'),
|
|
387
|
+
]);
|
|
388
|
+
}
|
|
389
|
+
return out;
|
|
390
|
+
})();
|
|
391
|
+
/**
|
|
392
|
+
* Dev-mode notice for a key on a delegate's args object that this operation has
|
|
393
|
+
* no meaning for.
|
|
394
|
+
*
|
|
395
|
+
* An unrecognized key is silently ignored (JavaScript objects have no schema),
|
|
396
|
+
* which makes a typo, a turbine spelling, and a genuinely missing feature all
|
|
397
|
+
* look identical: nothing happens. The client-config warner
|
|
398
|
+
* (`warnUnknownConfigKeys` in client.ts) exists for the same reason and this is
|
|
399
|
+
* its query-level twin, down to the ranking of the suggestion.
|
|
400
|
+
*
|
|
401
|
+
* Deliberately a WARNING, never an error. Throwing would turn a working app
|
|
402
|
+
* into a failing one on upgrade over one stray key, and a key from a Prisma
|
|
403
|
+
* major newer than {@link PRISMA_ARG_KEYS} would be exactly that key. The whole
|
|
404
|
+
* body is wrapped so a hostile or exotic args object (a Proxy whose `ownKeys`
|
|
405
|
+
* throws) can never be the reason a query fails. Dev-only and once per
|
|
406
|
+
* `model.operation.key` per process, like every other advisory here.
|
|
407
|
+
*/
|
|
408
|
+
function warnUnknownQueryOptions(model, op, args) {
|
|
409
|
+
if (process.env.NODE_ENV === 'production')
|
|
410
|
+
return;
|
|
411
|
+
if (!isPlainObject(args))
|
|
412
|
+
return;
|
|
413
|
+
try {
|
|
414
|
+
const known = KNOWN_KEYS[op];
|
|
415
|
+
const table = OPERATION_TABLES[op];
|
|
416
|
+
for (const key of Object.keys(args)) {
|
|
417
|
+
// `{ ...maybeOptions }` routinely materializes keys with no value.
|
|
418
|
+
// Nothing is being dropped when the value is undefined.
|
|
419
|
+
if (args[key] === undefined)
|
|
420
|
+
continue;
|
|
421
|
+
const alias = table[key] === 'nativeAlias' ? ALIAS_HINT[key] : undefined;
|
|
422
|
+
if (!alias && known.has(key))
|
|
423
|
+
continue;
|
|
424
|
+
if (!shouldWarnOnce(WARN_NS.unknownQueryOption, `${model}.${op}.${key}`))
|
|
425
|
+
continue;
|
|
426
|
+
if (alias) {
|
|
427
|
+
console.warn(`[turbine] prisma-compat: "${key}" is Turbine's spelling and is ignored here;` +
|
|
428
|
+
` prisma-compat takes Prisma's "${alias}". (${model}.${op})`);
|
|
429
|
+
continue;
|
|
430
|
+
}
|
|
431
|
+
const suggestion = suggestKey(key, known);
|
|
432
|
+
console.warn(`[turbine] prisma-compat: unknown option "${key}" in ${model}.${op}(), it is ignored.` +
|
|
433
|
+
(suggestion ? ` Did you mean "${suggestion}"?` : ''));
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
// Key enumeration is the only thing that can fail here, and a diagnostic
|
|
438
|
+
// must never be the reason a query fails.
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Prisma 6.7+ accepts `limit` on `updateMany` / `deleteMany` to BOUND how many
|
|
443
|
+
* rows a mass mutation touches. Turbine has no row-bounded mass mutation, so
|
|
444
|
+
* this one is refused rather than warned about: everywhere else in this design
|
|
445
|
+
* a dropped option costs the caller a feature, but silently dropping a safety
|
|
446
|
+
* bound turns "change at most 10 rows" into "change every row".
|
|
447
|
+
*/
|
|
448
|
+
function refuseRowLimit(model, op, args) {
|
|
449
|
+
if (!isPlainObject(args) || args.limit === undefined)
|
|
450
|
+
return;
|
|
451
|
+
throw new UnsupportedFeatureError(`\`limit\` on ${op} (row-bounded mass mutation)`, 'prisma-compat', `Turbine has no row-bounded ${op}; select the rows you mean with \`where\`` +
|
|
452
|
+
` (on ${model}.${op}), or page them and mutate by primary key.`);
|
|
453
|
+
}
|
|
454
|
+
/**
|
|
455
|
+
* Prisma's `relationLoadStrategy` and Turbine's share a name and NOT a value
|
|
456
|
+
* domain: Prisma has `'query' | 'join'`, Turbine has
|
|
457
|
+
* `'join' | 'batched' | 'auto' | 'flatten'`. Core's strategy resolution has no
|
|
458
|
+
* branch for `'query'` and returns the value unchanged, so forwarding it
|
|
459
|
+
* verbatim gave a caller who asked for the per-relation query plan the JOIN
|
|
460
|
+
* plan, the exact opposite of the request. Prisma's `'query'` IS Turbine's
|
|
461
|
+
* `'batched'` (one follow-up statement per relation); the turbine-only values
|
|
462
|
+
* pass through so a compat caller can still reach them.
|
|
463
|
+
*/
|
|
464
|
+
function mapRelationLoadStrategy(value) {
|
|
465
|
+
return value === 'query' ? 'batched' : value;
|
|
466
|
+
}
|
|
255
467
|
/**
|
|
256
468
|
* Translate a Prisma `where` (or nested relation where) into a Turbine `where`.
|
|
257
469
|
* Renames scalar field keys and relation keys through the map, recurses into
|
|
@@ -446,6 +658,13 @@ function modelName(ctx, mm) {
|
|
|
446
658
|
*/
|
|
447
659
|
function translateReadArgs(ctx, mm, prismaArgs, kind) {
|
|
448
660
|
const t = {};
|
|
661
|
+
// FIRST, so a per-call `stableRelationOrder` overrides it: the client-level
|
|
662
|
+
// option is a default, the arg is an instruction.
|
|
663
|
+
if (ctx.options.stablePkOrder)
|
|
664
|
+
t.stableRelationOrder = true;
|
|
665
|
+
// Every turbine-native option the arg surface declares, in one line that
|
|
666
|
+
// cannot fall behind the interface (see the option-surface tables).
|
|
667
|
+
applyNativeOptions(kind === 'unique' ? FIND_UNIQUE_OPTIONS : FIND_MANY_OPTIONS, prismaArgs, t);
|
|
449
668
|
if (prismaArgs.where !== undefined)
|
|
450
669
|
t.where = translateWhere(ctx, mm, prismaArgs.where);
|
|
451
670
|
if (prismaArgs.orderBy !== undefined)
|
|
@@ -458,17 +677,9 @@ function translateReadArgs(ctx, mm, prismaArgs, kind) {
|
|
|
458
677
|
if (Array.isArray(prismaArgs.distinct)) {
|
|
459
678
|
t.distinct = prismaArgs.distinct.map((f) => renameField(mm, f));
|
|
460
679
|
}
|
|
461
|
-
if (prismaArgs.relationLoadStrategy !== undefined)
|
|
462
|
-
t.relationLoadStrategy = prismaArgs.relationLoadStrategy;
|
|
463
|
-
|
|
464
|
-
t.timeout = prismaArgs.timeout;
|
|
465
|
-
// Turbine-only passthrough. Prisma has no PII concept, so a compat caller
|
|
466
|
-
// whose schema tags columns needs SOME way to opt in; without this the
|
|
467
|
-
// adapter is a one-way door into redacted reads and refused aggregates.
|
|
468
|
-
if (prismaArgs.includePii !== undefined)
|
|
469
|
-
t.includePii = prismaArgs.includePii;
|
|
470
|
-
if (ctx.options.stablePkOrder)
|
|
471
|
-
t.stableRelationOrder = true;
|
|
680
|
+
if (prismaArgs.relationLoadStrategy !== undefined) {
|
|
681
|
+
t.relationLoadStrategy = mapRelationLoadStrategy(prismaArgs.relationLoadStrategy);
|
|
682
|
+
}
|
|
472
683
|
// ORDER IS LOAD-BEARING: translateCursor MUST run BEFORE applyImplicitPkOrder.
|
|
473
684
|
// The cursor translation reads `t.orderBy` to decide the seek direction and to
|
|
474
685
|
// validate that a bare inclusive cursor names the sort key; it must see the
|
|
@@ -767,6 +978,7 @@ function translateUpsertNested(ctx, target, p) {
|
|
|
767
978
|
const AGG_FIELD_BLOCKS = ['_sum', '_avg', '_min', '_max'];
|
|
768
979
|
function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
769
980
|
const t = {};
|
|
981
|
+
applyNativeOptions(isGroupBy ? GROUP_BY_OPTIONS : AGGREGATE_OPTIONS, args, t);
|
|
770
982
|
if (args.where !== undefined)
|
|
771
983
|
t.where = translateWhere(ctx, mm, args.where);
|
|
772
984
|
if (args._count !== undefined)
|
|
@@ -775,12 +987,6 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
775
987
|
if (args[block] !== undefined)
|
|
776
988
|
t[block] = renameAggBlock(mm, args[block], false);
|
|
777
989
|
}
|
|
778
|
-
if (typeof args.timeout === 'number')
|
|
779
|
-
t.timeout = args.timeout;
|
|
780
|
-
// Turbine-only passthrough: the PII gate on groupBy keys and _min/_max needs
|
|
781
|
-
// an opt-in that Prisma's arg shape has no equivalent for.
|
|
782
|
-
if (args.includePii !== undefined)
|
|
783
|
-
t.includePii = args.includePii;
|
|
784
990
|
if (isGroupBy) {
|
|
785
991
|
if (Array.isArray(args.by))
|
|
786
992
|
t.by = args.by.map((f) => renameField(mm, f));
|
|
@@ -788,6 +994,8 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
788
994
|
t.orderBy = translateOrderBy(ctx, mm, args.orderBy);
|
|
789
995
|
if (args.having !== undefined)
|
|
790
996
|
t.having = renameHaving(mm, args.having);
|
|
997
|
+
if (args.distinctOn !== undefined)
|
|
998
|
+
t.distinctOn = translateDistinctOn(ctx, mm, args.distinctOn);
|
|
791
999
|
if (typeof args.take === 'number')
|
|
792
1000
|
t.limit = mapTake(args.take);
|
|
793
1001
|
if (typeof args.skip === 'number')
|
|
@@ -795,6 +1003,23 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
795
1003
|
}
|
|
796
1004
|
return t;
|
|
797
1005
|
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Translate a turbine-native groupBy `distinctOn`. Both halves of its value
|
|
1008
|
+
* (`columns`, `orderBy`) are FIELD NAMES, so this is the concrete reason the
|
|
1009
|
+
* option surface refuses to copy unknown keys through by default: a blind
|
|
1010
|
+
* passthrough is correct on a model whose Prisma and turbine names coincide and
|
|
1011
|
+
* silently wrong on one with a `@map`.
|
|
1012
|
+
*/
|
|
1013
|
+
function translateDistinctOn(ctx, mm, val) {
|
|
1014
|
+
if (!isPlainObject(val))
|
|
1015
|
+
return val;
|
|
1016
|
+
const out = { ...val };
|
|
1017
|
+
if (Array.isArray(val.columns))
|
|
1018
|
+
out.columns = val.columns.map((f) => renameField(mm, f));
|
|
1019
|
+
if (val.orderBy !== undefined)
|
|
1020
|
+
out.orderBy = translateOrderBy(ctx, mm, val.orderBy);
|
|
1021
|
+
return out;
|
|
1022
|
+
}
|
|
798
1023
|
/** Rename field keys inside an aggregate block; `_count`'s `_all` passes through. */
|
|
799
1024
|
function renameAggBlock(mm, block, isCount) {
|
|
800
1025
|
if (block === true || !isPlainObject(block))
|
|
@@ -1139,6 +1364,8 @@ async function createManyByRun(qi, t, runs) {
|
|
|
1139
1364
|
const args = { data: run };
|
|
1140
1365
|
if (t.skipDuplicates)
|
|
1141
1366
|
args.skipDuplicates = true;
|
|
1367
|
+
if (t.timeout !== undefined)
|
|
1368
|
+
args.timeout = t.timeout;
|
|
1142
1369
|
count += (await qi.createMany(args)).length;
|
|
1143
1370
|
}
|
|
1144
1371
|
return { count };
|
|
@@ -1154,7 +1381,14 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1154
1381
|
// async run wrapper also converts any synchronous throw from the underlying
|
|
1155
1382
|
// `qi.*` build into a rejection; the array `$transaction([...])` batch path
|
|
1156
1383
|
// catches the same throw from `batch.build`.
|
|
1157
|
-
const defer = (
|
|
1384
|
+
const defer = (op, rawArgs, translateRaw, run, batch) => {
|
|
1385
|
+
// The unknown-key check rides the SAME deferred boundary as the translation
|
|
1386
|
+
// itself, for the same reason (see the comment above): a compat promise that
|
|
1387
|
+
// is built and never awaited must produce no output at all.
|
|
1388
|
+
const translate = () => {
|
|
1389
|
+
warnUnknownQueryOptions(modelName(ctx, mm), op, rawArgs);
|
|
1390
|
+
return translateRaw();
|
|
1391
|
+
};
|
|
1158
1392
|
const batchable = batch
|
|
1159
1393
|
? {
|
|
1160
1394
|
build: () => batch.build(getQI(), translate()),
|
|
@@ -1194,27 +1428,27 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1194
1428
|
return args;
|
|
1195
1429
|
};
|
|
1196
1430
|
return {
|
|
1197
|
-
findMany: (args = {}) => defer(() => translateReadArgs(ctx, mm, args, 'many'), (qi, t) => qi.findMany(t).then((r) => reshapeRows(ctx, mm, r)), { build: (qi, t) => qi.buildFindMany(t), reshape: (raw) => reshapeRows(ctx, mm, raw) }),
|
|
1198
|
-
findFirst: (args = {}) => defer(() => translateReadArgs(ctx, mm, args, 'first'), (qi, t) => qi.findFirst(t).then((r) => reshapeRowOrNull(ctx, mm, r)), { build: (qi, t) => qi.buildFindFirst(t), reshape: (raw) => reshapeRowOrNull(ctx, mm, raw) }),
|
|
1199
|
-
findUnique: (args) => defer(() => translateReadArgs(ctx, mm, requireWhere(args, 'findUnique'), 'unique'), (qi, t) => qi.findUnique(t).then((r) => reshapeRowOrNull(ctx, mm, r)), { build: (qi, t) => qi.buildFindUnique(t), reshape: (raw) => reshapeRowOrNull(ctx, mm, raw) }),
|
|
1200
|
-
findFirstOrThrow: (args = {}) => defer(() => translateReadArgs(ctx, mm, args, 'first'), (qi, t) => qi.findFirstOrThrow(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildFindFirstOrThrow(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1201
|
-
findUniqueOrThrow: (args) => defer(() => translateReadArgs(ctx, mm, requireWhere(args, 'findUniqueOrThrow'), 'unique'), (qi, t) => qi.findUniqueOrThrow(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildFindUniqueOrThrow(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1202
|
-
create: (args) => defer(() => {
|
|
1431
|
+
findMany: (args = {}) => defer('findMany', args, () => translateReadArgs(ctx, mm, args, 'many'), (qi, t) => qi.findMany(t).then((r) => reshapeRows(ctx, mm, r)), { build: (qi, t) => qi.buildFindMany(t), reshape: (raw) => reshapeRows(ctx, mm, raw) }),
|
|
1432
|
+
findFirst: (args = {}) => defer('findFirst', args, () => translateReadArgs(ctx, mm, args, 'first'), (qi, t) => qi.findFirst(t).then((r) => reshapeRowOrNull(ctx, mm, r)), { build: (qi, t) => qi.buildFindFirst(t), reshape: (raw) => reshapeRowOrNull(ctx, mm, raw) }),
|
|
1433
|
+
findUnique: (args) => defer('findUnique', args, () => translateReadArgs(ctx, mm, requireWhere(args, 'findUnique'), 'unique'), (qi, t) => qi.findUnique(t).then((r) => reshapeRowOrNull(ctx, mm, r)), { build: (qi, t) => qi.buildFindUnique(t), reshape: (raw) => reshapeRowOrNull(ctx, mm, raw) }),
|
|
1434
|
+
findFirstOrThrow: (args = {}) => defer('findFirstOrThrow', args, () => translateReadArgs(ctx, mm, args, 'first'), (qi, t) => qi.findFirstOrThrow(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildFindFirstOrThrow(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1435
|
+
findUniqueOrThrow: (args) => defer('findUniqueOrThrow', args, () => translateReadArgs(ctx, mm, requireWhere(args, 'findUniqueOrThrow'), 'unique'), (qi, t) => qi.findUniqueOrThrow(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildFindUniqueOrThrow(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1436
|
+
create: (args) => defer('create', args, () => {
|
|
1203
1437
|
const t = { data: translateWriteData(ctx, mm, applyCreateDefaults(mm, args.data)) };
|
|
1204
|
-
|
|
1205
|
-
t.timeout = args.timeout;
|
|
1438
|
+
applyNativeOptions(CREATE_OPTIONS, args, t);
|
|
1206
1439
|
return t;
|
|
1207
1440
|
}, (qi, t) => qi.create(t).then((r) => reshapeRow(ctx, mm, r)), {
|
|
1208
1441
|
build: (qi, t) => qi.buildCreate(t),
|
|
1209
1442
|
reshape: (raw) => reshapeRow(ctx, mm, raw),
|
|
1210
1443
|
nested: (t) => hasNestedKeys(ctx, mm, t.data),
|
|
1211
1444
|
}),
|
|
1212
|
-
createMany: (args) => defer(() => {
|
|
1445
|
+
createMany: (args) => defer('createMany', args, () => {
|
|
1213
1446
|
const data = args.data;
|
|
1214
1447
|
const rows = Array.isArray(data)
|
|
1215
1448
|
? data.map((d) => translateWriteData(ctx, mm, applyCreateDefaults(mm, d)))
|
|
1216
1449
|
: [];
|
|
1217
1450
|
const t = { data: rows };
|
|
1451
|
+
applyNativeOptions(CREATE_MANY_OPTIONS, args, t);
|
|
1218
1452
|
if (args.skipDuplicates)
|
|
1219
1453
|
t.skipDuplicates = true;
|
|
1220
1454
|
return t;
|
|
@@ -1235,45 +1469,68 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1235
1469
|
nested: (t) => createManyRunsOf(t).length > 1,
|
|
1236
1470
|
execInTx: (table, t) => createManyByRun(table(mm.table), t, createManyRunsOf(t)),
|
|
1237
1471
|
}),
|
|
1238
|
-
update: (args) => defer(() => {
|
|
1472
|
+
update: (args) => defer('update', args, () => {
|
|
1239
1473
|
const a = requireWhere(args, 'update');
|
|
1240
|
-
|
|
1474
|
+
const t = {
|
|
1241
1475
|
where: translateWhere(ctx, mm, a.where),
|
|
1242
1476
|
data: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.data)),
|
|
1243
1477
|
};
|
|
1478
|
+
applyNativeOptions(UPDATE_OPTIONS, a, t);
|
|
1479
|
+
// `optimisticLock.field` is a FIELD NAME, so it is renamed rather than
|
|
1480
|
+
// copied: a blind passthrough would send the Prisma spelling into core
|
|
1481
|
+
// and break on any model whose column is `@map`ped.
|
|
1482
|
+
if (isPlainObject(a.optimisticLock)) {
|
|
1483
|
+
t.optimisticLock = {
|
|
1484
|
+
...a.optimisticLock,
|
|
1485
|
+
field: renameField(mm, String(a.optimisticLock.field)),
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
return t;
|
|
1244
1489
|
}, (qi, t) => qi.update(t).then((r) => reshapeRow(ctx, mm, r)), {
|
|
1245
1490
|
build: (qi, t) => qi.buildUpdate(t),
|
|
1246
1491
|
reshape: (raw) => reshapeRow(ctx, mm, raw),
|
|
1247
1492
|
nested: (t) => hasNestedKeys(ctx, mm, t.data),
|
|
1248
1493
|
}),
|
|
1249
|
-
updateMany: (args) => defer(() => {
|
|
1494
|
+
updateMany: (args) => defer('updateMany', args, () => {
|
|
1250
1495
|
const a = args;
|
|
1496
|
+
refuseRowLimit(modelName(ctx, mm), 'updateMany', a);
|
|
1251
1497
|
const t = {
|
|
1252
1498
|
where: translateWhere(ctx, mm, a.where ?? {}),
|
|
1253
1499
|
data: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.data)),
|
|
1254
1500
|
};
|
|
1501
|
+
applyNativeOptions(UPDATE_MANY_OPTIONS, a, t);
|
|
1502
|
+
// LAST, so it wins: a Prisma updateMany with no `where` affects every
|
|
1503
|
+
// row, and an explicit `allowFullTableScan: false` must not be able to
|
|
1504
|
+
// turn that parity into a thrown empty-where guard.
|
|
1255
1505
|
if (a.where === undefined)
|
|
1256
1506
|
t.allowFullTableScan = true;
|
|
1257
1507
|
return t;
|
|
1258
1508
|
}, (qi, t) => qi.updateMany(t), { build: (qi, t) => qi.buildUpdateMany(t), reshape: (raw) => raw }),
|
|
1259
|
-
delete: (args) => defer(() => {
|
|
1509
|
+
delete: (args) => defer('delete', args, () => {
|
|
1260
1510
|
const a = requireWhere(args, 'delete');
|
|
1261
|
-
|
|
1511
|
+
const t = { where: translateWhere(ctx, mm, a.where) };
|
|
1512
|
+
applyNativeOptions(DELETE_OPTIONS, a, t);
|
|
1513
|
+
return t;
|
|
1262
1514
|
}, (qi, t) => qi.delete(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildDelete(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1263
|
-
deleteMany: (args = {}) => defer(() => {
|
|
1515
|
+
deleteMany: (args = {}) => defer('deleteMany', args, () => {
|
|
1264
1516
|
const a = args;
|
|
1517
|
+
refuseRowLimit(modelName(ctx, mm), 'deleteMany', a);
|
|
1265
1518
|
const t = { where: translateWhere(ctx, mm, a.where ?? {}) };
|
|
1519
|
+
applyNativeOptions(DELETE_MANY_OPTIONS, a, t);
|
|
1520
|
+
// LAST, so it wins. See the same note on updateMany.
|
|
1266
1521
|
if (a.where === undefined)
|
|
1267
1522
|
t.allowFullTableScan = true;
|
|
1268
1523
|
return t;
|
|
1269
1524
|
}, (qi, t) => qi.deleteMany(t), { build: (qi, t) => qi.buildDeleteMany(t), reshape: (raw) => raw }),
|
|
1270
|
-
upsert: (args) => defer(() => {
|
|
1525
|
+
upsert: (args) => defer('upsert', args, () => {
|
|
1271
1526
|
const a = requireWhere(args, 'upsert');
|
|
1272
|
-
|
|
1527
|
+
const t = {
|
|
1273
1528
|
where: translateWhere(ctx, mm, a.where),
|
|
1274
1529
|
create: translateWriteData(ctx, mm, applyCreateDefaults(mm, a.create)),
|
|
1275
1530
|
update: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.update)),
|
|
1276
1531
|
};
|
|
1532
|
+
applyNativeOptions(UPSERT_OPTIONS, a, t);
|
|
1533
|
+
return t;
|
|
1277
1534
|
}, (qi, t) => {
|
|
1278
1535
|
// Native ON CONFLICT upsert is only Prisma-equivalent when the where
|
|
1279
1536
|
// key values equal the create values AND no nested write data is
|
|
@@ -1296,16 +1553,15 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1296
1553
|
return reshapeRow(ctx, mm, await upsertLookupFirst(table(mm.table), t));
|
|
1297
1554
|
},
|
|
1298
1555
|
}),
|
|
1299
|
-
count: (args = {}) => defer(() => {
|
|
1556
|
+
count: (args = {}) => defer('count', args, () => {
|
|
1300
1557
|
const t = {};
|
|
1558
|
+
applyNativeOptions(COUNT_OPTIONS, args, t);
|
|
1301
1559
|
if (args.where !== undefined)
|
|
1302
1560
|
t.where = translateWhere(ctx, mm, args.where);
|
|
1303
|
-
if (typeof args.timeout === 'number')
|
|
1304
|
-
t.timeout = args.timeout;
|
|
1305
1561
|
return t;
|
|
1306
1562
|
}, (qi, t) => qi.count(t), { build: (qi, t) => qi.buildCount(t), reshape: (raw) => raw }),
|
|
1307
|
-
aggregate: (args) => defer(() => translateAggregateArgs(ctx, mm, args, false), (qi, t) => qi.aggregate(t).then((r) => reshapeAggregate(ctx, mm, r)), { build: (qi, t) => qi.buildAggregate(t), reshape: (raw) => reshapeAggregate(ctx, mm, raw) }),
|
|
1308
|
-
groupBy: (args) => defer(() => translateAggregateArgs(ctx, mm, args, true), (qi, t) => qi.groupBy(t).then((rows) => rows.map((r) => reshapeGroupRow(ctx, mm, r))), {
|
|
1563
|
+
aggregate: (args) => defer('aggregate', args, () => translateAggregateArgs(ctx, mm, args, false), (qi, t) => qi.aggregate(t).then((r) => reshapeAggregate(ctx, mm, r)), { build: (qi, t) => qi.buildAggregate(t), reshape: (raw) => reshapeAggregate(ctx, mm, raw) }),
|
|
1564
|
+
groupBy: (args) => defer('groupBy', args, () => translateAggregateArgs(ctx, mm, args, true), (qi, t) => qi.groupBy(t).then((rows) => rows.map((r) => reshapeGroupRow(ctx, mm, r))), {
|
|
1309
1565
|
build: (qi, t) => qi.buildGroupBy(t),
|
|
1310
1566
|
reshape: (raw) => raw.map((r) => reshapeGroupRow(ctx, mm, r)),
|
|
1311
1567
|
}),
|
package/dist/query/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@
|
|
|
8
8
|
export type { AggregateArgs, AggregateResult, ArrayFilter, ColumnRef, ConnectOrCreateOp, CountArgs, CreateArgs, CreateDataInput, CreateManyArgs, DeleteArgs, DeleteManyArgs, FieldResult, FindManyArgs, FindManyStreamArgs, FindUniqueArgs, GlobalFilters, GroupByAggregateSpec, GroupByArgs, GroupByDistinctOn, GroupByResult, HavingClause, JsonFilter, JsonPathAggregateTarget, JsonPathGroupKey, JsonPathOrderBy, NestedCreateOp, NestedUpdateOp, NestedUpdateOpItem, NestedUpsertOpItem, OmitResult, OrderByClause, OrderByObject, OrderDirection, QueryResult, RelationDescriptor, RelationFilter, RelationLoadStrategy, RelationPickBy, RelationPickOrderBy, SelectResult, SkipGlobalFilters, TextSearchFilter, TypedWithClause, UpdateArgs, UpdateDataInput, UpdateInput, UpdateManyArgs, UpdateOperatorInput, UpsertArgs, VectorDistanceFilter, VectorFilter, VectorMetric, VectorOrderBy, VectorOrderByDistance, WhereClause, WhereOperator, WhereValue, WithClause, WithOptions, WithOrderByObject, WithResult, } from './types.js';
|
|
9
9
|
export type { BuiltStatement, BulkInsertStatementInput, ColumnDefinitionInput, ColumnTypeInput, CreateIndexStatementInput, CreateTableStatementInput, Dialect, InsertStatementInput, UpsertStatementInput, } from '../dialect.js';
|
|
10
10
|
export { postgresDialect } from '../dialect.js';
|
|
11
|
+
export type { OptionKind, OptionTable } from './option-surface.js';
|
|
12
|
+
export { AGGREGATE_OPTIONS, ALL_OPTION_TABLES, applyNativeOptions, COUNT_OPTIONS, CREATE_MANY_OPTIONS, CREATE_OPTIONS, DELETE_MANY_OPTIONS, DELETE_OPTIONS, FIND_MANY_OPTIONS, FIND_MANY_STREAM_OPTIONS, FIND_UNIQUE_OPTIONS, GROUP_BY_OPTIONS, optionKeysOfKind, UPDATE_MANY_OPTIONS, UPDATE_OPTIONS, UPSERT_OPTIONS, } from './option-surface.js';
|
|
11
13
|
export type { SqlCacheEntry } from './utils.js';
|
|
12
14
|
export { buildCorrelation, escapeLike, escSingleQuote, fnv1a64Hex, LRUCache, OPERATOR_KEYS, quoteIdent, sqlToPreparedName, } from './utils.js';
|
|
13
15
|
export type { DeferredQuery, MiddlewareFn, QueryEvent, QueryEventListener, QueryInterfaceOptions, ReselectExecutor, TemporalInfinityReading, } from './builder.js';
|
package/dist/query/index.js
CHANGED
|
@@ -6,5 +6,6 @@
|
|
|
6
6
|
* former monolithic `import { … } from './query.js'`.
|
|
7
7
|
*/
|
|
8
8
|
export { postgresDialect } from '../dialect.js';
|
|
9
|
+
export { AGGREGATE_OPTIONS, ALL_OPTION_TABLES, applyNativeOptions, COUNT_OPTIONS, CREATE_MANY_OPTIONS, CREATE_OPTIONS, DELETE_MANY_OPTIONS, DELETE_OPTIONS, FIND_MANY_OPTIONS, FIND_MANY_STREAM_OPTIONS, FIND_UNIQUE_OPTIONS, GROUP_BY_OPTIONS, optionKeysOfKind, UPDATE_MANY_OPTIONS, UPDATE_OPTIONS, UPSERT_OPTIONS, } from './option-surface.js';
|
|
9
10
|
export { buildCorrelation, escapeLike, escSingleQuote, fnv1a64Hex, LRUCache, OPERATOR_KEYS, quoteIdent, sqlToPreparedName, } from './utils.js';
|
|
10
11
|
export { AUTO_ASSUMED_ROUND_TRIP_MS, AUTO_COUNT_BATCH_MIN_PARENT_ROWS, AUTO_JOIN_PENALTY_MS_PER_ROW, AUTO_TO_ONE_JOIN_MAX_ROWS, AUTO_TO_ONE_JOIN_ROWS_MAX, AUTO_TO_ONE_JOIN_ROWS_MIN, QueryInterface, } from './builder.js';
|