prisma-guard 1.28.0 → 1.29.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 +75 -1
- package/dist/generator/index.js +50 -40
- package/dist/generator/index.js.map +1 -1
- package/dist/runtime/index.cjs +265 -183
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +19 -9
- package/dist/runtime/index.d.ts +19 -9
- package/dist/runtime/index.js +265 -183
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -212,7 +212,7 @@ function createScalarBase(strictDecimal) {
|
|
|
212
212
|
return {
|
|
213
213
|
String: () => z.string(),
|
|
214
214
|
Int: () => z.number().int(),
|
|
215
|
-
Float: () => z.number(),
|
|
215
|
+
Float: () => z.number().finite(),
|
|
216
216
|
Decimal: createDecimalFactory(strictDecimal),
|
|
217
217
|
BigInt: () => z.union([
|
|
218
218
|
z.bigint(),
|
|
@@ -353,6 +353,19 @@ function requireConfigTrue(config, context) {
|
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
|
+
function requirePlainObjectConfig(value, message) {
|
|
357
|
+
if (!isPlainObject(value)) {
|
|
358
|
+
throw new ShapeError(message);
|
|
359
|
+
}
|
|
360
|
+
return value;
|
|
361
|
+
}
|
|
362
|
+
function assertAllowedKeys(value, allowed, makeError) {
|
|
363
|
+
for (const key of Object.keys(value)) {
|
|
364
|
+
if (!allowed.has(key)) {
|
|
365
|
+
throw new ShapeError(makeError(key));
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
356
369
|
|
|
357
370
|
// src/runtime/zod-type-map.ts
|
|
358
371
|
var SCALAR_OPERATORS = {
|
|
@@ -416,24 +429,12 @@ var JSON_ARRAY_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
416
429
|
"array_starts_with",
|
|
417
430
|
"array_ends_with"
|
|
418
431
|
]);
|
|
419
|
-
function getSupportedOperators(
|
|
420
|
-
|
|
421
|
-
let list;
|
|
422
|
-
let enumField;
|
|
423
|
-
if (typeof input === "string") {
|
|
424
|
-
fieldType = input;
|
|
425
|
-
list = isList;
|
|
426
|
-
enumField = isEnum;
|
|
427
|
-
} else {
|
|
428
|
-
fieldType = input.type;
|
|
429
|
-
list = input.isList;
|
|
430
|
-
enumField = input.isEnum === true;
|
|
431
|
-
}
|
|
432
|
-
if (list)
|
|
432
|
+
function getSupportedOperators(fieldMeta) {
|
|
433
|
+
if (fieldMeta.isList)
|
|
433
434
|
return [...SCALAR_LIST_OPERATORS];
|
|
434
|
-
if (
|
|
435
|
+
if (fieldMeta.isEnum === true)
|
|
435
436
|
return [...ENUM_OPERATORS];
|
|
436
|
-
const ops = SCALAR_OPERATORS[
|
|
437
|
+
const ops = SCALAR_OPERATORS[fieldMeta.type];
|
|
437
438
|
if (!ops)
|
|
438
439
|
return [];
|
|
439
440
|
return [...ops];
|
|
@@ -998,6 +999,7 @@ function validateContext(ctx) {
|
|
|
998
999
|
|
|
999
1000
|
// src/runtime/query-builder-where.ts
|
|
1000
1001
|
import { z as z5 } from "zod";
|
|
1002
|
+
import { inspect } from "util";
|
|
1001
1003
|
|
|
1002
1004
|
// src/shared/deep-clone.ts
|
|
1003
1005
|
function deepClone(value) {
|
|
@@ -1278,15 +1280,10 @@ function applyBuiltShape(built, body, isUniqueMethod, modelName) {
|
|
|
1278
1280
|
try {
|
|
1279
1281
|
validated = built.zodSchema.parse(parseable);
|
|
1280
1282
|
} catch (err) {
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
throw new ShapeError(`${context}: ${formatZodError(err)}`, {
|
|
1286
|
-
cause: err
|
|
1287
|
-
});
|
|
1288
|
-
}
|
|
1289
|
-
throw err;
|
|
1283
|
+
wrapParseError(
|
|
1284
|
+
err,
|
|
1285
|
+
modelName ? `Invalid query on model "${modelName}"` : "Invalid query"
|
|
1286
|
+
);
|
|
1290
1287
|
}
|
|
1291
1288
|
if (hasWhereForced(built.forcedWhere)) {
|
|
1292
1289
|
validated.where = isUniqueMethod ? mergeUniqueWhereForced(
|
|
@@ -1603,37 +1600,8 @@ var JSON_STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
|
1603
1600
|
]);
|
|
1604
1601
|
var NEGATIVE_RELATION_OPS = /* @__PURE__ */ new Set(["none", "isNot"]);
|
|
1605
1602
|
var MAX_WHERE_DEPTH = 10;
|
|
1606
|
-
function
|
|
1607
|
-
|
|
1608
|
-
return `${value}n`;
|
|
1609
|
-
if (typeof value === "undefined")
|
|
1610
|
-
return "undefined";
|
|
1611
|
-
if (typeof value === "function")
|
|
1612
|
-
return "[function]";
|
|
1613
|
-
if (typeof value === "symbol")
|
|
1614
|
-
return value.toString();
|
|
1615
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
1616
|
-
try {
|
|
1617
|
-
const json = JSON.stringify(value, (_key, current) => {
|
|
1618
|
-
if (typeof current === "bigint")
|
|
1619
|
-
return `${current}n`;
|
|
1620
|
-
if (typeof current === "undefined")
|
|
1621
|
-
return "[undefined]";
|
|
1622
|
-
if (typeof current === "function")
|
|
1623
|
-
return "[function]";
|
|
1624
|
-
if (typeof current === "symbol")
|
|
1625
|
-
return current.toString();
|
|
1626
|
-
if (current && typeof current === "object") {
|
|
1627
|
-
if (seen.has(current))
|
|
1628
|
-
return "[Circular]";
|
|
1629
|
-
seen.add(current);
|
|
1630
|
-
}
|
|
1631
|
-
return current;
|
|
1632
|
-
});
|
|
1633
|
-
return json === void 0 ? String(value) : json;
|
|
1634
|
-
} catch {
|
|
1635
|
-
return String(value);
|
|
1636
|
-
}
|
|
1603
|
+
function formatValue(value) {
|
|
1604
|
+
return inspect(value, { depth: 3, breakLength: Infinity });
|
|
1637
1605
|
}
|
|
1638
1606
|
function mergeScalarConditions(target, source) {
|
|
1639
1607
|
for (const [field, ops] of Object.entries(source)) {
|
|
@@ -1654,7 +1622,7 @@ function mergeScalarConditions(target, source) {
|
|
|
1654
1622
|
const existingVal = existing[op];
|
|
1655
1623
|
if (!deepEqual(existingVal, val)) {
|
|
1656
1624
|
throw new ShapeError(
|
|
1657
|
-
`Conflicting forced where values for "${field}.${op}": shape defines both ${
|
|
1625
|
+
`Conflicting forced where values for "${field}.${op}": shape defines both ${formatValue(existingVal)} and ${formatValue(val)}`
|
|
1658
1626
|
);
|
|
1659
1627
|
}
|
|
1660
1628
|
}
|
|
@@ -2492,10 +2460,7 @@ function createArgsBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2492
2460
|
`${fieldMeta.type} field "${fieldName}" cannot be used in having`
|
|
2493
2461
|
);
|
|
2494
2462
|
}
|
|
2495
|
-
const allowedOps = getSupportedOperators(
|
|
2496
|
-
fieldMeta.type,
|
|
2497
|
-
fieldMeta.isList
|
|
2498
|
-
);
|
|
2463
|
+
const allowedOps = getSupportedOperators(fieldMeta);
|
|
2499
2464
|
const opSchemas = {};
|
|
2500
2465
|
for (const op of allowedOps) {
|
|
2501
2466
|
opSchemas[op] = createOperatorSchema(
|
|
@@ -2672,20 +2637,27 @@ function buildDefaultProjectionBody(shape) {
|
|
|
2672
2637
|
|
|
2673
2638
|
// src/runtime/query-builder-projection.ts
|
|
2674
2639
|
var KNOWN_NESTED_KEYS = {
|
|
2675
|
-
include: /* @__PURE__ */ new Set([
|
|
2676
|
-
|
|
2640
|
+
include: /* @__PURE__ */ new Set([
|
|
2641
|
+
"where",
|
|
2642
|
+
"include",
|
|
2643
|
+
"select",
|
|
2644
|
+
"orderBy",
|
|
2645
|
+
"cursor",
|
|
2646
|
+
"take",
|
|
2647
|
+
"skip"
|
|
2648
|
+
]),
|
|
2649
|
+
select: /* @__PURE__ */ new Set([
|
|
2650
|
+
"select",
|
|
2651
|
+
"include",
|
|
2652
|
+
"where",
|
|
2653
|
+
"orderBy",
|
|
2654
|
+
"cursor",
|
|
2655
|
+
"take",
|
|
2656
|
+
"skip"
|
|
2657
|
+
])
|
|
2677
2658
|
};
|
|
2678
2659
|
var KNOWN_COUNT_SELECT_ENTRY_KEYS = /* @__PURE__ */ new Set(["where"]);
|
|
2679
2660
|
var MAX_PROJECTION_DEPTH = 10;
|
|
2680
|
-
function validateNestedKeys(keys, allowed, context) {
|
|
2681
|
-
for (const key of keys) {
|
|
2682
|
-
if (!allowed.has(key)) {
|
|
2683
|
-
throw new ShapeError(
|
|
2684
|
-
`Unknown key "${key}" in ${context}. Allowed: ${[...allowed].join(", ")}`
|
|
2685
|
-
);
|
|
2686
|
-
}
|
|
2687
|
-
}
|
|
2688
|
-
}
|
|
2689
2661
|
function hasDefinedKeys(v) {
|
|
2690
2662
|
return Object.values(v).some((value) => value !== void 0);
|
|
2691
2663
|
}
|
|
@@ -2698,6 +2670,20 @@ function wrapRelationSchema(nestedObj, skeleton) {
|
|
|
2698
2670
|
collapsed
|
|
2699
2671
|
);
|
|
2700
2672
|
}
|
|
2673
|
+
function buildRelationWhere(relatedType, whereConfig, context, buildWhereSchema) {
|
|
2674
|
+
if (Object.keys(whereConfig).length === 0) {
|
|
2675
|
+
throw new ShapeError(
|
|
2676
|
+
`Empty "where" in ${context}. Define at least one field.`
|
|
2677
|
+
);
|
|
2678
|
+
}
|
|
2679
|
+
const { schema, forced } = buildWhereSchema(relatedType, whereConfig);
|
|
2680
|
+
if (!schema && !hasWhereForced(forced)) {
|
|
2681
|
+
throw new ShapeError(
|
|
2682
|
+
`"where" in ${context} produced no schema and no forced conditions. Define at least one field.`
|
|
2683
|
+
);
|
|
2684
|
+
}
|
|
2685
|
+
return { schema, forced };
|
|
2686
|
+
}
|
|
2701
2687
|
function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
2702
2688
|
function buildIncludeCountSchema(model, config) {
|
|
2703
2689
|
const modelFields = typeMap[model];
|
|
@@ -2711,13 +2697,11 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2711
2697
|
`Invalid _count config on model "${model}". Expected true or { select: { ... } }`
|
|
2712
2698
|
);
|
|
2713
2699
|
}
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2700
|
+
assertAllowedKeys(
|
|
2701
|
+
config,
|
|
2702
|
+
/* @__PURE__ */ new Set(["select"]),
|
|
2703
|
+
(key) => `Unknown key "${key}" in _count config on model "${model}". Only "select" is allowed.`
|
|
2704
|
+
);
|
|
2721
2705
|
if (!isPlainObject(config.select)) {
|
|
2722
2706
|
throw new ShapeError(
|
|
2723
2707
|
`Invalid _count.select on model "${model}". Expected a plain object with relation field keys.`
|
|
@@ -2734,11 +2718,17 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2734
2718
|
for (const [fieldName, fieldConfig] of Object.entries(selectObj)) {
|
|
2735
2719
|
const fieldMeta = modelFields[fieldName];
|
|
2736
2720
|
if (!fieldMeta)
|
|
2737
|
-
throw new ShapeError(
|
|
2721
|
+
throw new ShapeError(
|
|
2722
|
+
`Unknown field "${fieldName}" on model "${model}" in _count.select`
|
|
2723
|
+
);
|
|
2738
2724
|
if (!fieldMeta.isRelation)
|
|
2739
|
-
throw new ShapeError(
|
|
2725
|
+
throw new ShapeError(
|
|
2726
|
+
`Field "${fieldName}" is not a relation on model "${model}" in _count.select`
|
|
2727
|
+
);
|
|
2740
2728
|
if (!fieldMeta.isList)
|
|
2741
|
-
throw new ShapeError(
|
|
2729
|
+
throw new ShapeError(
|
|
2730
|
+
`Field "${fieldName}" is a to-one relation on model "${model}" in _count.select. Only to-many relations support _count.`
|
|
2731
|
+
);
|
|
2742
2732
|
if (fieldConfig === true) {
|
|
2743
2733
|
countSelectFields[fieldName] = z7.literal(true).optional();
|
|
2744
2734
|
continue;
|
|
@@ -2753,16 +2743,18 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2753
2743
|
`Empty config for _count.select.${fieldName} on model "${model}". Use true or { where: { ... } }.`
|
|
2754
2744
|
);
|
|
2755
2745
|
}
|
|
2756
|
-
|
|
2757
|
-
|
|
2746
|
+
assertAllowedKeys(
|
|
2747
|
+
fieldConfig,
|
|
2758
2748
|
KNOWN_COUNT_SELECT_ENTRY_KEYS,
|
|
2759
|
-
`_count.select.${fieldName} on model "${model}"`
|
|
2749
|
+
(key) => `Unknown key "${key}" in _count.select.${fieldName} on model "${model}". Allowed: ${[...KNOWN_COUNT_SELECT_ENTRY_KEYS].join(", ")}`
|
|
2760
2750
|
);
|
|
2761
2751
|
if (fieldConfig.where) {
|
|
2762
2752
|
const relatedType = fieldMeta.type;
|
|
2763
|
-
const { schema: whereSchema, forced } =
|
|
2753
|
+
const { schema: whereSchema, forced } = buildRelationWhere(
|
|
2764
2754
|
relatedType,
|
|
2765
|
-
fieldConfig.where
|
|
2755
|
+
fieldConfig.where,
|
|
2756
|
+
`_count.select.${fieldName} on model "${model}"`,
|
|
2757
|
+
deps.buildWhereSchema
|
|
2766
2758
|
);
|
|
2767
2759
|
const nestedSchemas = {};
|
|
2768
2760
|
if (whereSchema)
|
|
@@ -2785,13 +2777,15 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2785
2777
|
forcedCountWhere
|
|
2786
2778
|
};
|
|
2787
2779
|
}
|
|
2788
|
-
function buildNestedRelSchemas(relatedType, config, depth) {
|
|
2780
|
+
function buildNestedRelSchemas(relatedType, config, depth, context) {
|
|
2789
2781
|
const nestedSchemas = {};
|
|
2790
2782
|
const relForced = {};
|
|
2791
2783
|
if (config.where) {
|
|
2792
|
-
const { schema: whereSchema, forced } =
|
|
2784
|
+
const { schema: whereSchema, forced } = buildRelationWhere(
|
|
2793
2785
|
relatedType,
|
|
2794
|
-
config.where
|
|
2786
|
+
config.where,
|
|
2787
|
+
context,
|
|
2788
|
+
deps.buildWhereSchema
|
|
2795
2789
|
);
|
|
2796
2790
|
if (whereSchema)
|
|
2797
2791
|
nestedSchemas["where"] = whereSchema;
|
|
@@ -2799,7 +2793,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2799
2793
|
relForced.where = forced;
|
|
2800
2794
|
}
|
|
2801
2795
|
if (config.include) {
|
|
2802
|
-
const nested = buildProjectionSchema(
|
|
2796
|
+
const nested = buildProjectionSchema(
|
|
2797
|
+
"include",
|
|
2798
|
+
relatedType,
|
|
2799
|
+
config.include,
|
|
2800
|
+
depth + 1
|
|
2801
|
+
);
|
|
2803
2802
|
nestedSchemas["include"] = nested.schema;
|
|
2804
2803
|
if (Object.keys(nested.forcedTree).length > 0)
|
|
2805
2804
|
relForced.include = nested.forcedTree;
|
|
@@ -2809,7 +2808,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2809
2808
|
}
|
|
2810
2809
|
}
|
|
2811
2810
|
if (config.select) {
|
|
2812
|
-
const nested = buildProjectionSchema(
|
|
2811
|
+
const nested = buildProjectionSchema(
|
|
2812
|
+
"select",
|
|
2813
|
+
relatedType,
|
|
2814
|
+
config.select,
|
|
2815
|
+
depth + 1
|
|
2816
|
+
);
|
|
2813
2817
|
nestedSchemas["select"] = nested.schema;
|
|
2814
2818
|
if (Object.keys(nested.forcedTree).length > 0)
|
|
2815
2819
|
relForced.select = nested.forcedTree;
|
|
@@ -2819,15 +2823,26 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2819
2823
|
}
|
|
2820
2824
|
}
|
|
2821
2825
|
if (config.orderBy) {
|
|
2822
|
-
nestedSchemas["orderBy"] = deps.buildOrderBySchema(
|
|
2826
|
+
nestedSchemas["orderBy"] = deps.buildOrderBySchema(
|
|
2827
|
+
relatedType,
|
|
2828
|
+
config.orderBy
|
|
2829
|
+
);
|
|
2823
2830
|
}
|
|
2824
2831
|
if (config.cursor) {
|
|
2825
|
-
nestedSchemas["cursor"] = deps.buildCursorSchema(
|
|
2832
|
+
nestedSchemas["cursor"] = deps.buildCursorSchema(
|
|
2833
|
+
relatedType,
|
|
2834
|
+
config.cursor
|
|
2835
|
+
);
|
|
2826
2836
|
}
|
|
2827
|
-
if (config.take) {
|
|
2837
|
+
if ("take" in config && config.take !== void 0) {
|
|
2828
2838
|
nestedSchemas["take"] = deps.buildTakeSchema(config.take);
|
|
2829
2839
|
}
|
|
2830
|
-
if (config.skip) {
|
|
2840
|
+
if ("skip" in config && config.skip !== void 0) {
|
|
2841
|
+
if (config.skip !== true) {
|
|
2842
|
+
throw new ShapeError(
|
|
2843
|
+
`Nested "skip" in ${context} must be true`
|
|
2844
|
+
);
|
|
2845
|
+
}
|
|
2831
2846
|
nestedSchemas["skip"] = z7.number().int().min(0).optional();
|
|
2832
2847
|
}
|
|
2833
2848
|
return { nestedSchemas, relForced };
|
|
@@ -2853,28 +2868,43 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2853
2868
|
let topLevelForcedCountWhere = {};
|
|
2854
2869
|
for (const [fieldName, config] of Object.entries(projectionConfig)) {
|
|
2855
2870
|
if (fieldName === "_count") {
|
|
2856
|
-
const countResult = buildIncludeCountSchema(
|
|
2871
|
+
const countResult = buildIncludeCountSchema(
|
|
2872
|
+
model,
|
|
2873
|
+
config
|
|
2874
|
+
);
|
|
2857
2875
|
fieldSchemas["_count"] = countResult.schema;
|
|
2858
2876
|
topLevelForcedCountWhere = countResult.forcedCountWhere;
|
|
2859
2877
|
continue;
|
|
2860
2878
|
}
|
|
2861
2879
|
const fieldMeta = modelFields[fieldName];
|
|
2862
2880
|
if (!fieldMeta)
|
|
2863
|
-
throw new ShapeError(
|
|
2881
|
+
throw new ShapeError(
|
|
2882
|
+
`Unknown field "${fieldName}" on model "${model}"`
|
|
2883
|
+
);
|
|
2864
2884
|
if (mode === "include" && !fieldMeta.isRelation) {
|
|
2865
|
-
throw new ShapeError(
|
|
2885
|
+
throw new ShapeError(
|
|
2886
|
+
`Field "${fieldName}" is not a relation on model "${model}"`
|
|
2887
|
+
);
|
|
2866
2888
|
}
|
|
2867
2889
|
if (config === true) {
|
|
2868
2890
|
fieldSchemas[fieldName] = z7.literal(true).optional();
|
|
2869
2891
|
continue;
|
|
2870
2892
|
}
|
|
2871
2893
|
if (mode === "select" && !fieldMeta.isRelation) {
|
|
2872
|
-
throw new ShapeError(
|
|
2894
|
+
throw new ShapeError(
|
|
2895
|
+
`Nested select args only valid for relations, not scalar "${fieldName}" on model "${model}"`
|
|
2896
|
+
);
|
|
2873
2897
|
}
|
|
2874
2898
|
const contextLabel = `nested ${mode} for "${fieldName}" on model "${model}"`;
|
|
2875
|
-
|
|
2899
|
+
assertAllowedKeys(
|
|
2900
|
+
config,
|
|
2901
|
+
allowedNestedKeys,
|
|
2902
|
+
(key) => `Unknown key "${key}" in ${contextLabel}. Allowed: ${[...allowedNestedKeys].join(", ")}`
|
|
2903
|
+
);
|
|
2876
2904
|
if (config.select && config.include) {
|
|
2877
|
-
throw new ShapeError(
|
|
2905
|
+
throw new ShapeError(
|
|
2906
|
+
`Nested ${mode} for "${fieldName}" cannot define both "select" and "include".`
|
|
2907
|
+
);
|
|
2878
2908
|
}
|
|
2879
2909
|
if (!fieldMeta.isList) {
|
|
2880
2910
|
if (config.where || config.orderBy || config.cursor || config.take || config.skip) {
|
|
@@ -2883,7 +2913,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2883
2913
|
);
|
|
2884
2914
|
}
|
|
2885
2915
|
}
|
|
2886
|
-
const { nestedSchemas, relForced } = buildNestedRelSchemas(
|
|
2916
|
+
const { nestedSchemas, relForced } = buildNestedRelSchemas(
|
|
2917
|
+
fieldMeta.type,
|
|
2918
|
+
config,
|
|
2919
|
+
currentDepth,
|
|
2920
|
+
contextLabel
|
|
2921
|
+
);
|
|
2887
2922
|
const nestedObj = z7.object(nestedSchemas).strict();
|
|
2888
2923
|
fieldSchemas[fieldName] = wrapRelationSchema(
|
|
2889
2924
|
nestedObj,
|
|
@@ -2908,27 +2943,33 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2908
2943
|
function buildSelectSchema(model, selectConfig, depth) {
|
|
2909
2944
|
return buildProjectionSchema("select", model, selectConfig, depth);
|
|
2910
2945
|
}
|
|
2911
|
-
return {
|
|
2946
|
+
return {
|
|
2947
|
+
buildIncludeSchema,
|
|
2948
|
+
buildSelectSchema,
|
|
2949
|
+
buildIncludeCountSchema,
|
|
2950
|
+
buildProjectionSchema
|
|
2951
|
+
};
|
|
2912
2952
|
}
|
|
2913
2953
|
|
|
2914
2954
|
// src/shared/operation-shape-keys.ts
|
|
2915
2955
|
var OPERATION_SHAPE_KEYS = {
|
|
2916
2956
|
findMany: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2957
|
+
findManyPaginated: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2917
2958
|
findFirst: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2918
2959
|
findFirstOrThrow: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2919
2960
|
findUnique: ["where", "include", "select"],
|
|
2920
2961
|
findUniqueOrThrow: ["where", "include", "select"],
|
|
2921
2962
|
count: ["where", "select", "cursor", "orderBy", "skip", "take"],
|
|
2922
2963
|
aggregate: ["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
|
|
2923
|
-
groupBy: ["where", "
|
|
2924
|
-
create: ["data", "
|
|
2925
|
-
createMany: ["data"],
|
|
2926
|
-
createManyAndReturn: ["data", "select", "include"],
|
|
2927
|
-
update: ["
|
|
2928
|
-
updateMany: ["
|
|
2929
|
-
updateManyAndReturn: ["
|
|
2930
|
-
upsert: ["where", "create", "update", "
|
|
2931
|
-
delete: ["where", "
|
|
2964
|
+
groupBy: ["where", "orderBy", "by", "having", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
|
|
2965
|
+
create: ["data", "include", "select"],
|
|
2966
|
+
createMany: ["data", "skipDuplicates"],
|
|
2967
|
+
createManyAndReturn: ["data", "select", "include", "skipDuplicates"],
|
|
2968
|
+
update: ["where", "data", "include", "select"],
|
|
2969
|
+
updateMany: ["where", "data"],
|
|
2970
|
+
updateManyAndReturn: ["where", "data", "select", "include"],
|
|
2971
|
+
upsert: ["where", "create", "update", "include", "select"],
|
|
2972
|
+
delete: ["where", "include", "select"],
|
|
2932
2973
|
deleteMany: ["where"]
|
|
2933
2974
|
};
|
|
2934
2975
|
var READ_METHOD_ALLOWED_ARGS = {
|
|
@@ -3240,7 +3281,17 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
3240
3281
|
let forcedIncludeCountWhere = {};
|
|
3241
3282
|
let forcedSelectCountWhere = {};
|
|
3242
3283
|
if (shape.where) {
|
|
3284
|
+
if (Object.keys(shape.where).length === 0) {
|
|
3285
|
+
throw new ShapeError(
|
|
3286
|
+
`Empty "where" in shape for model "${model}" method "${method}". Define at least one field.`
|
|
3287
|
+
);
|
|
3288
|
+
}
|
|
3243
3289
|
const builtWhere = UNIQUE_WHERE_METHODS.has(method) ? whereBuilder.buildUniqueWhereSchema(model, shape.where) : whereBuilder.buildWhereSchema(model, shape.where);
|
|
3290
|
+
if (!builtWhere.schema && !hasWhereForced(builtWhere.forced)) {
|
|
3291
|
+
throw new ShapeError(
|
|
3292
|
+
`"where" in shape for model "${model}" method "${method}" produced no schema and no forced conditions.`
|
|
3293
|
+
);
|
|
3294
|
+
}
|
|
3244
3295
|
if (builtWhere.schema) {
|
|
3245
3296
|
schemaFields.where = builtWhere.schema;
|
|
3246
3297
|
}
|
|
@@ -4042,27 +4093,19 @@ function validateRelationOpKeys(actual, opKey, model, field, opLabel) {
|
|
|
4042
4093
|
const allowed = RELATION_OP_ALLOWED_KEYS[opKey];
|
|
4043
4094
|
if (!allowed)
|
|
4044
4095
|
return;
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
}
|
|
4051
|
-
}
|
|
4096
|
+
assertAllowedKeys(
|
|
4097
|
+
actual,
|
|
4098
|
+
allowed,
|
|
4099
|
+
(key) => `Unknown key "${key}" in ${opLabel} config on "${model}.${field}". Allowed: ${[...allowed].join(", ")}`
|
|
4100
|
+
);
|
|
4052
4101
|
}
|
|
4053
4102
|
function validateAllowedKeys(value, allowed, method, kind) {
|
|
4054
|
-
|
|
4055
|
-
if (
|
|
4056
|
-
|
|
4057
|
-
throw new ShapeError(
|
|
4058
|
-
`Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`
|
|
4059
|
-
);
|
|
4060
|
-
}
|
|
4061
|
-
throw new ShapeError(
|
|
4062
|
-
`Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`
|
|
4063
|
-
);
|
|
4103
|
+
assertAllowedKeys(value, allowed, (key) => {
|
|
4104
|
+
if (kind === "body") {
|
|
4105
|
+
return `Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`;
|
|
4064
4106
|
}
|
|
4065
|
-
|
|
4107
|
+
return `Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`;
|
|
4108
|
+
});
|
|
4066
4109
|
}
|
|
4067
4110
|
function validateCreateCompleteness(modelName, dataConfig, typeMap, scopeFks, zodDefaults) {
|
|
4068
4111
|
const modelFields = typeMap[modelName];
|
|
@@ -4149,18 +4192,10 @@ function buildNestedDataSchema(model, config, mode, typeMap, schemaBuilder) {
|
|
|
4149
4192
|
}
|
|
4150
4193
|
return z10.object(fieldSchemas).strict();
|
|
4151
4194
|
}
|
|
4152
|
-
function requirePlainObjectConfig(value, message) {
|
|
4153
|
-
if (!isPlainObject(value))
|
|
4154
|
-
throw new ShapeError(message);
|
|
4155
|
-
return value;
|
|
4156
|
-
}
|
|
4157
4195
|
function requireNestedObject(cfg, key, message) {
|
|
4158
|
-
|
|
4159
|
-
if (!v || !isPlainObject(v))
|
|
4160
|
-
throw new ShapeError(message);
|
|
4161
|
-
return v;
|
|
4196
|
+
return requirePlainObjectConfig(cfg[key], message);
|
|
4162
4197
|
}
|
|
4163
|
-
function
|
|
4198
|
+
function buildRelatedUniqueSelector(ctx, cfg, context) {
|
|
4164
4199
|
return buildUniqueSelectorSchema(
|
|
4165
4200
|
ctx.model,
|
|
4166
4201
|
ctx.fieldName,
|
|
@@ -4173,7 +4208,7 @@ function buildUniqueSelector(ctx, cfg, context) {
|
|
|
4173
4208
|
context
|
|
4174
4209
|
);
|
|
4175
4210
|
}
|
|
4176
|
-
function
|
|
4211
|
+
function buildRelatedNestedData(ctx, cfg, mode) {
|
|
4177
4212
|
return buildNestedDataSchema(
|
|
4178
4213
|
ctx.relatedModelName,
|
|
4179
4214
|
cfg,
|
|
@@ -4187,7 +4222,7 @@ var handleConnect = (ctx) => {
|
|
|
4187
4222
|
ctx.config,
|
|
4188
4223
|
`connect config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4189
4224
|
);
|
|
4190
|
-
const schema =
|
|
4225
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "connect");
|
|
4191
4226
|
return wrapRelationOp(ctx.isList, schema);
|
|
4192
4227
|
};
|
|
4193
4228
|
var handleConnectOrCreate = (ctx) => {
|
|
@@ -4206,8 +4241,8 @@ var handleConnectOrCreate = (ctx) => {
|
|
|
4206
4241
|
"create",
|
|
4207
4242
|
`connectOrCreate on "${ctx.model}.${ctx.fieldName}" requires "create" object`
|
|
4208
4243
|
);
|
|
4209
|
-
const whereSchema =
|
|
4210
|
-
const createSchema =
|
|
4244
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "connectOrCreate.where");
|
|
4245
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4211
4246
|
const cocSchema = z10.object({ where: whereSchema, create: createSchema }).strict();
|
|
4212
4247
|
return wrapRelationOp(ctx.isList, cocSchema);
|
|
4213
4248
|
};
|
|
@@ -4216,7 +4251,7 @@ var handleCreate = (ctx) => {
|
|
|
4216
4251
|
ctx.config,
|
|
4217
4252
|
`create config on "${ctx.model}.${ctx.fieldName}" must be an object of field names`
|
|
4218
4253
|
);
|
|
4219
|
-
const createSchema =
|
|
4254
|
+
const createSchema = buildRelatedNestedData(ctx, cfg, "create");
|
|
4220
4255
|
return wrapRelationOp(ctx.isList, createSchema);
|
|
4221
4256
|
};
|
|
4222
4257
|
var handleCreateMany = (ctx) => {
|
|
@@ -4235,7 +4270,7 @@ var handleCreateMany = (ctx) => {
|
|
|
4235
4270
|
"data",
|
|
4236
4271
|
`createMany on "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4237
4272
|
);
|
|
4238
|
-
const dataSchema =
|
|
4273
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "create");
|
|
4239
4274
|
const cmSchemaFields = {
|
|
4240
4275
|
data: z10.preprocess(coerceToArray, z10.array(dataSchema))
|
|
4241
4276
|
};
|
|
@@ -4258,7 +4293,7 @@ var handleDisconnect = (ctx) => {
|
|
|
4258
4293
|
`disconnect config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4259
4294
|
);
|
|
4260
4295
|
}
|
|
4261
|
-
const schema =
|
|
4296
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "disconnect");
|
|
4262
4297
|
if (ctx.isList)
|
|
4263
4298
|
return wrapRelationOp(true, schema);
|
|
4264
4299
|
return z10.union([z10.literal(true), schema]).optional();
|
|
@@ -4277,7 +4312,7 @@ var handleDelete = (ctx) => {
|
|
|
4277
4312
|
`delete config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4278
4313
|
);
|
|
4279
4314
|
}
|
|
4280
|
-
const schema =
|
|
4315
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "delete");
|
|
4281
4316
|
if (ctx.isList)
|
|
4282
4317
|
return wrapRelationOp(true, schema);
|
|
4283
4318
|
return z10.union([z10.literal(true), schema]).optional();
|
|
@@ -4292,7 +4327,7 @@ var handleSet = (ctx) => {
|
|
|
4292
4327
|
ctx.config,
|
|
4293
4328
|
`set config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4294
4329
|
);
|
|
4295
|
-
const schema =
|
|
4330
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "set");
|
|
4296
4331
|
return wrapRelationOp(true, schema);
|
|
4297
4332
|
};
|
|
4298
4333
|
var handleUpdate = (ctx) => {
|
|
@@ -4312,12 +4347,12 @@ var handleUpdate = (ctx) => {
|
|
|
4312
4347
|
"data",
|
|
4313
4348
|
`update on to-many "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4314
4349
|
);
|
|
4315
|
-
const whereSchema =
|
|
4316
|
-
const dataSchema2 =
|
|
4350
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "update.where");
|
|
4351
|
+
const dataSchema2 = buildRelatedNestedData(ctx, data, "update");
|
|
4317
4352
|
const updateSchema = z10.object({ where: whereSchema, data: dataSchema2 }).strict();
|
|
4318
4353
|
return wrapRelationOp(true, updateSchema);
|
|
4319
4354
|
}
|
|
4320
|
-
const dataSchema =
|
|
4355
|
+
const dataSchema = buildRelatedNestedData(ctx, cfg, "update");
|
|
4321
4356
|
return dataSchema.optional();
|
|
4322
4357
|
};
|
|
4323
4358
|
var handleUpsert = (ctx) => {
|
|
@@ -4342,15 +4377,15 @@ var handleUpsert = (ctx) => {
|
|
|
4342
4377
|
"update",
|
|
4343
4378
|
`upsert on "${ctx.model}.${ctx.fieldName}" requires "update" object`
|
|
4344
4379
|
);
|
|
4345
|
-
const createSchema =
|
|
4346
|
-
const updateSchema =
|
|
4380
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4381
|
+
const updateSchema = buildRelatedNestedData(ctx, update, "update");
|
|
4347
4382
|
if (ctx.isList) {
|
|
4348
4383
|
const where = requireNestedObject(
|
|
4349
4384
|
cfg,
|
|
4350
4385
|
"where",
|
|
4351
4386
|
`upsert on to-many "${ctx.model}.${ctx.fieldName}" requires "where" object`
|
|
4352
4387
|
);
|
|
4353
|
-
const whereSchema =
|
|
4388
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "upsert.where");
|
|
4354
4389
|
const upsertSchema2 = z10.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4355
4390
|
return wrapRelationOp(true, upsertSchema2);
|
|
4356
4391
|
}
|
|
@@ -4361,7 +4396,7 @@ var handleUpsert = (ctx) => {
|
|
|
4361
4396
|
`upsert on to-one "${ctx.model}.${ctx.fieldName}" has invalid "where": must be a plain object of unique selectors`
|
|
4362
4397
|
);
|
|
4363
4398
|
}
|
|
4364
|
-
const whereSchema =
|
|
4399
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, cfg.where, "upsert.where");
|
|
4365
4400
|
const upsertSchema2 = z10.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4366
4401
|
return upsertSchema2.optional();
|
|
4367
4402
|
}
|
|
@@ -4405,7 +4440,7 @@ var handleUpdateMany = (ctx) => {
|
|
|
4405
4440
|
ctx.typeMap,
|
|
4406
4441
|
ctx.schemaBuilder
|
|
4407
4442
|
);
|
|
4408
|
-
const dataSchema =
|
|
4443
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "update");
|
|
4409
4444
|
const umSchema = z10.object({ where: whereSchema, data: dataSchema }).strict();
|
|
4410
4445
|
return wrapRelationOp(true, umSchema);
|
|
4411
4446
|
};
|
|
@@ -4452,17 +4487,21 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4452
4487
|
throw new ShapeError(
|
|
4453
4488
|
`Unknown related model "${relatedModelName}" for field "${model}.${fieldName}"`
|
|
4454
4489
|
);
|
|
4455
|
-
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4490
|
+
assertAllowedKeys(
|
|
4491
|
+
config,
|
|
4492
|
+
KNOWN_RELATION_WRITE_OPS,
|
|
4493
|
+
(key) => `Unknown relation write operation "${key}" on "${model}.${fieldName}". Allowed: ${[...KNOWN_RELATION_WRITE_OPS].join(", ")}`
|
|
4494
|
+
);
|
|
4495
|
+
const definedEntries = Object.entries(config).filter(
|
|
4496
|
+
([, opConfig]) => opConfig !== void 0
|
|
4497
|
+
);
|
|
4498
|
+
if (definedEntries.length === 0) {
|
|
4499
|
+
throw new ShapeError(
|
|
4500
|
+
`Empty relation write config on "${model}.${fieldName}". Define at least one operation: ${[...KNOWN_RELATION_WRITE_OPS].join(", ")}`
|
|
4501
|
+
);
|
|
4461
4502
|
}
|
|
4462
4503
|
const opSchemas = {};
|
|
4463
|
-
for (const [op, opConfig] of
|
|
4464
|
-
if (opConfig === void 0)
|
|
4465
|
-
continue;
|
|
4504
|
+
for (const [op, opConfig] of definedEntries) {
|
|
4466
4505
|
const handler = RELATION_OP_HANDLERS[op];
|
|
4467
4506
|
opSchemas[op] = handler({
|
|
4468
4507
|
model,
|
|
@@ -4479,7 +4518,7 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4479
4518
|
}
|
|
4480
4519
|
return z10.object(opSchemas).strict();
|
|
4481
4520
|
}
|
|
4482
|
-
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults) {
|
|
4521
|
+
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults, allowRelationWrites) {
|
|
4483
4522
|
const modelFields = typeMap[model];
|
|
4484
4523
|
if (!modelFields)
|
|
4485
4524
|
throw new ShapeError(`Unknown model: ${model}`);
|
|
@@ -4509,6 +4548,11 @@ function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, s
|
|
|
4509
4548
|
continue;
|
|
4510
4549
|
}
|
|
4511
4550
|
if (fieldMeta.isRelation) {
|
|
4551
|
+
if (!allowRelationWrites) {
|
|
4552
|
+
throw new ShapeError(
|
|
4553
|
+
`Field "${fieldName}" on model "${model}" is a relation. Relation writes are not supported for this method.`
|
|
4554
|
+
);
|
|
4555
|
+
}
|
|
4512
4556
|
if (!isPlainObject(value)) {
|
|
4513
4557
|
throw new ShapeError(
|
|
4514
4558
|
`Relation field "${fieldName}" on model "${model}" requires a relation write config object`
|
|
@@ -4622,13 +4666,8 @@ function validateAndMergeData(bodyData, cached, method, modelName) {
|
|
|
4622
4666
|
try {
|
|
4623
4667
|
validated = cached.schema.parse(bodyData);
|
|
4624
4668
|
} catch (err) {
|
|
4625
|
-
|
|
4626
|
-
|
|
4627
|
-
if (err && typeof err === "object" && "issues" in err) {
|
|
4628
|
-
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4629
|
-
throw new ShapeError(`${context}: ${formatZodError(err)}`, { cause: err });
|
|
4630
|
-
}
|
|
4631
|
-
throw err;
|
|
4669
|
+
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4670
|
+
wrapParseError(err, context);
|
|
4632
4671
|
}
|
|
4633
4672
|
return { ...validated, ...deepClone(cached.forced) };
|
|
4634
4673
|
}
|
|
@@ -4783,6 +4822,8 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
4783
4822
|
"updateManyAndReturn"
|
|
4784
4823
|
]);
|
|
4785
4824
|
var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set(["createMany", "createManyAndReturn"]);
|
|
4825
|
+
var RELATION_WRITE_CREATE_METHODS = /* @__PURE__ */ new Set(["create"]);
|
|
4826
|
+
var RELATION_WRITE_UPDATE_METHODS = /* @__PURE__ */ new Set(["update"]);
|
|
4786
4827
|
var MAX_PROJECTION_WALK_DEPTH = 10;
|
|
4787
4828
|
function walkForClientContent(obj, predicate, depth) {
|
|
4788
4829
|
if (depth > MAX_PROJECTION_WALK_DEPTH)
|
|
@@ -4933,11 +4974,11 @@ function createModelGuardExtension(config) {
|
|
|
4933
4974
|
)
|
|
4934
4975
|
);
|
|
4935
4976
|
}
|
|
4936
|
-
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
|
|
4977
|
+
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic, allowRelationWrites) {
|
|
4937
4978
|
const skipCache = wasDynamic || hasDataRefines(dataConfig);
|
|
4938
4979
|
return memoize(
|
|
4939
4980
|
dataSchemaCache,
|
|
4940
|
-
`${mode}\0${matchedKey}`,
|
|
4981
|
+
`${mode}\0${matchedKey}\0${allowRelationWrites ? "r" : "n"}`,
|
|
4941
4982
|
skipCache,
|
|
4942
4983
|
() => buildDataSchema(
|
|
4943
4984
|
modelName,
|
|
@@ -4948,7 +4989,8 @@ function createModelGuardExtension(config) {
|
|
|
4948
4989
|
enumMap,
|
|
4949
4990
|
scalarBase,
|
|
4950
4991
|
schemaBuilder,
|
|
4951
|
-
zodDefaults
|
|
4992
|
+
zodDefaults,
|
|
4993
|
+
allowRelationWrites
|
|
4952
4994
|
)
|
|
4953
4995
|
);
|
|
4954
4996
|
}
|
|
@@ -5206,6 +5248,39 @@ function createModelGuardExtension(config) {
|
|
|
5206
5248
|
const defaultProjection = buildDefaultProjectionBody(resolved.shape);
|
|
5207
5249
|
return { ...resolved.body, ...defaultProjection };
|
|
5208
5250
|
}
|
|
5251
|
+
function makeResolveMethod() {
|
|
5252
|
+
const WRITE_KEYS = ["data", "create", "update"];
|
|
5253
|
+
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
5254
|
+
return (body) => {
|
|
5255
|
+
const caller = resolveCaller();
|
|
5256
|
+
const resolved = resolveShape(input, body, contextFn, caller);
|
|
5257
|
+
for (const key of WRITE_KEYS) {
|
|
5258
|
+
if (hasOwn(resolved.shape, key)) {
|
|
5259
|
+
throw new ShapeError(
|
|
5260
|
+
`.resolve() is a read-only planning helper. Guard shape contains write key "${key}". Use the corresponding write method instead.`
|
|
5261
|
+
);
|
|
5262
|
+
}
|
|
5263
|
+
}
|
|
5264
|
+
for (const key of WRITE_KEYS) {
|
|
5265
|
+
if (hasOwn(resolved.body, key)) {
|
|
5266
|
+
throw new ShapeError(
|
|
5267
|
+
`.resolve() is a read-only planning helper. Request body contains write key "${key}".`
|
|
5268
|
+
);
|
|
5269
|
+
}
|
|
5270
|
+
}
|
|
5271
|
+
const effectiveReadBody = buildEffectiveReadBody({
|
|
5272
|
+
shape: resolved.shape,
|
|
5273
|
+
body: resolved.body
|
|
5274
|
+
});
|
|
5275
|
+
return {
|
|
5276
|
+
shape: resolved.shape,
|
|
5277
|
+
body: resolved.body,
|
|
5278
|
+
effectiveReadBody,
|
|
5279
|
+
matchedKey: resolved.matchedKey,
|
|
5280
|
+
wasDynamic: resolved.wasDynamic
|
|
5281
|
+
};
|
|
5282
|
+
};
|
|
5283
|
+
}
|
|
5209
5284
|
function makeReadMethod(method) {
|
|
5210
5285
|
return (body) => {
|
|
5211
5286
|
const caller = resolveCaller();
|
|
@@ -5239,6 +5314,7 @@ function createModelGuardExtension(config) {
|
|
|
5239
5314
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5240
5315
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5241
5316
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5317
|
+
const allowRelationWrites = RELATION_WRITE_CREATE_METHODS.has(method);
|
|
5242
5318
|
return (body) => {
|
|
5243
5319
|
const caller = resolveCaller();
|
|
5244
5320
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5264,7 +5340,8 @@ function createModelGuardExtension(config) {
|
|
|
5264
5340
|
"create",
|
|
5265
5341
|
resolved.shape.data,
|
|
5266
5342
|
resolved.matchedKey,
|
|
5267
|
-
resolved.wasDynamic
|
|
5343
|
+
resolved.wasDynamic,
|
|
5344
|
+
allowRelationWrites
|
|
5268
5345
|
);
|
|
5269
5346
|
let args;
|
|
5270
5347
|
if (method === "create") {
|
|
@@ -5312,6 +5389,7 @@ function createModelGuardExtension(config) {
|
|
|
5312
5389
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5313
5390
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5314
5391
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5392
|
+
const allowRelationWrites = RELATION_WRITE_UPDATE_METHODS.has(method);
|
|
5315
5393
|
return (body) => {
|
|
5316
5394
|
const caller = resolveCaller();
|
|
5317
5395
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5334,7 +5412,8 @@ function createModelGuardExtension(config) {
|
|
|
5334
5412
|
"update",
|
|
5335
5413
|
resolved.shape.data,
|
|
5336
5414
|
resolved.matchedKey,
|
|
5337
|
-
resolved.wasDynamic
|
|
5415
|
+
resolved.wasDynamic,
|
|
5416
|
+
allowRelationWrites
|
|
5338
5417
|
);
|
|
5339
5418
|
const data = validateAndMergeData(
|
|
5340
5419
|
resolved.body.data,
|
|
@@ -5507,7 +5586,8 @@ function createModelGuardExtension(config) {
|
|
|
5507
5586
|
"create",
|
|
5508
5587
|
resolved.shape.create,
|
|
5509
5588
|
`upsert:create\0${resolved.matchedKey}`,
|
|
5510
|
-
resolved.wasDynamic
|
|
5589
|
+
resolved.wasDynamic,
|
|
5590
|
+
true
|
|
5511
5591
|
);
|
|
5512
5592
|
const createData = validateAndMergeData(
|
|
5513
5593
|
resolved.body.create,
|
|
@@ -5519,7 +5599,8 @@ function createModelGuardExtension(config) {
|
|
|
5519
5599
|
"update",
|
|
5520
5600
|
resolved.shape.update,
|
|
5521
5601
|
`upsert:update\0${resolved.matchedKey}`,
|
|
5522
|
-
resolved.wasDynamic
|
|
5602
|
+
resolved.wasDynamic,
|
|
5603
|
+
true
|
|
5523
5604
|
);
|
|
5524
5605
|
const updateData = validateAndMergeData(
|
|
5525
5606
|
resolved.body.update,
|
|
@@ -5552,6 +5633,7 @@ function createModelGuardExtension(config) {
|
|
|
5552
5633
|
};
|
|
5553
5634
|
}
|
|
5554
5635
|
return {
|
|
5636
|
+
resolve: makeResolveMethod(),
|
|
5555
5637
|
findMany: makeReadMethod("findMany"),
|
|
5556
5638
|
findFirst: makeReadMethod("findFirst"),
|
|
5557
5639
|
findFirstOrThrow: makeReadMethod("findFirstOrThrow"),
|