turbine-orm 0.55.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.d.ts +3 -1
- package/dist/cjs/cli/index.js +341 -14
- package/dist/cjs/client.d.ts +16 -1
- package/dist/cjs/client.js +7 -39
- package/dist/cjs/dialect.d.ts +9 -0
- package/dist/cjs/index-stats.d.ts +46 -0
- package/dist/cjs/index-stats.js +42 -1
- package/dist/cjs/plan-divergence.d.ts +511 -0
- package/dist/cjs/plan-divergence.js +790 -0
- package/dist/cjs/powql.d.ts +11 -0
- package/dist/cjs/powql.js +22 -0
- package/dist/cjs/prisma-compat.d.ts +32 -1
- package/dist/cjs/prisma-compat.js +297 -41
- package/dist/cjs/query/builder.d.ts +45 -0
- package/dist/cjs/query/builder.js +90 -17
- package/dist/cjs/query/deferred.d.ts +9 -0
- 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/types.d.ts +140 -0
- package/dist/cjs/query/utils.d.ts +30 -0
- package/dist/cjs/query/utils.js +67 -3
- package/dist/cjs/query/warn-registry.d.ts +8 -0
- package/dist/cjs/query/warn-registry.js +8 -0
- package/dist/cli/index.d.ts +3 -1
- package/dist/cli/index.js +341 -14
- package/dist/client.d.ts +16 -1
- package/dist/client.js +8 -40
- package/dist/dialect.d.ts +9 -0
- package/dist/index-stats.d.ts +46 -0
- package/dist/index-stats.js +42 -1
- package/dist/plan-divergence.d.ts +511 -0
- package/dist/plan-divergence.js +783 -0
- package/dist/powql.d.ts +11 -0
- package/dist/powql.js +22 -0
- package/dist/prisma-compat.d.ts +32 -1
- package/dist/prisma-compat.js +297 -41
- package/dist/query/builder.d.ts +45 -0
- package/dist/query/builder.js +90 -17
- package/dist/query/deferred.d.ts +9 -0
- 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/types.d.ts +140 -0
- package/dist/query/utils.d.ts +30 -0
- package/dist/query/utils.js +66 -3
- package/dist/query/warn-registry.d.ts +8 -0
- package/dist/query/warn-registry.js +8 -0
- package/package.json +1 -1
package/dist/cjs/powql.d.ts
CHANGED
|
@@ -125,6 +125,17 @@ export declare class PowqlInterface<T extends object = Record<string, unknown>>
|
|
|
125
125
|
* callers short-circuit it, because PowDB's projection fast path returned ONE
|
|
126
126
|
* row for `limit 0` below 0.20.
|
|
127
127
|
*/
|
|
128
|
+
/**
|
|
129
|
+
* Refuse the per-query `forceCustomPlan` read option.
|
|
130
|
+
*
|
|
131
|
+
* `FindManyArgs.forceCustomPlan` documents an `UnsupportedFeatureError` on any
|
|
132
|
+
* engine with no PostgreSQL plan cache, and PowDB is one: it is not a
|
|
133
|
+
* `Dialect` at all, so it never reaches the SQL builder's own refusal at
|
|
134
|
+
* `preparedNameFor`. Without this the flag would be silently ignored here,
|
|
135
|
+
* which is precisely the "reports a guarantee that was never made" failure the
|
|
136
|
+
* option's refusal exists to prevent.
|
|
137
|
+
*/
|
|
138
|
+
private assertNoForceCustomPlan;
|
|
128
139
|
private assertPagination;
|
|
129
140
|
/** A predicate that is always false, the empty-`in` / contradiction sentinel. */
|
|
130
141
|
private alwaysFalse;
|
package/dist/cjs/powql.js
CHANGED
|
@@ -328,6 +328,22 @@ class PowqlInterface {
|
|
|
328
328
|
* callers short-circuit it, because PowDB's projection fast path returned ONE
|
|
329
329
|
* row for `limit 0` below 0.20.
|
|
330
330
|
*/
|
|
331
|
+
/**
|
|
332
|
+
* Refuse the per-query `forceCustomPlan` read option.
|
|
333
|
+
*
|
|
334
|
+
* `FindManyArgs.forceCustomPlan` documents an `UnsupportedFeatureError` on any
|
|
335
|
+
* engine with no PostgreSQL plan cache, and PowDB is one: it is not a
|
|
336
|
+
* `Dialect` at all, so it never reaches the SQL builder's own refusal at
|
|
337
|
+
* `preparedNameFor`. Without this the flag would be silently ignored here,
|
|
338
|
+
* which is precisely the "reports a guarantee that was never made" failure the
|
|
339
|
+
* option's refusal exists to prevent.
|
|
340
|
+
*/
|
|
341
|
+
assertNoForceCustomPlan(args) {
|
|
342
|
+
if (args?.forceCustomPlan !== true)
|
|
343
|
+
return;
|
|
344
|
+
throw new errors_js_1.UnsupportedFeatureError('The forceCustomPlan query option', 'powdb', 'Forcing a per-query custom plan means keeping the statement out of the PostgreSQL plan cache, and PowDB ' +
|
|
345
|
+
'has no such cache to keep it out of. Remove the option, or set it only on PostgreSQL queries.');
|
|
346
|
+
}
|
|
331
347
|
assertPagination(limit, offset, context) {
|
|
332
348
|
for (const [name, value] of [
|
|
333
349
|
['limit', limit],
|
|
@@ -1157,6 +1173,7 @@ class PowqlInterface {
|
|
|
1157
1173
|
// Reads
|
|
1158
1174
|
// -------------------------------------------------------------------------
|
|
1159
1175
|
async findMany(args = {}) {
|
|
1176
|
+
this.assertNoForceCustomPlan(args);
|
|
1160
1177
|
return this.withMiddleware('findMany', args, async () => {
|
|
1161
1178
|
// `limit: 0` means "no rows" (SQL `LIMIT 0`), and answering it client-side
|
|
1162
1179
|
// is correct on every engine version: PowDB's projection fast path returned
|
|
@@ -1296,6 +1313,7 @@ class PowqlInterface {
|
|
|
1296
1313
|
.filter((line) => line.length > 0);
|
|
1297
1314
|
}
|
|
1298
1315
|
async findUnique(args) {
|
|
1316
|
+
this.assertNoForceCustomPlan(args);
|
|
1299
1317
|
// Prisma compound-unique selector → column conjunction (engine parity with
|
|
1300
1318
|
// the SQL findUnique family; pure metadata, so this is a one-line adoption).
|
|
1301
1319
|
if (args.where) {
|
|
@@ -1318,6 +1336,7 @@ class PowqlInterface {
|
|
|
1318
1336
|
});
|
|
1319
1337
|
}
|
|
1320
1338
|
async findFirst(args = {}) {
|
|
1339
|
+
this.assertNoForceCustomPlan(args);
|
|
1321
1340
|
return this.withMiddleware('findFirst', args, async () => {
|
|
1322
1341
|
const { rows, native, nestedPlans, linkPlans, residualWith } = await this.runFind({ ...args, limit: 1 }, 'findFirst');
|
|
1323
1342
|
if (!rows.length)
|
|
@@ -2524,6 +2543,7 @@ class PowqlInterface {
|
|
|
2524
2543
|
// Aggregates
|
|
2525
2544
|
// -------------------------------------------------------------------------
|
|
2526
2545
|
async count(args = {}) {
|
|
2546
|
+
this.assertNoForceCustomPlan(args);
|
|
2527
2547
|
return this.withMiddleware('count', (args ?? {}), async () => {
|
|
2528
2548
|
const params = [];
|
|
2529
2549
|
const resolvedWhere = await this.resolveRelationFilters(args.where, args.timeout);
|
|
@@ -2562,6 +2582,7 @@ class PowqlInterface {
|
|
|
2562
2582
|
'`_count` of a NOT NULL column are correct on every version and are never refused.');
|
|
2563
2583
|
}
|
|
2564
2584
|
async aggregate(args) {
|
|
2585
|
+
this.assertNoForceCustomPlan(args);
|
|
2565
2586
|
return this.withMiddleware('aggregate', args, async () => {
|
|
2566
2587
|
// One scalar query per aggregate, PowDB's bare-projection aggregate is broken.
|
|
2567
2588
|
const result = {};
|
|
@@ -2607,6 +2628,7 @@ class PowqlInterface {
|
|
|
2607
2628
|
});
|
|
2608
2629
|
}
|
|
2609
2630
|
async groupBy(args) {
|
|
2631
|
+
this.assertNoForceCustomPlan(args);
|
|
2610
2632
|
return this.withMiddleware('groupBy', args, async () => {
|
|
2611
2633
|
// DISTINCT ON has no PowQL equivalent (no DISTINCT ON row source).
|
|
2612
2634
|
if (args.distinctOn) {
|
|
@@ -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
|
/**
|
|
@@ -32,6 +32,15 @@
|
|
|
32
32
|
* atomic.
|
|
33
33
|
* - **Result reshaping**: `_count` objects keyed back to Prisma relation names,
|
|
34
34
|
* and to-one relations surfaced as `object | null`.
|
|
35
|
+
* - **Turbine-native query options** (`timeout`, `forceCustomPlan`,
|
|
36
|
+
* `warnOnUnlimited`, `skipGlobalFilters`, `stableRelationOrder`,
|
|
37
|
+
* `allowFullTableScan`, `includePii`, `optimisticLock`, `distinctOn`) reach
|
|
38
|
+
* core on every operation whose arg surface declares them. The set is not a
|
|
39
|
+
* hand-maintained list here: it comes from the compiler-checked tables in
|
|
40
|
+
* `query/option-surface.ts`, so a new core option cannot be silently stranded
|
|
41
|
+
* by this layer, and a key that is neither a Prisma arg nor a turbine option
|
|
42
|
+
* gets a dev-mode warning instead of vanishing (see
|
|
43
|
+
* {@link PRISMA_ARG_KEYS} and `warnUnknownQueryOptions`).
|
|
35
44
|
*
|
|
36
45
|
* ## What it deliberately does NOT do (documented divergences)
|
|
37
46
|
*
|
|
@@ -64,6 +73,14 @@
|
|
|
64
73
|
* exclusive-cursor + `offset` translation.
|
|
65
74
|
* - **Negative `take`** (take-from-end) and **`skip` on a nested relation
|
|
66
75
|
* include** throw, Turbine's `with` clause has no offset and no reverse-take.
|
|
76
|
+
* - **`limit` on `updateMany` / `deleteMany`** (Prisma 6.7+) throws. Turbine has
|
|
77
|
+
* no row-bounded mass mutation, and dropping a SAFETY BOUND with a warning
|
|
78
|
+
* would turn "change at most 10 rows" into "change every matching row".
|
|
79
|
+
* - **Write projections** (`select` / `include` / `omit` on
|
|
80
|
+
* create/update/delete/upsert), **`select` on `count`**, and
|
|
81
|
+
* **`orderBy` / `cursor` / `take` / `skip` on `aggregate`** are accepted and
|
|
82
|
+
* IGNORED (they are legitimate Prisma, so they never warn); the full row / a
|
|
83
|
+
* plain number comes back.
|
|
67
84
|
*
|
|
68
85
|
* ## Type dependencies (0.41.0)
|
|
69
86
|
*
|
|
@@ -94,10 +111,12 @@
|
|
|
94
111
|
* ```
|
|
95
112
|
*/
|
|
96
113
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
97
|
-
exports.CLIENT_RESERVED_KEYS = exports.COMPAT_DEFERRED = exports.Prisma = void 0;
|
|
114
|
+
exports.CLIENT_RESERVED_KEYS = exports.COMPAT_DEFERRED = exports.PRISMA_ARG_KEYS = exports.Prisma = void 0;
|
|
98
115
|
exports.createPrismaCompatClient = createPrismaCompatClient;
|
|
99
116
|
const errors_js_1 = require("./errors.js");
|
|
100
117
|
const nested_write_js_1 = require("./nested-write.js");
|
|
118
|
+
const index_js_1 = require("./query/index.js");
|
|
119
|
+
const utils_js_1 = require("./query/utils.js");
|
|
101
120
|
const warn_registry_js_1 = require("./query/warn-registry.js");
|
|
102
121
|
// ---------------------------------------------------------------------------
|
|
103
122
|
// Prisma.sql-style raw fragments (local, minimal, never imports @prisma/client)
|
|
@@ -256,6 +275,199 @@ function isPlainObject(v) {
|
|
|
256
275
|
function renameField(mm, prismaField) {
|
|
257
276
|
return mm.fields[prismaField] ?? prismaField;
|
|
258
277
|
}
|
|
278
|
+
/** The turbine arg surface each operation compiles into. */
|
|
279
|
+
const OPERATION_TABLES = {
|
|
280
|
+
findMany: index_js_1.FIND_MANY_OPTIONS,
|
|
281
|
+
findFirst: index_js_1.FIND_MANY_OPTIONS,
|
|
282
|
+
findFirstOrThrow: index_js_1.FIND_MANY_OPTIONS,
|
|
283
|
+
findUnique: index_js_1.FIND_UNIQUE_OPTIONS,
|
|
284
|
+
findUniqueOrThrow: index_js_1.FIND_UNIQUE_OPTIONS,
|
|
285
|
+
create: index_js_1.CREATE_OPTIONS,
|
|
286
|
+
createMany: index_js_1.CREATE_MANY_OPTIONS,
|
|
287
|
+
update: index_js_1.UPDATE_OPTIONS,
|
|
288
|
+
updateMany: index_js_1.UPDATE_MANY_OPTIONS,
|
|
289
|
+
delete: index_js_1.DELETE_OPTIONS,
|
|
290
|
+
deleteMany: index_js_1.DELETE_MANY_OPTIONS,
|
|
291
|
+
upsert: index_js_1.UPSERT_OPTIONS,
|
|
292
|
+
count: index_js_1.COUNT_OPTIONS,
|
|
293
|
+
aggregate: index_js_1.AGGREGATE_OPTIONS,
|
|
294
|
+
groupBy: index_js_1.GROUP_BY_OPTIONS,
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Every argument key Prisma itself accepts, per operation.
|
|
298
|
+
*
|
|
299
|
+
* Extracted from a generated `@prisma/client` 7.9.0 `index.d.ts` (the
|
|
300
|
+
* `<Model><Op>Args` blocks). It must stay the UNION across the Prisma majors
|
|
301
|
+
* this adapter supports, never one version's set: a key a newer major
|
|
302
|
+
* introduces should degrade to one noisy dev line, never to a throw, and a key
|
|
303
|
+
* an older major had must keep working. The drift test in
|
|
304
|
+
* `src/test/prisma-compat-option-surface.test.ts` re-extracts from a generated
|
|
305
|
+
* client when one is present and asserts this stays a superset.
|
|
306
|
+
*/
|
|
307
|
+
exports.PRISMA_ARG_KEYS = {
|
|
308
|
+
findMany: [
|
|
309
|
+
'select',
|
|
310
|
+
'omit',
|
|
311
|
+
'include',
|
|
312
|
+
'where',
|
|
313
|
+
'orderBy',
|
|
314
|
+
'cursor',
|
|
315
|
+
'take',
|
|
316
|
+
'skip',
|
|
317
|
+
'distinct',
|
|
318
|
+
'relationLoadStrategy',
|
|
319
|
+
],
|
|
320
|
+
findFirst: [
|
|
321
|
+
'select',
|
|
322
|
+
'omit',
|
|
323
|
+
'include',
|
|
324
|
+
'where',
|
|
325
|
+
'orderBy',
|
|
326
|
+
'cursor',
|
|
327
|
+
'take',
|
|
328
|
+
'skip',
|
|
329
|
+
'distinct',
|
|
330
|
+
'relationLoadStrategy',
|
|
331
|
+
],
|
|
332
|
+
findFirstOrThrow: [
|
|
333
|
+
'select',
|
|
334
|
+
'omit',
|
|
335
|
+
'include',
|
|
336
|
+
'where',
|
|
337
|
+
'orderBy',
|
|
338
|
+
'cursor',
|
|
339
|
+
'take',
|
|
340
|
+
'skip',
|
|
341
|
+
'distinct',
|
|
342
|
+
'relationLoadStrategy',
|
|
343
|
+
],
|
|
344
|
+
findUnique: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
345
|
+
findUniqueOrThrow: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
346
|
+
create: ['select', 'omit', 'include', 'data', 'relationLoadStrategy'],
|
|
347
|
+
createMany: ['data', 'skipDuplicates'],
|
|
348
|
+
update: ['select', 'omit', 'include', 'data', 'where', 'relationLoadStrategy'],
|
|
349
|
+
updateMany: ['data', 'where', 'limit'],
|
|
350
|
+
delete: ['select', 'omit', 'include', 'where', 'relationLoadStrategy'],
|
|
351
|
+
deleteMany: ['where', 'limit'],
|
|
352
|
+
upsert: ['select', 'omit', 'include', 'where', 'create', 'update', 'relationLoadStrategy'],
|
|
353
|
+
count: ['where', 'orderBy', 'cursor', 'take', 'skip', 'select'],
|
|
354
|
+
aggregate: ['where', 'orderBy', 'cursor', 'take', 'skip', '_count', '_avg', '_sum', '_min', '_max'],
|
|
355
|
+
groupBy: ['where', 'orderBy', 'by', 'having', 'take', 'skip', '_count', '_avg', '_sum', '_min', '_max'],
|
|
356
|
+
};
|
|
357
|
+
/**
|
|
358
|
+
* Turbine spellings whose Prisma equivalent is spelled differently. A caller
|
|
359
|
+
* who reaches for one of these is not confused about the NAME, they are
|
|
360
|
+
* confused about which surface they are on, so they get a specific message
|
|
361
|
+
* rather than a fuzzy did-you-mean.
|
|
362
|
+
*/
|
|
363
|
+
const ALIAS_HINT = {
|
|
364
|
+
limit: 'take',
|
|
365
|
+
offset: 'skip',
|
|
366
|
+
with: 'include',
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Known(op) = Prisma's own keys for that operation, plus every key the
|
|
370
|
+
* operation's turbine arg surface declares except the `'internal'` ones.
|
|
371
|
+
*
|
|
372
|
+
* The second half is NOT just the `'native'` keys. Two turbine-only options are
|
|
373
|
+
* classified `'prisma'` because their values carry field names and so must be
|
|
374
|
+
* hand-translated (`optimisticLock`, `distinctOn`); they are fully honoured, and
|
|
375
|
+
* warning about a key the adapter just acted on would be the worst possible
|
|
376
|
+
* diagnostic. `'nativeAlias'` members are in the set on purpose too: `limit` on
|
|
377
|
+
* `findMany` IS recognized, it simply gets the alias message rather than the
|
|
378
|
+
* generic one. Only `'internal'` is excluded, because nothing on this surface
|
|
379
|
+
* can reach it.
|
|
380
|
+
*
|
|
381
|
+
* A `Set` rather than an `in` test on a record, so an inherited
|
|
382
|
+
* `Object.prototype` name (`toString`, `constructor`) is treated as the unknown
|
|
383
|
+
* key it is.
|
|
384
|
+
*/
|
|
385
|
+
const KNOWN_KEYS = (() => {
|
|
386
|
+
const out = {};
|
|
387
|
+
for (const op of Object.keys(OPERATION_TABLES)) {
|
|
388
|
+
out[op] = new Set([
|
|
389
|
+
...exports.PRISMA_ARG_KEYS[op],
|
|
390
|
+
...(0, index_js_1.optionKeysOfKind)(OPERATION_TABLES[op], 'prisma', 'native', 'nativeAlias'),
|
|
391
|
+
]);
|
|
392
|
+
}
|
|
393
|
+
return out;
|
|
394
|
+
})();
|
|
395
|
+
/**
|
|
396
|
+
* Dev-mode notice for a key on a delegate's args object that this operation has
|
|
397
|
+
* no meaning for.
|
|
398
|
+
*
|
|
399
|
+
* An unrecognized key is silently ignored (JavaScript objects have no schema),
|
|
400
|
+
* which makes a typo, a turbine spelling, and a genuinely missing feature all
|
|
401
|
+
* look identical: nothing happens. The client-config warner
|
|
402
|
+
* (`warnUnknownConfigKeys` in client.ts) exists for the same reason and this is
|
|
403
|
+
* its query-level twin, down to the ranking of the suggestion.
|
|
404
|
+
*
|
|
405
|
+
* Deliberately a WARNING, never an error. Throwing would turn a working app
|
|
406
|
+
* into a failing one on upgrade over one stray key, and a key from a Prisma
|
|
407
|
+
* major newer than {@link PRISMA_ARG_KEYS} would be exactly that key. The whole
|
|
408
|
+
* body is wrapped so a hostile or exotic args object (a Proxy whose `ownKeys`
|
|
409
|
+
* throws) can never be the reason a query fails. Dev-only and once per
|
|
410
|
+
* `model.operation.key` per process, like every other advisory here.
|
|
411
|
+
*/
|
|
412
|
+
function warnUnknownQueryOptions(model, op, args) {
|
|
413
|
+
if (process.env.NODE_ENV === 'production')
|
|
414
|
+
return;
|
|
415
|
+
if (!isPlainObject(args))
|
|
416
|
+
return;
|
|
417
|
+
try {
|
|
418
|
+
const known = KNOWN_KEYS[op];
|
|
419
|
+
const table = OPERATION_TABLES[op];
|
|
420
|
+
for (const key of Object.keys(args)) {
|
|
421
|
+
// `{ ...maybeOptions }` routinely materializes keys with no value.
|
|
422
|
+
// Nothing is being dropped when the value is undefined.
|
|
423
|
+
if (args[key] === undefined)
|
|
424
|
+
continue;
|
|
425
|
+
const alias = table[key] === 'nativeAlias' ? ALIAS_HINT[key] : undefined;
|
|
426
|
+
if (!alias && known.has(key))
|
|
427
|
+
continue;
|
|
428
|
+
if (!(0, warn_registry_js_1.shouldWarnOnce)(warn_registry_js_1.WARN_NS.unknownQueryOption, `${model}.${op}.${key}`))
|
|
429
|
+
continue;
|
|
430
|
+
if (alias) {
|
|
431
|
+
console.warn(`[turbine] prisma-compat: "${key}" is Turbine's spelling and is ignored here;` +
|
|
432
|
+
` prisma-compat takes Prisma's "${alias}". (${model}.${op})`);
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
const suggestion = (0, utils_js_1.suggestKey)(key, known);
|
|
436
|
+
console.warn(`[turbine] prisma-compat: unknown option "${key}" in ${model}.${op}(), it is ignored.` +
|
|
437
|
+
(suggestion ? ` Did you mean "${suggestion}"?` : ''));
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
catch {
|
|
441
|
+
// Key enumeration is the only thing that can fail here, and a diagnostic
|
|
442
|
+
// must never be the reason a query fails.
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Prisma 6.7+ accepts `limit` on `updateMany` / `deleteMany` to BOUND how many
|
|
447
|
+
* rows a mass mutation touches. Turbine has no row-bounded mass mutation, so
|
|
448
|
+
* this one is refused rather than warned about: everywhere else in this design
|
|
449
|
+
* a dropped option costs the caller a feature, but silently dropping a safety
|
|
450
|
+
* bound turns "change at most 10 rows" into "change every row".
|
|
451
|
+
*/
|
|
452
|
+
function refuseRowLimit(model, op, args) {
|
|
453
|
+
if (!isPlainObject(args) || args.limit === undefined)
|
|
454
|
+
return;
|
|
455
|
+
throw new errors_js_1.UnsupportedFeatureError(`\`limit\` on ${op} (row-bounded mass mutation)`, 'prisma-compat', `Turbine has no row-bounded ${op}; select the rows you mean with \`where\`` +
|
|
456
|
+
` (on ${model}.${op}), or page them and mutate by primary key.`);
|
|
457
|
+
}
|
|
458
|
+
/**
|
|
459
|
+
* Prisma's `relationLoadStrategy` and Turbine's share a name and NOT a value
|
|
460
|
+
* domain: Prisma has `'query' | 'join'`, Turbine has
|
|
461
|
+
* `'join' | 'batched' | 'auto' | 'flatten'`. Core's strategy resolution has no
|
|
462
|
+
* branch for `'query'` and returns the value unchanged, so forwarding it
|
|
463
|
+
* verbatim gave a caller who asked for the per-relation query plan the JOIN
|
|
464
|
+
* plan, the exact opposite of the request. Prisma's `'query'` IS Turbine's
|
|
465
|
+
* `'batched'` (one follow-up statement per relation); the turbine-only values
|
|
466
|
+
* pass through so a compat caller can still reach them.
|
|
467
|
+
*/
|
|
468
|
+
function mapRelationLoadStrategy(value) {
|
|
469
|
+
return value === 'query' ? 'batched' : value;
|
|
470
|
+
}
|
|
259
471
|
/**
|
|
260
472
|
* Translate a Prisma `where` (or nested relation where) into a Turbine `where`.
|
|
261
473
|
* Renames scalar field keys and relation keys through the map, recurses into
|
|
@@ -450,6 +662,13 @@ function modelName(ctx, mm) {
|
|
|
450
662
|
*/
|
|
451
663
|
function translateReadArgs(ctx, mm, prismaArgs, kind) {
|
|
452
664
|
const t = {};
|
|
665
|
+
// FIRST, so a per-call `stableRelationOrder` overrides it: the client-level
|
|
666
|
+
// option is a default, the arg is an instruction.
|
|
667
|
+
if (ctx.options.stablePkOrder)
|
|
668
|
+
t.stableRelationOrder = true;
|
|
669
|
+
// Every turbine-native option the arg surface declares, in one line that
|
|
670
|
+
// cannot fall behind the interface (see the option-surface tables).
|
|
671
|
+
(0, index_js_1.applyNativeOptions)(kind === 'unique' ? index_js_1.FIND_UNIQUE_OPTIONS : index_js_1.FIND_MANY_OPTIONS, prismaArgs, t);
|
|
453
672
|
if (prismaArgs.where !== undefined)
|
|
454
673
|
t.where = translateWhere(ctx, mm, prismaArgs.where);
|
|
455
674
|
if (prismaArgs.orderBy !== undefined)
|
|
@@ -462,17 +681,9 @@ function translateReadArgs(ctx, mm, prismaArgs, kind) {
|
|
|
462
681
|
if (Array.isArray(prismaArgs.distinct)) {
|
|
463
682
|
t.distinct = prismaArgs.distinct.map((f) => renameField(mm, f));
|
|
464
683
|
}
|
|
465
|
-
if (prismaArgs.relationLoadStrategy !== undefined)
|
|
466
|
-
t.relationLoadStrategy = prismaArgs.relationLoadStrategy;
|
|
467
|
-
|
|
468
|
-
t.timeout = prismaArgs.timeout;
|
|
469
|
-
// Turbine-only passthrough. Prisma has no PII concept, so a compat caller
|
|
470
|
-
// whose schema tags columns needs SOME way to opt in; without this the
|
|
471
|
-
// adapter is a one-way door into redacted reads and refused aggregates.
|
|
472
|
-
if (prismaArgs.includePii !== undefined)
|
|
473
|
-
t.includePii = prismaArgs.includePii;
|
|
474
|
-
if (ctx.options.stablePkOrder)
|
|
475
|
-
t.stableRelationOrder = true;
|
|
684
|
+
if (prismaArgs.relationLoadStrategy !== undefined) {
|
|
685
|
+
t.relationLoadStrategy = mapRelationLoadStrategy(prismaArgs.relationLoadStrategy);
|
|
686
|
+
}
|
|
476
687
|
// ORDER IS LOAD-BEARING: translateCursor MUST run BEFORE applyImplicitPkOrder.
|
|
477
688
|
// The cursor translation reads `t.orderBy` to decide the seek direction and to
|
|
478
689
|
// validate that a bare inclusive cursor names the sort key; it must see the
|
|
@@ -771,6 +982,7 @@ function translateUpsertNested(ctx, target, p) {
|
|
|
771
982
|
const AGG_FIELD_BLOCKS = ['_sum', '_avg', '_min', '_max'];
|
|
772
983
|
function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
773
984
|
const t = {};
|
|
985
|
+
(0, index_js_1.applyNativeOptions)(isGroupBy ? index_js_1.GROUP_BY_OPTIONS : index_js_1.AGGREGATE_OPTIONS, args, t);
|
|
774
986
|
if (args.where !== undefined)
|
|
775
987
|
t.where = translateWhere(ctx, mm, args.where);
|
|
776
988
|
if (args._count !== undefined)
|
|
@@ -779,12 +991,6 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
779
991
|
if (args[block] !== undefined)
|
|
780
992
|
t[block] = renameAggBlock(mm, args[block], false);
|
|
781
993
|
}
|
|
782
|
-
if (typeof args.timeout === 'number')
|
|
783
|
-
t.timeout = args.timeout;
|
|
784
|
-
// Turbine-only passthrough: the PII gate on groupBy keys and _min/_max needs
|
|
785
|
-
// an opt-in that Prisma's arg shape has no equivalent for.
|
|
786
|
-
if (args.includePii !== undefined)
|
|
787
|
-
t.includePii = args.includePii;
|
|
788
994
|
if (isGroupBy) {
|
|
789
995
|
if (Array.isArray(args.by))
|
|
790
996
|
t.by = args.by.map((f) => renameField(mm, f));
|
|
@@ -792,6 +998,8 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
792
998
|
t.orderBy = translateOrderBy(ctx, mm, args.orderBy);
|
|
793
999
|
if (args.having !== undefined)
|
|
794
1000
|
t.having = renameHaving(mm, args.having);
|
|
1001
|
+
if (args.distinctOn !== undefined)
|
|
1002
|
+
t.distinctOn = translateDistinctOn(ctx, mm, args.distinctOn);
|
|
795
1003
|
if (typeof args.take === 'number')
|
|
796
1004
|
t.limit = mapTake(args.take);
|
|
797
1005
|
if (typeof args.skip === 'number')
|
|
@@ -799,6 +1007,23 @@ function translateAggregateArgs(ctx, mm, args, isGroupBy) {
|
|
|
799
1007
|
}
|
|
800
1008
|
return t;
|
|
801
1009
|
}
|
|
1010
|
+
/**
|
|
1011
|
+
* Translate a turbine-native groupBy `distinctOn`. Both halves of its value
|
|
1012
|
+
* (`columns`, `orderBy`) are FIELD NAMES, so this is the concrete reason the
|
|
1013
|
+
* option surface refuses to copy unknown keys through by default: a blind
|
|
1014
|
+
* passthrough is correct on a model whose Prisma and turbine names coincide and
|
|
1015
|
+
* silently wrong on one with a `@map`.
|
|
1016
|
+
*/
|
|
1017
|
+
function translateDistinctOn(ctx, mm, val) {
|
|
1018
|
+
if (!isPlainObject(val))
|
|
1019
|
+
return val;
|
|
1020
|
+
const out = { ...val };
|
|
1021
|
+
if (Array.isArray(val.columns))
|
|
1022
|
+
out.columns = val.columns.map((f) => renameField(mm, f));
|
|
1023
|
+
if (val.orderBy !== undefined)
|
|
1024
|
+
out.orderBy = translateOrderBy(ctx, mm, val.orderBy);
|
|
1025
|
+
return out;
|
|
1026
|
+
}
|
|
802
1027
|
/** Rename field keys inside an aggregate block; `_count`'s `_all` passes through. */
|
|
803
1028
|
function renameAggBlock(mm, block, isCount) {
|
|
804
1029
|
if (block === true || !isPlainObject(block))
|
|
@@ -1143,6 +1368,8 @@ async function createManyByRun(qi, t, runs) {
|
|
|
1143
1368
|
const args = { data: run };
|
|
1144
1369
|
if (t.skipDuplicates)
|
|
1145
1370
|
args.skipDuplicates = true;
|
|
1371
|
+
if (t.timeout !== undefined)
|
|
1372
|
+
args.timeout = t.timeout;
|
|
1146
1373
|
count += (await qi.createMany(args)).length;
|
|
1147
1374
|
}
|
|
1148
1375
|
return { count };
|
|
@@ -1158,7 +1385,14 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1158
1385
|
// async run wrapper also converts any synchronous throw from the underlying
|
|
1159
1386
|
// `qi.*` build into a rejection; the array `$transaction([...])` batch path
|
|
1160
1387
|
// catches the same throw from `batch.build`.
|
|
1161
|
-
const defer = (
|
|
1388
|
+
const defer = (op, rawArgs, translateRaw, run, batch) => {
|
|
1389
|
+
// The unknown-key check rides the SAME deferred boundary as the translation
|
|
1390
|
+
// itself, for the same reason (see the comment above): a compat promise that
|
|
1391
|
+
// is built and never awaited must produce no output at all.
|
|
1392
|
+
const translate = () => {
|
|
1393
|
+
warnUnknownQueryOptions(modelName(ctx, mm), op, rawArgs);
|
|
1394
|
+
return translateRaw();
|
|
1395
|
+
};
|
|
1162
1396
|
const batchable = batch
|
|
1163
1397
|
? {
|
|
1164
1398
|
build: () => batch.build(getQI(), translate()),
|
|
@@ -1198,27 +1432,27 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1198
1432
|
return args;
|
|
1199
1433
|
};
|
|
1200
1434
|
return {
|
|
1201
|
-
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) }),
|
|
1202
|
-
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) }),
|
|
1203
|
-
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) }),
|
|
1204
|
-
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) }),
|
|
1205
|
-
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) }),
|
|
1206
|
-
create: (args) => defer(() => {
|
|
1435
|
+
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) }),
|
|
1436
|
+
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) }),
|
|
1437
|
+
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) }),
|
|
1438
|
+
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) }),
|
|
1439
|
+
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) }),
|
|
1440
|
+
create: (args) => defer('create', args, () => {
|
|
1207
1441
|
const t = { data: translateWriteData(ctx, mm, applyCreateDefaults(mm, args.data)) };
|
|
1208
|
-
|
|
1209
|
-
t.timeout = args.timeout;
|
|
1442
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.CREATE_OPTIONS, args, t);
|
|
1210
1443
|
return t;
|
|
1211
1444
|
}, (qi, t) => qi.create(t).then((r) => reshapeRow(ctx, mm, r)), {
|
|
1212
1445
|
build: (qi, t) => qi.buildCreate(t),
|
|
1213
1446
|
reshape: (raw) => reshapeRow(ctx, mm, raw),
|
|
1214
1447
|
nested: (t) => hasNestedKeys(ctx, mm, t.data),
|
|
1215
1448
|
}),
|
|
1216
|
-
createMany: (args) => defer(() => {
|
|
1449
|
+
createMany: (args) => defer('createMany', args, () => {
|
|
1217
1450
|
const data = args.data;
|
|
1218
1451
|
const rows = Array.isArray(data)
|
|
1219
1452
|
? data.map((d) => translateWriteData(ctx, mm, applyCreateDefaults(mm, d)))
|
|
1220
1453
|
: [];
|
|
1221
1454
|
const t = { data: rows };
|
|
1455
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.CREATE_MANY_OPTIONS, args, t);
|
|
1222
1456
|
if (args.skipDuplicates)
|
|
1223
1457
|
t.skipDuplicates = true;
|
|
1224
1458
|
return t;
|
|
@@ -1239,45 +1473,68 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1239
1473
|
nested: (t) => createManyRunsOf(t).length > 1,
|
|
1240
1474
|
execInTx: (table, t) => createManyByRun(table(mm.table), t, createManyRunsOf(t)),
|
|
1241
1475
|
}),
|
|
1242
|
-
update: (args) => defer(() => {
|
|
1476
|
+
update: (args) => defer('update', args, () => {
|
|
1243
1477
|
const a = requireWhere(args, 'update');
|
|
1244
|
-
|
|
1478
|
+
const t = {
|
|
1245
1479
|
where: translateWhere(ctx, mm, a.where),
|
|
1246
1480
|
data: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.data)),
|
|
1247
1481
|
};
|
|
1482
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.UPDATE_OPTIONS, a, t);
|
|
1483
|
+
// `optimisticLock.field` is a FIELD NAME, so it is renamed rather than
|
|
1484
|
+
// copied: a blind passthrough would send the Prisma spelling into core
|
|
1485
|
+
// and break on any model whose column is `@map`ped.
|
|
1486
|
+
if (isPlainObject(a.optimisticLock)) {
|
|
1487
|
+
t.optimisticLock = {
|
|
1488
|
+
...a.optimisticLock,
|
|
1489
|
+
field: renameField(mm, String(a.optimisticLock.field)),
|
|
1490
|
+
};
|
|
1491
|
+
}
|
|
1492
|
+
return t;
|
|
1248
1493
|
}, (qi, t) => qi.update(t).then((r) => reshapeRow(ctx, mm, r)), {
|
|
1249
1494
|
build: (qi, t) => qi.buildUpdate(t),
|
|
1250
1495
|
reshape: (raw) => reshapeRow(ctx, mm, raw),
|
|
1251
1496
|
nested: (t) => hasNestedKeys(ctx, mm, t.data),
|
|
1252
1497
|
}),
|
|
1253
|
-
updateMany: (args) => defer(() => {
|
|
1498
|
+
updateMany: (args) => defer('updateMany', args, () => {
|
|
1254
1499
|
const a = args;
|
|
1500
|
+
refuseRowLimit(modelName(ctx, mm), 'updateMany', a);
|
|
1255
1501
|
const t = {
|
|
1256
1502
|
where: translateWhere(ctx, mm, a.where ?? {}),
|
|
1257
1503
|
data: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.data)),
|
|
1258
1504
|
};
|
|
1505
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.UPDATE_MANY_OPTIONS, a, t);
|
|
1506
|
+
// LAST, so it wins: a Prisma updateMany with no `where` affects every
|
|
1507
|
+
// row, and an explicit `allowFullTableScan: false` must not be able to
|
|
1508
|
+
// turn that parity into a thrown empty-where guard.
|
|
1259
1509
|
if (a.where === undefined)
|
|
1260
1510
|
t.allowFullTableScan = true;
|
|
1261
1511
|
return t;
|
|
1262
1512
|
}, (qi, t) => qi.updateMany(t), { build: (qi, t) => qi.buildUpdateMany(t), reshape: (raw) => raw }),
|
|
1263
|
-
delete: (args) => defer(() => {
|
|
1513
|
+
delete: (args) => defer('delete', args, () => {
|
|
1264
1514
|
const a = requireWhere(args, 'delete');
|
|
1265
|
-
|
|
1515
|
+
const t = { where: translateWhere(ctx, mm, a.where) };
|
|
1516
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.DELETE_OPTIONS, a, t);
|
|
1517
|
+
return t;
|
|
1266
1518
|
}, (qi, t) => qi.delete(t).then((r) => reshapeRow(ctx, mm, r)), { build: (qi, t) => qi.buildDelete(t), reshape: (raw) => reshapeRow(ctx, mm, raw) }),
|
|
1267
|
-
deleteMany: (args = {}) => defer(() => {
|
|
1519
|
+
deleteMany: (args = {}) => defer('deleteMany', args, () => {
|
|
1268
1520
|
const a = args;
|
|
1521
|
+
refuseRowLimit(modelName(ctx, mm), 'deleteMany', a);
|
|
1269
1522
|
const t = { where: translateWhere(ctx, mm, a.where ?? {}) };
|
|
1523
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.DELETE_MANY_OPTIONS, a, t);
|
|
1524
|
+
// LAST, so it wins. See the same note on updateMany.
|
|
1270
1525
|
if (a.where === undefined)
|
|
1271
1526
|
t.allowFullTableScan = true;
|
|
1272
1527
|
return t;
|
|
1273
1528
|
}, (qi, t) => qi.deleteMany(t), { build: (qi, t) => qi.buildDeleteMany(t), reshape: (raw) => raw }),
|
|
1274
|
-
upsert: (args) => defer(() => {
|
|
1529
|
+
upsert: (args) => defer('upsert', args, () => {
|
|
1275
1530
|
const a = requireWhere(args, 'upsert');
|
|
1276
|
-
|
|
1531
|
+
const t = {
|
|
1277
1532
|
where: translateWhere(ctx, mm, a.where),
|
|
1278
1533
|
create: translateWriteData(ctx, mm, applyCreateDefaults(mm, a.create)),
|
|
1279
1534
|
update: translateWriteData(ctx, mm, applyUpdateTouch(mm, a.update)),
|
|
1280
1535
|
};
|
|
1536
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.UPSERT_OPTIONS, a, t);
|
|
1537
|
+
return t;
|
|
1281
1538
|
}, (qi, t) => {
|
|
1282
1539
|
// Native ON CONFLICT upsert is only Prisma-equivalent when the where
|
|
1283
1540
|
// key values equal the create values AND no nested write data is
|
|
@@ -1300,16 +1557,15 @@ function makeDelegate(ctx, mm, getQI, runInTx) {
|
|
|
1300
1557
|
return reshapeRow(ctx, mm, await upsertLookupFirst(table(mm.table), t));
|
|
1301
1558
|
},
|
|
1302
1559
|
}),
|
|
1303
|
-
count: (args = {}) => defer(() => {
|
|
1560
|
+
count: (args = {}) => defer('count', args, () => {
|
|
1304
1561
|
const t = {};
|
|
1562
|
+
(0, index_js_1.applyNativeOptions)(index_js_1.COUNT_OPTIONS, args, t);
|
|
1305
1563
|
if (args.where !== undefined)
|
|
1306
1564
|
t.where = translateWhere(ctx, mm, args.where);
|
|
1307
|
-
if (typeof args.timeout === 'number')
|
|
1308
|
-
t.timeout = args.timeout;
|
|
1309
1565
|
return t;
|
|
1310
1566
|
}, (qi, t) => qi.count(t), { build: (qi, t) => qi.buildCount(t), reshape: (raw) => raw }),
|
|
1311
|
-
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) }),
|
|
1312
|
-
groupBy: (args) => defer(() => translateAggregateArgs(ctx, mm, args, true), (qi, t) => qi.groupBy(t).then((rows) => rows.map((r) => reshapeGroupRow(ctx, mm, r))), {
|
|
1567
|
+
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) }),
|
|
1568
|
+
groupBy: (args) => defer('groupBy', args, () => translateAggregateArgs(ctx, mm, args, true), (qi, t) => qi.groupBy(t).then((rows) => rows.map((r) => reshapeGroupRow(ctx, mm, r))), {
|
|
1313
1569
|
build: (qi, t) => qi.buildGroupBy(t),
|
|
1314
1570
|
reshape: (raw) => raw.map((r) => reshapeGroupRow(ctx, mm, r)),
|
|
1315
1571
|
}),
|