turbine-orm 0.60.1 → 0.62.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 +71 -27
- package/dist/cjs/cli/config.d.ts +40 -0
- package/dist/cjs/cli/config.js +74 -2
- package/dist/cjs/cli/index.d.ts +85 -1
- package/dist/cjs/cli/index.js +374 -24
- package/dist/cjs/cli/mcp.d.ts +8 -0
- package/dist/cjs/cli/mcp.js +448 -29
- package/dist/cjs/cli/pii-tags.d.ts +64 -9
- package/dist/cjs/cli/pii-tags.js +218 -39
- package/dist/cjs/cli/studio-ui.generated.js +1 -1
- package/dist/cjs/cli/studio.d.ts +23 -0
- package/dist/cjs/cli/studio.js +126 -53
- package/dist/cjs/cli/ui.d.ts +15 -1
- package/dist/cjs/cli/ui.js +19 -5
- package/dist/cjs/client.js +248 -11
- package/dist/cjs/errors.d.ts +38 -1
- package/dist/cjs/errors.js +235 -24
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +7 -2
- package/dist/cjs/pipeline-submittable.js +26 -3
- package/dist/cjs/pipeline.js +15 -2
- package/dist/cjs/powql.d.ts +12 -0
- package/dist/cjs/powql.js +46 -21
- package/dist/cjs/prisma-compat.d.ts +15 -5
- package/dist/cjs/prisma-compat.js +273 -78
- package/dist/cjs/query/aggregates.d.ts +1 -1
- package/dist/cjs/query/aggregates.js +24 -10
- package/dist/cjs/query/batched-loader.d.ts +9 -4
- package/dist/cjs/query/batched-loader.js +4 -1
- package/dist/cjs/query/builder.d.ts +47 -0
- package/dist/cjs/query/builder.js +149 -21
- package/dist/cjs/query/index.d.ts +3 -1
- package/dist/cjs/query/index.js +7 -1
- package/dist/cjs/query/option-surface.d.ts +11 -0
- package/dist/cjs/query/option-surface.js +13 -0
- package/dist/cjs/query/relations.d.ts +8 -0
- package/dist/cjs/query/relations.js +21 -1
- package/dist/cjs/query/types.d.ts +152 -18
- package/dist/cjs/query/types.js +212 -1
- package/dist/cjs/query/where.d.ts +3 -3
- package/dist/cjs/query/where.js +8 -2
- package/dist/cjs/query/writes.js +10 -9
- package/dist/cli/config.d.ts +40 -0
- package/dist/cli/config.js +73 -2
- package/dist/cli/index.d.ts +85 -1
- package/dist/cli/index.js +373 -27
- package/dist/cli/mcp.d.ts +8 -0
- package/dist/cli/mcp.js +448 -29
- package/dist/cli/pii-tags.d.ts +64 -9
- package/dist/cli/pii-tags.js +217 -39
- package/dist/cli/studio-ui.generated.js +1 -1
- package/dist/cli/studio.d.ts +23 -0
- package/dist/cli/studio.js +125 -53
- package/dist/cli/ui.d.ts +15 -1
- package/dist/cli/ui.js +18 -4
- package/dist/client.js +250 -13
- package/dist/errors.d.ts +38 -1
- package/dist/errors.js +234 -23
- package/dist/index.d.ts +2 -2
- package/dist/index.js +5 -2
- package/dist/pipeline-submittable.js +26 -3
- package/dist/pipeline.js +15 -2
- package/dist/powql.d.ts +12 -0
- package/dist/powql.js +46 -21
- package/dist/prisma-compat.d.ts +15 -5
- package/dist/prisma-compat.js +274 -79
- package/dist/query/aggregates.d.ts +1 -1
- package/dist/query/aggregates.js +24 -10
- package/dist/query/batched-loader.d.ts +9 -4
- package/dist/query/batched-loader.js +4 -1
- package/dist/query/builder.d.ts +47 -0
- package/dist/query/builder.js +148 -21
- package/dist/query/index.d.ts +3 -1
- package/dist/query/index.js +2 -0
- package/dist/query/option-surface.d.ts +11 -0
- package/dist/query/option-surface.js +13 -0
- package/dist/query/relations.d.ts +8 -0
- package/dist/query/relations.js +21 -1
- package/dist/query/types.d.ts +152 -18
- package/dist/query/types.js +207 -2
- package/dist/query/where.d.ts +3 -3
- package/dist/query/where.js +8 -2
- package/dist/query/writes.js +10 -9
- package/package.json +13 -3
package/dist/powql.js
CHANGED
|
@@ -41,6 +41,10 @@ import { ALL_POWDB_CAPABILITIES, coerceNativeValue, isJsonColumn, isPowdbDatetim
|
|
|
41
41
|
import { assertAggregatePiiOptIn } from './query/aggregates.js';
|
|
42
42
|
import { expandCompoundUniqueWhere } from './query/compound-unique.js';
|
|
43
43
|
import { isJsonFilter, isRelationPickOrderBy, orderByEntries } from './query/filters.js';
|
|
44
|
+
// The privilege sentinel and its resolver: `includePii` / `allowFullTableScan`
|
|
45
|
+
// are unlocked ONLY by the UNSAFE symbol, on this engine exactly as on the SQL
|
|
46
|
+
// engines, so a spread request body cannot turn either on here either.
|
|
47
|
+
import { assertDirectionToken, resolveUnsafeFlag, UNSAFE } from './query/types.js';
|
|
44
48
|
import { escapeLike } from './query/utils.js';
|
|
45
49
|
import { assertJsonFilterKeys, jsonStringEntries } from './query/where.js';
|
|
46
50
|
import { normalizeKeyColumns, snakeToCamel, } from './schema.js';
|
|
@@ -954,6 +958,21 @@ export class PowqlInterface {
|
|
|
954
958
|
* contract): for identical cross-engine results pass `nulls: 'last'`
|
|
955
959
|
* explicitly on Postgres, which defaults nulls-first for `desc`.
|
|
956
960
|
*/
|
|
961
|
+
/**
|
|
962
|
+
* Validate one orderBy direction token and return the PowQL keyword.
|
|
963
|
+
*
|
|
964
|
+
* Every direction site on this engine used to be spelled
|
|
965
|
+
* `x === 'desc' ? 'desc' : 'asc'`, so `'DESC'`, a token the CORE explicitly
|
|
966
|
+
* accepts and honours, compiled to `asc` here: identical application code
|
|
967
|
+
* sorted one way on Postgres and silently the opposite way on PowDB. The rule
|
|
968
|
+
* is core's {@link assertDirectionToken}, reused rather than re-derived, so
|
|
969
|
+
* the two engines cannot drift again. `undefined` stays "not specified"
|
|
970
|
+
* (defaults asc); `null` is a VALUE and is refused like any other bad token.
|
|
971
|
+
*/
|
|
972
|
+
dirKeyword(value, context) {
|
|
973
|
+
assertDirectionToken(value, context);
|
|
974
|
+
return typeof value === 'string' && value.toLowerCase() === 'desc' ? 'desc' : 'asc';
|
|
975
|
+
}
|
|
957
976
|
buildOrder(orderBy, params, alias) {
|
|
958
977
|
if (!orderBy)
|
|
959
978
|
return '';
|
|
@@ -974,7 +993,7 @@ export class PowqlInterface {
|
|
|
974
993
|
if (spec.nulls === 'first') {
|
|
975
994
|
throw new UnsupportedFeatureError('NULLS FIRST placement', 'PowDB', `field "${field}": PowDB orders NULLs / missing keys LAST in both directions`);
|
|
976
995
|
}
|
|
977
|
-
return `${this.ref(field, alias)} ${spec.sort
|
|
996
|
+
return `${this.ref(field, alias)} ${this.dirKeyword(spec.sort, `orderBy on "${field}"`)}`;
|
|
978
997
|
}
|
|
979
998
|
// Name the actual feature in the refusal, a pick-row ordering
|
|
980
999
|
// reported as "vector / distance ordering" sends users hunting for
|
|
@@ -990,7 +1009,7 @@ export class PowqlInterface {
|
|
|
990
1009
|
: 'object-valued ordering';
|
|
991
1010
|
throw new UnsupportedFeatureError(feature, 'PowDB', `field "${field}"`);
|
|
992
1011
|
}
|
|
993
|
-
return `${this.ref(field, alias)} ${dir
|
|
1012
|
+
return `${this.ref(field, alias)} ${this.dirKeyword(dir, `orderBy on "${field}"`)}`;
|
|
994
1013
|
});
|
|
995
1014
|
return ` order ${parts.join(', ')}`;
|
|
996
1015
|
}
|
|
@@ -1008,7 +1027,7 @@ export class PowqlInterface {
|
|
|
1008
1027
|
// `type: 'numeric'` casts a JSON STRING number for numeric ordering; native
|
|
1009
1028
|
// JSON numbers already order numerically without a cast.
|
|
1010
1029
|
const expr = spec.type === 'numeric' ? `cast(${pathExpr}, "float")` : pathExpr;
|
|
1011
|
-
return `${expr} ${spec.direction
|
|
1030
|
+
return `${expr} ${this.dirKeyword(spec.direction, `JSON-path orderBy on "${field}"`)}`;
|
|
1012
1031
|
}
|
|
1013
1032
|
// -------------------------------------------------------------------------
|
|
1014
1033
|
// Execution plumbing
|
|
@@ -1153,7 +1172,7 @@ export class PowqlInterface {
|
|
|
1153
1172
|
if (linkPlans.length)
|
|
1154
1173
|
this.attachLinkRows(entities, linkPlans, native);
|
|
1155
1174
|
if (residualWith) {
|
|
1156
|
-
await this.loadRelations(entities, residualWith, args.timeout, 0, { args, resolvedWhere }, args.includePii
|
|
1175
|
+
await this.loadRelations(entities, residualWith, args.timeout, 0, { args, resolvedWhere }, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
1157
1176
|
}
|
|
1158
1177
|
return entities;
|
|
1159
1178
|
});
|
|
@@ -1176,7 +1195,7 @@ export class PowqlInterface {
|
|
|
1176
1195
|
throw new UnsupportedFeatureError('cursor pagination', 'PowDB', 'use limit/offset instead');
|
|
1177
1196
|
}
|
|
1178
1197
|
const resolvedWhere = await this.resolveRelationFilters(args.where, args.timeout);
|
|
1179
|
-
const cols = this.projectedColumns(args.select, args.omit, args.includePii
|
|
1198
|
+
const cols = this.projectedColumns(args.select, args.omit, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
1180
1199
|
// Partition the `with` clause: nested-projection blocks vs loader residue.
|
|
1181
1200
|
// A parent `distinct` never nests (distinct over a row containing a JSON
|
|
1182
1201
|
// array is not a defined comparison), and a relation whose field name
|
|
@@ -1192,7 +1211,9 @@ export class PowqlInterface {
|
|
|
1192
1211
|
if (!opt)
|
|
1193
1212
|
continue;
|
|
1194
1213
|
const rel = this.meta.relations[relName];
|
|
1195
|
-
const plan = rel && !cols.includes(relName)
|
|
1214
|
+
const plan = rel && !cols.includes(relName)
|
|
1215
|
+
? this.planNestedRelation(relName, rel, opt, resolveUnsafeFlag(args.includePii, 'includePii'))
|
|
1216
|
+
: null;
|
|
1196
1217
|
if (plan) {
|
|
1197
1218
|
nestedPlans.push(plan);
|
|
1198
1219
|
continue;
|
|
@@ -1202,7 +1223,7 @@ export class PowqlInterface {
|
|
|
1202
1223
|
// inside, only when a genuine candidate reaches it), else it stays on the
|
|
1203
1224
|
// loaders.
|
|
1204
1225
|
const linkPlan = rel && !cols.includes(relName)
|
|
1205
|
-
? await this.planLinkPathRelation(relName, rel, opt, args.includePii
|
|
1226
|
+
? await this.planLinkPathRelation(relName, rel, opt, resolveUnsafeFlag(args.includePii, 'includePii'), cols, linkPlans.length + 1)
|
|
1206
1227
|
: null;
|
|
1207
1228
|
if (linkPlan)
|
|
1208
1229
|
linkPlans.push(linkPlan);
|
|
@@ -1295,7 +1316,7 @@ export class PowqlInterface {
|
|
|
1295
1316
|
if (linkPlans.length)
|
|
1296
1317
|
this.attachLinkRows(entities, linkPlans, native);
|
|
1297
1318
|
if (residualWith)
|
|
1298
|
-
await this.loadRelations(entities, residualWith, args.timeout, 0, undefined, args.includePii
|
|
1319
|
+
await this.loadRelations(entities, residualWith, args.timeout, 0, undefined, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
1299
1320
|
return entities[0];
|
|
1300
1321
|
});
|
|
1301
1322
|
}
|
|
@@ -1311,7 +1332,7 @@ export class PowqlInterface {
|
|
|
1311
1332
|
if (linkPlans.length)
|
|
1312
1333
|
this.attachLinkRows(entities, linkPlans, native);
|
|
1313
1334
|
if (residualWith)
|
|
1314
|
-
await this.loadRelations(entities, residualWith, args.timeout, 0, undefined, args.includePii
|
|
1335
|
+
await this.loadRelations(entities, residualWith, args.timeout, 0, undefined, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
1315
1336
|
return entities[0];
|
|
1316
1337
|
});
|
|
1317
1338
|
}
|
|
@@ -1431,7 +1452,9 @@ export class PowqlInterface {
|
|
|
1431
1452
|
where: childWhere,
|
|
1432
1453
|
with: options.with,
|
|
1433
1454
|
timeout: options.timeout ?? timeout,
|
|
1434
|
-
|
|
1455
|
+
// Re-entering the public findMany, so the opt-in has to be spelled
|
|
1456
|
+
// in its PUBLIC form (the sentinel); a plain `true` is refused there.
|
|
1457
|
+
includePii: includePii ? UNSAFE : undefined,
|
|
1435
1458
|
}));
|
|
1436
1459
|
for (const child of children) {
|
|
1437
1460
|
const k = this.joinKey(child[childKeyField]);
|
|
@@ -1536,7 +1559,8 @@ export class PowqlInterface {
|
|
|
1536
1559
|
where,
|
|
1537
1560
|
with: options.with,
|
|
1538
1561
|
timeout: options.timeout ?? timeout,
|
|
1539
|
-
|
|
1562
|
+
// Public findMany, so the sentinel form. See loadRelation above.
|
|
1563
|
+
includePii: includePii ? UNSAFE : undefined,
|
|
1540
1564
|
}));
|
|
1541
1565
|
for (const t of targets)
|
|
1542
1566
|
targetByPk.set(String(t[targetPkField]), t);
|
|
@@ -2293,7 +2317,7 @@ export class PowqlInterface {
|
|
|
2293
2317
|
const params = [];
|
|
2294
2318
|
const resolvedWhere = await this.resolveRelationFilters(args.where, args.timeout);
|
|
2295
2319
|
const where = this.buildWhere(resolvedWhere, params);
|
|
2296
|
-
this.assertCompiledWhere(where, args.allowFullTableScan, 'updateMany');
|
|
2320
|
+
this.assertCompiledWhere(where, resolveUnsafeFlag(args.allowFullTableScan, 'allowFullTableScan'), 'updateMany');
|
|
2297
2321
|
const setClause = this.buildUpdateAssignments(args.data, params);
|
|
2298
2322
|
const filter = where ? ` filter ${where}` : '';
|
|
2299
2323
|
const { rowCount } = await this.exec(`${this.qt}${filter} update { ${setClause} }`, params, args.timeout, 'updateMany');
|
|
@@ -2443,7 +2467,7 @@ export class PowqlInterface {
|
|
|
2443
2467
|
const params = [];
|
|
2444
2468
|
const resolvedWhere = await this.resolveRelationFilters(args.where, args.timeout);
|
|
2445
2469
|
const where = this.buildWhere(resolvedWhere, params);
|
|
2446
|
-
this.assertCompiledWhere(where, args.allowFullTableScan, 'deleteMany');
|
|
2470
|
+
this.assertCompiledWhere(where, resolveUnsafeFlag(args.allowFullTableScan, 'allowFullTableScan'), 'deleteMany');
|
|
2447
2471
|
const filter = where ? ` filter ${where}` : '';
|
|
2448
2472
|
const { rowCount } = await this.exec(`${this.qt}${filter} delete`, params, args.timeout, 'deleteMany');
|
|
2449
2473
|
return { count: rowCount };
|
|
@@ -2582,7 +2606,7 @@ export class PowqlInterface {
|
|
|
2582
2606
|
const powfn = fn.slice(1); // sum/avg/min/max
|
|
2583
2607
|
// Same PII contract as the SQL engines: _min/_max return a stored cell.
|
|
2584
2608
|
if (fn === '_min' || fn === '_max') {
|
|
2585
|
-
assertAggregatePiiOptIn(this.table, this.meta, field, this.column(field).name, `aggregate ${fn}`, args.includePii);
|
|
2609
|
+
assertAggregatePiiOptIn(this.table, this.meta, field, this.column(field).name, `aggregate ${fn}`, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
2586
2610
|
}
|
|
2587
2611
|
acc[field] = await scalar(`${powfn}(${this.qt}${filter} { ${this.ref(field)} })`);
|
|
2588
2612
|
}
|
|
@@ -2636,7 +2660,7 @@ export class PowqlInterface {
|
|
|
2636
2660
|
for (const entry of args.by) {
|
|
2637
2661
|
if (typeof entry === 'string') {
|
|
2638
2662
|
const col = this.column(entry);
|
|
2639
|
-
assertAggregatePiiOptIn(this.table, this.meta, entry, col.name, 'groupBy `by` key', args.includePii);
|
|
2663
|
+
assertAggregatePiiOptIn(this.table, this.meta, entry, col.name, 'groupBy `by` key', resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
2640
2664
|
claim(entry, `column "${col.name}"`);
|
|
2641
2665
|
if (col.name !== entry)
|
|
2642
2666
|
claim(col.name, `column "${col.name}"`);
|
|
@@ -2650,7 +2674,7 @@ export class PowqlInterface {
|
|
|
2650
2674
|
if (!isJsonColumn(col)) {
|
|
2651
2675
|
throw new ValidationError(`[turbine] groupBy JSON group key on "${entry.field}" (table "${this.table}") requires a json column.`);
|
|
2652
2676
|
}
|
|
2653
|
-
assertAggregatePiiOptIn(this.table, this.meta, entry.field, col.name, 'groupBy JSON `by` key', args.includePii);
|
|
2677
|
+
assertAggregatePiiOptIn(this.table, this.meta, entry.field, col.name, 'groupBy JSON `by` key', resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
2654
2678
|
this.assertJsonPath('group key', entry.field, entry.path);
|
|
2655
2679
|
const pathExpr = this.jsonPathExpr(col, entry.path, params);
|
|
2656
2680
|
const alias = entry.alias ?? String(entry.path[entry.path.length - 1]);
|
|
@@ -2701,7 +2725,7 @@ export class PowqlInterface {
|
|
|
2701
2725
|
if (target === true) {
|
|
2702
2726
|
const col = this.column(key);
|
|
2703
2727
|
if (fn === '_min' || fn === '_max') {
|
|
2704
|
-
assertAggregatePiiOptIn(this.table, this.meta, key, col.name, `groupBy ${fn}`, args.includePii);
|
|
2728
|
+
assertAggregatePiiOptIn(this.table, this.meta, key, col.name, `groupBy ${fn}`, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
2705
2729
|
}
|
|
2706
2730
|
claim(`${fn}_${col.name}`, `${fn} of column "${col.name}"`);
|
|
2707
2731
|
const inner = `.${col.name}`;
|
|
@@ -2716,7 +2740,7 @@ export class PowqlInterface {
|
|
|
2716
2740
|
throw new ValidationError(`[turbine] groupBy ${fn} target "${key}" on "${target.field}" (table "${this.table}") requires a json column.`);
|
|
2717
2741
|
}
|
|
2718
2742
|
if (fn === '_min' || fn === '_max') {
|
|
2719
|
-
assertAggregatePiiOptIn(this.table, this.meta, target.field, col.name, `groupBy ${fn} JSON target`, args.includePii);
|
|
2743
|
+
assertAggregatePiiOptIn(this.table, this.meta, target.field, col.name, `groupBy ${fn} JSON target`, resolveUnsafeFlag(args.includePii, 'includePii'));
|
|
2720
2744
|
}
|
|
2721
2745
|
this.assertJsonPath(`${fn} target "${key}"`, target.field, target.path);
|
|
2722
2746
|
const alwaysNumeric = fn === '_sum' || fn === '_avg';
|
|
@@ -2916,9 +2940,9 @@ export class PowqlInterface {
|
|
|
2916
2940
|
if (spec.nulls === 'first') {
|
|
2917
2941
|
throw new UnsupportedFeatureError('NULLS FIRST placement', 'PowDB', `groupBy orderBy "${keyForMsg}": PowDB orders NULLs / missing keys LAST in both directions`);
|
|
2918
2942
|
}
|
|
2919
|
-
return spec.sort
|
|
2943
|
+
return this.dirKeyword(spec.sort, `groupBy orderBy "${keyForMsg}"`);
|
|
2920
2944
|
}
|
|
2921
|
-
return value
|
|
2945
|
+
return this.dirKeyword(value, `groupBy orderBy "${keyForMsg}"`);
|
|
2922
2946
|
}
|
|
2923
2947
|
// -------------------------------------------------------------------------
|
|
2924
2948
|
// Streaming / unsupported
|
|
@@ -2955,7 +2979,8 @@ export class PowqlInterface {
|
|
|
2955
2979
|
if (compiledWhere.length > 0)
|
|
2956
2980
|
return;
|
|
2957
2981
|
throw new ValidationError(`[turbine] ${action} on "${this.table}" refused: the \`where\` clause is empty. ` +
|
|
2958
|
-
|
|
2982
|
+
"Pass `allowFullTableScan: UNSAFE` to opt in (import { UNSAFE } from 'turbine-orm'), " +
|
|
2983
|
+
'or check that your filter values are defined.');
|
|
2959
2984
|
}
|
|
2960
2985
|
}
|
|
2961
2986
|
/** Coerce a group-key scalar string by the column's TS type (numbers/bools). */
|
package/dist/prisma-compat.d.ts
CHANGED
|
@@ -40,6 +40,11 @@
|
|
|
40
40
|
* by this layer, and a key that is neither a Prisma arg nor a turbine option
|
|
41
41
|
* gets a dev-mode warning instead of vanishing (see
|
|
42
42
|
* {@link PRISMA_ARG_KEYS} and `warnUnknownQueryOptions`).
|
|
43
|
+
* The three PRIVILEGE options among them (`skipGlobalFilters`, `includePii`,
|
|
44
|
+
* `allowFullTableScan`) are forwarded VERBATIM, which is what makes them safe
|
|
45
|
+
* here: core accepts only the `UNSAFE` sentinel, so a Prisma-shaped args
|
|
46
|
+
* object carrying `includePii: true` reaches core and is refused there, and
|
|
47
|
+
* this layer never needs its own copy of that rule.
|
|
43
48
|
*
|
|
44
49
|
* ## What it deliberately does NOT do (documented divergences)
|
|
45
50
|
*
|
|
@@ -75,11 +80,16 @@
|
|
|
75
80
|
* - **`limit` on `updateMany` / `deleteMany`** (Prisma 6.7+) throws. Turbine has
|
|
76
81
|
* no row-bounded mass mutation, and dropping a SAFETY BOUND with a warning
|
|
77
82
|
* would turn "change at most 10 rows" into "change every matching row".
|
|
78
|
-
* - **Write projections
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
+
* - **Write projections**: `select` / `omit` on create/update/delete/upsert
|
|
84
|
+
* narrow the RETURNED OBJECT (see {@link resolveWriteProjection}); they do
|
|
85
|
+
* NOT narrow the statement's `RETURNING` list, so the column still crosses
|
|
86
|
+
* the wire, and `pii: true` remains the SQL-level control. A relation key in
|
|
87
|
+
* either (or any `include` on a write) THROWS, since a write returns its own
|
|
88
|
+
* row only. `omit` on READS is translated to core's own `omit`, see
|
|
89
|
+
* {@link translateOmit}.
|
|
90
|
+
* - **`select` on `count`** and **`orderBy` / `cursor` / `take` / `skip` on
|
|
91
|
+
* `aggregate`** are accepted and IGNORED (they are legitimate Prisma, so they
|
|
92
|
+
* never warn); a plain number / the aggregate comes back.
|
|
83
93
|
*
|
|
84
94
|
* ## Type dependencies (0.41.0)
|
|
85
95
|
*
|