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.cjs
CHANGED
|
@@ -243,7 +243,7 @@ function createScalarBase(strictDecimal) {
|
|
|
243
243
|
return {
|
|
244
244
|
String: () => import_zod.z.string(),
|
|
245
245
|
Int: () => import_zod.z.number().int(),
|
|
246
|
-
Float: () => import_zod.z.number(),
|
|
246
|
+
Float: () => import_zod.z.number().finite(),
|
|
247
247
|
Decimal: createDecimalFactory(strictDecimal),
|
|
248
248
|
BigInt: () => import_zod.z.union([
|
|
249
249
|
import_zod.z.bigint(),
|
|
@@ -384,6 +384,19 @@ function requireConfigTrue(config, context) {
|
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
|
+
function requirePlainObjectConfig(value, message) {
|
|
388
|
+
if (!isPlainObject(value)) {
|
|
389
|
+
throw new ShapeError(message);
|
|
390
|
+
}
|
|
391
|
+
return value;
|
|
392
|
+
}
|
|
393
|
+
function assertAllowedKeys(value, allowed, makeError) {
|
|
394
|
+
for (const key of Object.keys(value)) {
|
|
395
|
+
if (!allowed.has(key)) {
|
|
396
|
+
throw new ShapeError(makeError(key));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
387
400
|
|
|
388
401
|
// src/runtime/zod-type-map.ts
|
|
389
402
|
var SCALAR_OPERATORS = {
|
|
@@ -447,24 +460,12 @@ var JSON_ARRAY_OPERATORS = /* @__PURE__ */ new Set([
|
|
|
447
460
|
"array_starts_with",
|
|
448
461
|
"array_ends_with"
|
|
449
462
|
]);
|
|
450
|
-
function getSupportedOperators(
|
|
451
|
-
|
|
452
|
-
let list;
|
|
453
|
-
let enumField;
|
|
454
|
-
if (typeof input === "string") {
|
|
455
|
-
fieldType = input;
|
|
456
|
-
list = isList;
|
|
457
|
-
enumField = isEnum;
|
|
458
|
-
} else {
|
|
459
|
-
fieldType = input.type;
|
|
460
|
-
list = input.isList;
|
|
461
|
-
enumField = input.isEnum === true;
|
|
462
|
-
}
|
|
463
|
-
if (list)
|
|
463
|
+
function getSupportedOperators(fieldMeta) {
|
|
464
|
+
if (fieldMeta.isList)
|
|
464
465
|
return [...SCALAR_LIST_OPERATORS];
|
|
465
|
-
if (
|
|
466
|
+
if (fieldMeta.isEnum === true)
|
|
466
467
|
return [...ENUM_OPERATORS];
|
|
467
|
-
const ops = SCALAR_OPERATORS[
|
|
468
|
+
const ops = SCALAR_OPERATORS[fieldMeta.type];
|
|
468
469
|
if (!ops)
|
|
469
470
|
return [];
|
|
470
471
|
return [...ops];
|
|
@@ -1029,6 +1030,7 @@ function validateContext(ctx) {
|
|
|
1029
1030
|
|
|
1030
1031
|
// src/runtime/query-builder-where.ts
|
|
1031
1032
|
var import_zod5 = require("zod");
|
|
1033
|
+
var import_node_util = require("util");
|
|
1032
1034
|
|
|
1033
1035
|
// src/shared/deep-clone.ts
|
|
1034
1036
|
function deepClone(value) {
|
|
@@ -1309,15 +1311,10 @@ function applyBuiltShape(built, body, isUniqueMethod, modelName) {
|
|
|
1309
1311
|
try {
|
|
1310
1312
|
validated = built.zodSchema.parse(parseable);
|
|
1311
1313
|
} catch (err) {
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
throw new ShapeError(`${context}: ${formatZodError(err)}`, {
|
|
1317
|
-
cause: err
|
|
1318
|
-
});
|
|
1319
|
-
}
|
|
1320
|
-
throw err;
|
|
1314
|
+
wrapParseError(
|
|
1315
|
+
err,
|
|
1316
|
+
modelName ? `Invalid query on model "${modelName}"` : "Invalid query"
|
|
1317
|
+
);
|
|
1321
1318
|
}
|
|
1322
1319
|
if (hasWhereForced(built.forcedWhere)) {
|
|
1323
1320
|
validated.where = isUniqueMethod ? mergeUniqueWhereForced(
|
|
@@ -1634,37 +1631,8 @@ var JSON_STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
|
1634
1631
|
]);
|
|
1635
1632
|
var NEGATIVE_RELATION_OPS = /* @__PURE__ */ new Set(["none", "isNot"]);
|
|
1636
1633
|
var MAX_WHERE_DEPTH = 10;
|
|
1637
|
-
function
|
|
1638
|
-
|
|
1639
|
-
return `${value}n`;
|
|
1640
|
-
if (typeof value === "undefined")
|
|
1641
|
-
return "undefined";
|
|
1642
|
-
if (typeof value === "function")
|
|
1643
|
-
return "[function]";
|
|
1644
|
-
if (typeof value === "symbol")
|
|
1645
|
-
return value.toString();
|
|
1646
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
1647
|
-
try {
|
|
1648
|
-
const json = JSON.stringify(value, (_key, current) => {
|
|
1649
|
-
if (typeof current === "bigint")
|
|
1650
|
-
return `${current}n`;
|
|
1651
|
-
if (typeof current === "undefined")
|
|
1652
|
-
return "[undefined]";
|
|
1653
|
-
if (typeof current === "function")
|
|
1654
|
-
return "[function]";
|
|
1655
|
-
if (typeof current === "symbol")
|
|
1656
|
-
return current.toString();
|
|
1657
|
-
if (current && typeof current === "object") {
|
|
1658
|
-
if (seen.has(current))
|
|
1659
|
-
return "[Circular]";
|
|
1660
|
-
seen.add(current);
|
|
1661
|
-
}
|
|
1662
|
-
return current;
|
|
1663
|
-
});
|
|
1664
|
-
return json === void 0 ? String(value) : json;
|
|
1665
|
-
} catch {
|
|
1666
|
-
return String(value);
|
|
1667
|
-
}
|
|
1634
|
+
function formatValue(value) {
|
|
1635
|
+
return (0, import_node_util.inspect)(value, { depth: 3, breakLength: Infinity });
|
|
1668
1636
|
}
|
|
1669
1637
|
function mergeScalarConditions(target, source) {
|
|
1670
1638
|
for (const [field, ops] of Object.entries(source)) {
|
|
@@ -1685,7 +1653,7 @@ function mergeScalarConditions(target, source) {
|
|
|
1685
1653
|
const existingVal = existing[op];
|
|
1686
1654
|
if (!deepEqual(existingVal, val)) {
|
|
1687
1655
|
throw new ShapeError(
|
|
1688
|
-
`Conflicting forced where values for "${field}.${op}": shape defines both ${
|
|
1656
|
+
`Conflicting forced where values for "${field}.${op}": shape defines both ${formatValue(existingVal)} and ${formatValue(val)}`
|
|
1689
1657
|
);
|
|
1690
1658
|
}
|
|
1691
1659
|
}
|
|
@@ -2523,10 +2491,7 @@ function createArgsBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2523
2491
|
`${fieldMeta.type} field "${fieldName}" cannot be used in having`
|
|
2524
2492
|
);
|
|
2525
2493
|
}
|
|
2526
|
-
const allowedOps = getSupportedOperators(
|
|
2527
|
-
fieldMeta.type,
|
|
2528
|
-
fieldMeta.isList
|
|
2529
|
-
);
|
|
2494
|
+
const allowedOps = getSupportedOperators(fieldMeta);
|
|
2530
2495
|
const opSchemas = {};
|
|
2531
2496
|
for (const op of allowedOps) {
|
|
2532
2497
|
opSchemas[op] = createOperatorSchema(
|
|
@@ -2703,20 +2668,27 @@ function buildDefaultProjectionBody(shape) {
|
|
|
2703
2668
|
|
|
2704
2669
|
// src/runtime/query-builder-projection.ts
|
|
2705
2670
|
var KNOWN_NESTED_KEYS = {
|
|
2706
|
-
include: /* @__PURE__ */ new Set([
|
|
2707
|
-
|
|
2671
|
+
include: /* @__PURE__ */ new Set([
|
|
2672
|
+
"where",
|
|
2673
|
+
"include",
|
|
2674
|
+
"select",
|
|
2675
|
+
"orderBy",
|
|
2676
|
+
"cursor",
|
|
2677
|
+
"take",
|
|
2678
|
+
"skip"
|
|
2679
|
+
]),
|
|
2680
|
+
select: /* @__PURE__ */ new Set([
|
|
2681
|
+
"select",
|
|
2682
|
+
"include",
|
|
2683
|
+
"where",
|
|
2684
|
+
"orderBy",
|
|
2685
|
+
"cursor",
|
|
2686
|
+
"take",
|
|
2687
|
+
"skip"
|
|
2688
|
+
])
|
|
2708
2689
|
};
|
|
2709
2690
|
var KNOWN_COUNT_SELECT_ENTRY_KEYS = /* @__PURE__ */ new Set(["where"]);
|
|
2710
2691
|
var MAX_PROJECTION_DEPTH = 10;
|
|
2711
|
-
function validateNestedKeys(keys, allowed, context) {
|
|
2712
|
-
for (const key of keys) {
|
|
2713
|
-
if (!allowed.has(key)) {
|
|
2714
|
-
throw new ShapeError(
|
|
2715
|
-
`Unknown key "${key}" in ${context}. Allowed: ${[...allowed].join(", ")}`
|
|
2716
|
-
);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
}
|
|
2720
2692
|
function hasDefinedKeys(v) {
|
|
2721
2693
|
return Object.values(v).some((value) => value !== void 0);
|
|
2722
2694
|
}
|
|
@@ -2729,6 +2701,20 @@ function wrapRelationSchema(nestedObj, skeleton) {
|
|
|
2729
2701
|
collapsed
|
|
2730
2702
|
);
|
|
2731
2703
|
}
|
|
2704
|
+
function buildRelationWhere(relatedType, whereConfig, context, buildWhereSchema) {
|
|
2705
|
+
if (Object.keys(whereConfig).length === 0) {
|
|
2706
|
+
throw new ShapeError(
|
|
2707
|
+
`Empty "where" in ${context}. Define at least one field.`
|
|
2708
|
+
);
|
|
2709
|
+
}
|
|
2710
|
+
const { schema, forced } = buildWhereSchema(relatedType, whereConfig);
|
|
2711
|
+
if (!schema && !hasWhereForced(forced)) {
|
|
2712
|
+
throw new ShapeError(
|
|
2713
|
+
`"where" in ${context} produced no schema and no forced conditions. Define at least one field.`
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
return { schema, forced };
|
|
2717
|
+
}
|
|
2732
2718
|
function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
2733
2719
|
function buildIncludeCountSchema(model, config) {
|
|
2734
2720
|
const modelFields = typeMap[model];
|
|
@@ -2742,13 +2728,11 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2742
2728
|
`Invalid _count config on model "${model}". Expected true or { select: { ... } }`
|
|
2743
2729
|
);
|
|
2744
2730
|
}
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2748
|
-
|
|
2749
|
-
|
|
2750
|
-
}
|
|
2751
|
-
}
|
|
2731
|
+
assertAllowedKeys(
|
|
2732
|
+
config,
|
|
2733
|
+
/* @__PURE__ */ new Set(["select"]),
|
|
2734
|
+
(key) => `Unknown key "${key}" in _count config on model "${model}". Only "select" is allowed.`
|
|
2735
|
+
);
|
|
2752
2736
|
if (!isPlainObject(config.select)) {
|
|
2753
2737
|
throw new ShapeError(
|
|
2754
2738
|
`Invalid _count.select on model "${model}". Expected a plain object with relation field keys.`
|
|
@@ -2765,11 +2749,17 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2765
2749
|
for (const [fieldName, fieldConfig] of Object.entries(selectObj)) {
|
|
2766
2750
|
const fieldMeta = modelFields[fieldName];
|
|
2767
2751
|
if (!fieldMeta)
|
|
2768
|
-
throw new ShapeError(
|
|
2752
|
+
throw new ShapeError(
|
|
2753
|
+
`Unknown field "${fieldName}" on model "${model}" in _count.select`
|
|
2754
|
+
);
|
|
2769
2755
|
if (!fieldMeta.isRelation)
|
|
2770
|
-
throw new ShapeError(
|
|
2756
|
+
throw new ShapeError(
|
|
2757
|
+
`Field "${fieldName}" is not a relation on model "${model}" in _count.select`
|
|
2758
|
+
);
|
|
2771
2759
|
if (!fieldMeta.isList)
|
|
2772
|
-
throw new ShapeError(
|
|
2760
|
+
throw new ShapeError(
|
|
2761
|
+
`Field "${fieldName}" is a to-one relation on model "${model}" in _count.select. Only to-many relations support _count.`
|
|
2762
|
+
);
|
|
2773
2763
|
if (fieldConfig === true) {
|
|
2774
2764
|
countSelectFields[fieldName] = import_zod7.z.literal(true).optional();
|
|
2775
2765
|
continue;
|
|
@@ -2784,16 +2774,18 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2784
2774
|
`Empty config for _count.select.${fieldName} on model "${model}". Use true or { where: { ... } }.`
|
|
2785
2775
|
);
|
|
2786
2776
|
}
|
|
2787
|
-
|
|
2788
|
-
|
|
2777
|
+
assertAllowedKeys(
|
|
2778
|
+
fieldConfig,
|
|
2789
2779
|
KNOWN_COUNT_SELECT_ENTRY_KEYS,
|
|
2790
|
-
`_count.select.${fieldName} on model "${model}"`
|
|
2780
|
+
(key) => `Unknown key "${key}" in _count.select.${fieldName} on model "${model}". Allowed: ${[...KNOWN_COUNT_SELECT_ENTRY_KEYS].join(", ")}`
|
|
2791
2781
|
);
|
|
2792
2782
|
if (fieldConfig.where) {
|
|
2793
2783
|
const relatedType = fieldMeta.type;
|
|
2794
|
-
const { schema: whereSchema, forced } =
|
|
2784
|
+
const { schema: whereSchema, forced } = buildRelationWhere(
|
|
2795
2785
|
relatedType,
|
|
2796
|
-
fieldConfig.where
|
|
2786
|
+
fieldConfig.where,
|
|
2787
|
+
`_count.select.${fieldName} on model "${model}"`,
|
|
2788
|
+
deps.buildWhereSchema
|
|
2797
2789
|
);
|
|
2798
2790
|
const nestedSchemas = {};
|
|
2799
2791
|
if (whereSchema)
|
|
@@ -2816,13 +2808,15 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2816
2808
|
forcedCountWhere
|
|
2817
2809
|
};
|
|
2818
2810
|
}
|
|
2819
|
-
function buildNestedRelSchemas(relatedType, config, depth) {
|
|
2811
|
+
function buildNestedRelSchemas(relatedType, config, depth, context) {
|
|
2820
2812
|
const nestedSchemas = {};
|
|
2821
2813
|
const relForced = {};
|
|
2822
2814
|
if (config.where) {
|
|
2823
|
-
const { schema: whereSchema, forced } =
|
|
2815
|
+
const { schema: whereSchema, forced } = buildRelationWhere(
|
|
2824
2816
|
relatedType,
|
|
2825
|
-
config.where
|
|
2817
|
+
config.where,
|
|
2818
|
+
context,
|
|
2819
|
+
deps.buildWhereSchema
|
|
2826
2820
|
);
|
|
2827
2821
|
if (whereSchema)
|
|
2828
2822
|
nestedSchemas["where"] = whereSchema;
|
|
@@ -2830,7 +2824,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2830
2824
|
relForced.where = forced;
|
|
2831
2825
|
}
|
|
2832
2826
|
if (config.include) {
|
|
2833
|
-
const nested = buildProjectionSchema(
|
|
2827
|
+
const nested = buildProjectionSchema(
|
|
2828
|
+
"include",
|
|
2829
|
+
relatedType,
|
|
2830
|
+
config.include,
|
|
2831
|
+
depth + 1
|
|
2832
|
+
);
|
|
2834
2833
|
nestedSchemas["include"] = nested.schema;
|
|
2835
2834
|
if (Object.keys(nested.forcedTree).length > 0)
|
|
2836
2835
|
relForced.include = nested.forcedTree;
|
|
@@ -2840,7 +2839,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2840
2839
|
}
|
|
2841
2840
|
}
|
|
2842
2841
|
if (config.select) {
|
|
2843
|
-
const nested = buildProjectionSchema(
|
|
2842
|
+
const nested = buildProjectionSchema(
|
|
2843
|
+
"select",
|
|
2844
|
+
relatedType,
|
|
2845
|
+
config.select,
|
|
2846
|
+
depth + 1
|
|
2847
|
+
);
|
|
2844
2848
|
nestedSchemas["select"] = nested.schema;
|
|
2845
2849
|
if (Object.keys(nested.forcedTree).length > 0)
|
|
2846
2850
|
relForced.select = nested.forcedTree;
|
|
@@ -2850,15 +2854,26 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2850
2854
|
}
|
|
2851
2855
|
}
|
|
2852
2856
|
if (config.orderBy) {
|
|
2853
|
-
nestedSchemas["orderBy"] = deps.buildOrderBySchema(
|
|
2857
|
+
nestedSchemas["orderBy"] = deps.buildOrderBySchema(
|
|
2858
|
+
relatedType,
|
|
2859
|
+
config.orderBy
|
|
2860
|
+
);
|
|
2854
2861
|
}
|
|
2855
2862
|
if (config.cursor) {
|
|
2856
|
-
nestedSchemas["cursor"] = deps.buildCursorSchema(
|
|
2863
|
+
nestedSchemas["cursor"] = deps.buildCursorSchema(
|
|
2864
|
+
relatedType,
|
|
2865
|
+
config.cursor
|
|
2866
|
+
);
|
|
2857
2867
|
}
|
|
2858
|
-
if (config.take) {
|
|
2868
|
+
if ("take" in config && config.take !== void 0) {
|
|
2859
2869
|
nestedSchemas["take"] = deps.buildTakeSchema(config.take);
|
|
2860
2870
|
}
|
|
2861
|
-
if (config.skip) {
|
|
2871
|
+
if ("skip" in config && config.skip !== void 0) {
|
|
2872
|
+
if (config.skip !== true) {
|
|
2873
|
+
throw new ShapeError(
|
|
2874
|
+
`Nested "skip" in ${context} must be true`
|
|
2875
|
+
);
|
|
2876
|
+
}
|
|
2862
2877
|
nestedSchemas["skip"] = import_zod7.z.number().int().min(0).optional();
|
|
2863
2878
|
}
|
|
2864
2879
|
return { nestedSchemas, relForced };
|
|
@@ -2884,28 +2899,43 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2884
2899
|
let topLevelForcedCountWhere = {};
|
|
2885
2900
|
for (const [fieldName, config] of Object.entries(projectionConfig)) {
|
|
2886
2901
|
if (fieldName === "_count") {
|
|
2887
|
-
const countResult = buildIncludeCountSchema(
|
|
2902
|
+
const countResult = buildIncludeCountSchema(
|
|
2903
|
+
model,
|
|
2904
|
+
config
|
|
2905
|
+
);
|
|
2888
2906
|
fieldSchemas["_count"] = countResult.schema;
|
|
2889
2907
|
topLevelForcedCountWhere = countResult.forcedCountWhere;
|
|
2890
2908
|
continue;
|
|
2891
2909
|
}
|
|
2892
2910
|
const fieldMeta = modelFields[fieldName];
|
|
2893
2911
|
if (!fieldMeta)
|
|
2894
|
-
throw new ShapeError(
|
|
2912
|
+
throw new ShapeError(
|
|
2913
|
+
`Unknown field "${fieldName}" on model "${model}"`
|
|
2914
|
+
);
|
|
2895
2915
|
if (mode === "include" && !fieldMeta.isRelation) {
|
|
2896
|
-
throw new ShapeError(
|
|
2916
|
+
throw new ShapeError(
|
|
2917
|
+
`Field "${fieldName}" is not a relation on model "${model}"`
|
|
2918
|
+
);
|
|
2897
2919
|
}
|
|
2898
2920
|
if (config === true) {
|
|
2899
2921
|
fieldSchemas[fieldName] = import_zod7.z.literal(true).optional();
|
|
2900
2922
|
continue;
|
|
2901
2923
|
}
|
|
2902
2924
|
if (mode === "select" && !fieldMeta.isRelation) {
|
|
2903
|
-
throw new ShapeError(
|
|
2925
|
+
throw new ShapeError(
|
|
2926
|
+
`Nested select args only valid for relations, not scalar "${fieldName}" on model "${model}"`
|
|
2927
|
+
);
|
|
2904
2928
|
}
|
|
2905
2929
|
const contextLabel = `nested ${mode} for "${fieldName}" on model "${model}"`;
|
|
2906
|
-
|
|
2930
|
+
assertAllowedKeys(
|
|
2931
|
+
config,
|
|
2932
|
+
allowedNestedKeys,
|
|
2933
|
+
(key) => `Unknown key "${key}" in ${contextLabel}. Allowed: ${[...allowedNestedKeys].join(", ")}`
|
|
2934
|
+
);
|
|
2907
2935
|
if (config.select && config.include) {
|
|
2908
|
-
throw new ShapeError(
|
|
2936
|
+
throw new ShapeError(
|
|
2937
|
+
`Nested ${mode} for "${fieldName}" cannot define both "select" and "include".`
|
|
2938
|
+
);
|
|
2909
2939
|
}
|
|
2910
2940
|
if (!fieldMeta.isList) {
|
|
2911
2941
|
if (config.where || config.orderBy || config.cursor || config.take || config.skip) {
|
|
@@ -2914,7 +2944,12 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2914
2944
|
);
|
|
2915
2945
|
}
|
|
2916
2946
|
}
|
|
2917
|
-
const { nestedSchemas, relForced } = buildNestedRelSchemas(
|
|
2947
|
+
const { nestedSchemas, relForced } = buildNestedRelSchemas(
|
|
2948
|
+
fieldMeta.type,
|
|
2949
|
+
config,
|
|
2950
|
+
currentDepth,
|
|
2951
|
+
contextLabel
|
|
2952
|
+
);
|
|
2918
2953
|
const nestedObj = import_zod7.z.object(nestedSchemas).strict();
|
|
2919
2954
|
fieldSchemas[fieldName] = wrapRelationSchema(
|
|
2920
2955
|
nestedObj,
|
|
@@ -2939,27 +2974,33 @@ function createProjectionBuilder(typeMap, _enumMap, deps) {
|
|
|
2939
2974
|
function buildSelectSchema(model, selectConfig, depth) {
|
|
2940
2975
|
return buildProjectionSchema("select", model, selectConfig, depth);
|
|
2941
2976
|
}
|
|
2942
|
-
return {
|
|
2977
|
+
return {
|
|
2978
|
+
buildIncludeSchema,
|
|
2979
|
+
buildSelectSchema,
|
|
2980
|
+
buildIncludeCountSchema,
|
|
2981
|
+
buildProjectionSchema
|
|
2982
|
+
};
|
|
2943
2983
|
}
|
|
2944
2984
|
|
|
2945
2985
|
// src/shared/operation-shape-keys.ts
|
|
2946
2986
|
var OPERATION_SHAPE_KEYS = {
|
|
2947
2987
|
findMany: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2988
|
+
findManyPaginated: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2948
2989
|
findFirst: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2949
2990
|
findFirstOrThrow: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
|
|
2950
2991
|
findUnique: ["where", "include", "select"],
|
|
2951
2992
|
findUniqueOrThrow: ["where", "include", "select"],
|
|
2952
2993
|
count: ["where", "select", "cursor", "orderBy", "skip", "take"],
|
|
2953
2994
|
aggregate: ["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
|
|
2954
|
-
groupBy: ["where", "
|
|
2955
|
-
create: ["data", "
|
|
2956
|
-
createMany: ["data"],
|
|
2957
|
-
createManyAndReturn: ["data", "select", "include"],
|
|
2958
|
-
update: ["
|
|
2959
|
-
updateMany: ["
|
|
2960
|
-
updateManyAndReturn: ["
|
|
2961
|
-
upsert: ["where", "create", "update", "
|
|
2962
|
-
delete: ["where", "
|
|
2995
|
+
groupBy: ["where", "orderBy", "by", "having", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
|
|
2996
|
+
create: ["data", "include", "select"],
|
|
2997
|
+
createMany: ["data", "skipDuplicates"],
|
|
2998
|
+
createManyAndReturn: ["data", "select", "include", "skipDuplicates"],
|
|
2999
|
+
update: ["where", "data", "include", "select"],
|
|
3000
|
+
updateMany: ["where", "data"],
|
|
3001
|
+
updateManyAndReturn: ["where", "data", "select", "include"],
|
|
3002
|
+
upsert: ["where", "create", "update", "include", "select"],
|
|
3003
|
+
delete: ["where", "include", "select"],
|
|
2963
3004
|
deleteMany: ["where"]
|
|
2964
3005
|
};
|
|
2965
3006
|
var READ_METHOD_ALLOWED_ARGS = {
|
|
@@ -3271,7 +3312,17 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
3271
3312
|
let forcedIncludeCountWhere = {};
|
|
3272
3313
|
let forcedSelectCountWhere = {};
|
|
3273
3314
|
if (shape.where) {
|
|
3315
|
+
if (Object.keys(shape.where).length === 0) {
|
|
3316
|
+
throw new ShapeError(
|
|
3317
|
+
`Empty "where" in shape for model "${model}" method "${method}". Define at least one field.`
|
|
3318
|
+
);
|
|
3319
|
+
}
|
|
3274
3320
|
const builtWhere = UNIQUE_WHERE_METHODS.has(method) ? whereBuilder.buildUniqueWhereSchema(model, shape.where) : whereBuilder.buildWhereSchema(model, shape.where);
|
|
3321
|
+
if (!builtWhere.schema && !hasWhereForced(builtWhere.forced)) {
|
|
3322
|
+
throw new ShapeError(
|
|
3323
|
+
`"where" in shape for model "${model}" method "${method}" produced no schema and no forced conditions.`
|
|
3324
|
+
);
|
|
3325
|
+
}
|
|
3275
3326
|
if (builtWhere.schema) {
|
|
3276
3327
|
schemaFields.where = builtWhere.schema;
|
|
3277
3328
|
}
|
|
@@ -4073,27 +4124,19 @@ function validateRelationOpKeys(actual, opKey, model, field, opLabel) {
|
|
|
4073
4124
|
const allowed = RELATION_OP_ALLOWED_KEYS[opKey];
|
|
4074
4125
|
if (!allowed)
|
|
4075
4126
|
return;
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
}
|
|
4082
|
-
}
|
|
4127
|
+
assertAllowedKeys(
|
|
4128
|
+
actual,
|
|
4129
|
+
allowed,
|
|
4130
|
+
(key) => `Unknown key "${key}" in ${opLabel} config on "${model}.${field}". Allowed: ${[...allowed].join(", ")}`
|
|
4131
|
+
);
|
|
4083
4132
|
}
|
|
4084
4133
|
function validateAllowedKeys(value, allowed, method, kind) {
|
|
4085
|
-
|
|
4086
|
-
if (
|
|
4087
|
-
|
|
4088
|
-
throw new ShapeError(
|
|
4089
|
-
`Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`
|
|
4090
|
-
);
|
|
4091
|
-
}
|
|
4092
|
-
throw new ShapeError(
|
|
4093
|
-
`Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`
|
|
4094
|
-
);
|
|
4134
|
+
assertAllowedKeys(value, allowed, (key) => {
|
|
4135
|
+
if (kind === "body") {
|
|
4136
|
+
return `Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`;
|
|
4095
4137
|
}
|
|
4096
|
-
|
|
4138
|
+
return `Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`;
|
|
4139
|
+
});
|
|
4097
4140
|
}
|
|
4098
4141
|
function validateCreateCompleteness(modelName, dataConfig, typeMap, scopeFks, zodDefaults) {
|
|
4099
4142
|
const modelFields = typeMap[modelName];
|
|
@@ -4180,18 +4223,10 @@ function buildNestedDataSchema(model, config, mode, typeMap, schemaBuilder) {
|
|
|
4180
4223
|
}
|
|
4181
4224
|
return import_zod10.z.object(fieldSchemas).strict();
|
|
4182
4225
|
}
|
|
4183
|
-
function requirePlainObjectConfig(value, message) {
|
|
4184
|
-
if (!isPlainObject(value))
|
|
4185
|
-
throw new ShapeError(message);
|
|
4186
|
-
return value;
|
|
4187
|
-
}
|
|
4188
4226
|
function requireNestedObject(cfg, key, message) {
|
|
4189
|
-
|
|
4190
|
-
if (!v || !isPlainObject(v))
|
|
4191
|
-
throw new ShapeError(message);
|
|
4192
|
-
return v;
|
|
4227
|
+
return requirePlainObjectConfig(cfg[key], message);
|
|
4193
4228
|
}
|
|
4194
|
-
function
|
|
4229
|
+
function buildRelatedUniqueSelector(ctx, cfg, context) {
|
|
4195
4230
|
return buildUniqueSelectorSchema(
|
|
4196
4231
|
ctx.model,
|
|
4197
4232
|
ctx.fieldName,
|
|
@@ -4204,7 +4239,7 @@ function buildUniqueSelector(ctx, cfg, context) {
|
|
|
4204
4239
|
context
|
|
4205
4240
|
);
|
|
4206
4241
|
}
|
|
4207
|
-
function
|
|
4242
|
+
function buildRelatedNestedData(ctx, cfg, mode) {
|
|
4208
4243
|
return buildNestedDataSchema(
|
|
4209
4244
|
ctx.relatedModelName,
|
|
4210
4245
|
cfg,
|
|
@@ -4218,7 +4253,7 @@ var handleConnect = (ctx) => {
|
|
|
4218
4253
|
ctx.config,
|
|
4219
4254
|
`connect config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4220
4255
|
);
|
|
4221
|
-
const schema =
|
|
4256
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "connect");
|
|
4222
4257
|
return wrapRelationOp(ctx.isList, schema);
|
|
4223
4258
|
};
|
|
4224
4259
|
var handleConnectOrCreate = (ctx) => {
|
|
@@ -4237,8 +4272,8 @@ var handleConnectOrCreate = (ctx) => {
|
|
|
4237
4272
|
"create",
|
|
4238
4273
|
`connectOrCreate on "${ctx.model}.${ctx.fieldName}" requires "create" object`
|
|
4239
4274
|
);
|
|
4240
|
-
const whereSchema =
|
|
4241
|
-
const createSchema =
|
|
4275
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "connectOrCreate.where");
|
|
4276
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4242
4277
|
const cocSchema = import_zod10.z.object({ where: whereSchema, create: createSchema }).strict();
|
|
4243
4278
|
return wrapRelationOp(ctx.isList, cocSchema);
|
|
4244
4279
|
};
|
|
@@ -4247,7 +4282,7 @@ var handleCreate = (ctx) => {
|
|
|
4247
4282
|
ctx.config,
|
|
4248
4283
|
`create config on "${ctx.model}.${ctx.fieldName}" must be an object of field names`
|
|
4249
4284
|
);
|
|
4250
|
-
const createSchema =
|
|
4285
|
+
const createSchema = buildRelatedNestedData(ctx, cfg, "create");
|
|
4251
4286
|
return wrapRelationOp(ctx.isList, createSchema);
|
|
4252
4287
|
};
|
|
4253
4288
|
var handleCreateMany = (ctx) => {
|
|
@@ -4266,7 +4301,7 @@ var handleCreateMany = (ctx) => {
|
|
|
4266
4301
|
"data",
|
|
4267
4302
|
`createMany on "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4268
4303
|
);
|
|
4269
|
-
const dataSchema =
|
|
4304
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "create");
|
|
4270
4305
|
const cmSchemaFields = {
|
|
4271
4306
|
data: import_zod10.z.preprocess(coerceToArray, import_zod10.z.array(dataSchema))
|
|
4272
4307
|
};
|
|
@@ -4289,7 +4324,7 @@ var handleDisconnect = (ctx) => {
|
|
|
4289
4324
|
`disconnect config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4290
4325
|
);
|
|
4291
4326
|
}
|
|
4292
|
-
const schema =
|
|
4327
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "disconnect");
|
|
4293
4328
|
if (ctx.isList)
|
|
4294
4329
|
return wrapRelationOp(true, schema);
|
|
4295
4330
|
return import_zod10.z.union([import_zod10.z.literal(true), schema]).optional();
|
|
@@ -4308,7 +4343,7 @@ var handleDelete = (ctx) => {
|
|
|
4308
4343
|
`delete config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4309
4344
|
);
|
|
4310
4345
|
}
|
|
4311
|
-
const schema =
|
|
4346
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "delete");
|
|
4312
4347
|
if (ctx.isList)
|
|
4313
4348
|
return wrapRelationOp(true, schema);
|
|
4314
4349
|
return import_zod10.z.union([import_zod10.z.literal(true), schema]).optional();
|
|
@@ -4323,7 +4358,7 @@ var handleSet = (ctx) => {
|
|
|
4323
4358
|
ctx.config,
|
|
4324
4359
|
`set config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4325
4360
|
);
|
|
4326
|
-
const schema =
|
|
4361
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "set");
|
|
4327
4362
|
return wrapRelationOp(true, schema);
|
|
4328
4363
|
};
|
|
4329
4364
|
var handleUpdate = (ctx) => {
|
|
@@ -4343,12 +4378,12 @@ var handleUpdate = (ctx) => {
|
|
|
4343
4378
|
"data",
|
|
4344
4379
|
`update on to-many "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4345
4380
|
);
|
|
4346
|
-
const whereSchema =
|
|
4347
|
-
const dataSchema2 =
|
|
4381
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "update.where");
|
|
4382
|
+
const dataSchema2 = buildRelatedNestedData(ctx, data, "update");
|
|
4348
4383
|
const updateSchema = import_zod10.z.object({ where: whereSchema, data: dataSchema2 }).strict();
|
|
4349
4384
|
return wrapRelationOp(true, updateSchema);
|
|
4350
4385
|
}
|
|
4351
|
-
const dataSchema =
|
|
4386
|
+
const dataSchema = buildRelatedNestedData(ctx, cfg, "update");
|
|
4352
4387
|
return dataSchema.optional();
|
|
4353
4388
|
};
|
|
4354
4389
|
var handleUpsert = (ctx) => {
|
|
@@ -4373,15 +4408,15 @@ var handleUpsert = (ctx) => {
|
|
|
4373
4408
|
"update",
|
|
4374
4409
|
`upsert on "${ctx.model}.${ctx.fieldName}" requires "update" object`
|
|
4375
4410
|
);
|
|
4376
|
-
const createSchema =
|
|
4377
|
-
const updateSchema =
|
|
4411
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4412
|
+
const updateSchema = buildRelatedNestedData(ctx, update, "update");
|
|
4378
4413
|
if (ctx.isList) {
|
|
4379
4414
|
const where = requireNestedObject(
|
|
4380
4415
|
cfg,
|
|
4381
4416
|
"where",
|
|
4382
4417
|
`upsert on to-many "${ctx.model}.${ctx.fieldName}" requires "where" object`
|
|
4383
4418
|
);
|
|
4384
|
-
const whereSchema =
|
|
4419
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "upsert.where");
|
|
4385
4420
|
const upsertSchema2 = import_zod10.z.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4386
4421
|
return wrapRelationOp(true, upsertSchema2);
|
|
4387
4422
|
}
|
|
@@ -4392,7 +4427,7 @@ var handleUpsert = (ctx) => {
|
|
|
4392
4427
|
`upsert on to-one "${ctx.model}.${ctx.fieldName}" has invalid "where": must be a plain object of unique selectors`
|
|
4393
4428
|
);
|
|
4394
4429
|
}
|
|
4395
|
-
const whereSchema =
|
|
4430
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, cfg.where, "upsert.where");
|
|
4396
4431
|
const upsertSchema2 = import_zod10.z.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4397
4432
|
return upsertSchema2.optional();
|
|
4398
4433
|
}
|
|
@@ -4436,7 +4471,7 @@ var handleUpdateMany = (ctx) => {
|
|
|
4436
4471
|
ctx.typeMap,
|
|
4437
4472
|
ctx.schemaBuilder
|
|
4438
4473
|
);
|
|
4439
|
-
const dataSchema =
|
|
4474
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "update");
|
|
4440
4475
|
const umSchema = import_zod10.z.object({ where: whereSchema, data: dataSchema }).strict();
|
|
4441
4476
|
return wrapRelationOp(true, umSchema);
|
|
4442
4477
|
};
|
|
@@ -4483,17 +4518,21 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4483
4518
|
throw new ShapeError(
|
|
4484
4519
|
`Unknown related model "${relatedModelName}" for field "${model}.${fieldName}"`
|
|
4485
4520
|
);
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4521
|
+
assertAllowedKeys(
|
|
4522
|
+
config,
|
|
4523
|
+
KNOWN_RELATION_WRITE_OPS,
|
|
4524
|
+
(key) => `Unknown relation write operation "${key}" on "${model}.${fieldName}". Allowed: ${[...KNOWN_RELATION_WRITE_OPS].join(", ")}`
|
|
4525
|
+
);
|
|
4526
|
+
const definedEntries = Object.entries(config).filter(
|
|
4527
|
+
([, opConfig]) => opConfig !== void 0
|
|
4528
|
+
);
|
|
4529
|
+
if (definedEntries.length === 0) {
|
|
4530
|
+
throw new ShapeError(
|
|
4531
|
+
`Empty relation write config on "${model}.${fieldName}". Define at least one operation: ${[...KNOWN_RELATION_WRITE_OPS].join(", ")}`
|
|
4532
|
+
);
|
|
4492
4533
|
}
|
|
4493
4534
|
const opSchemas = {};
|
|
4494
|
-
for (const [op, opConfig] of
|
|
4495
|
-
if (opConfig === void 0)
|
|
4496
|
-
continue;
|
|
4535
|
+
for (const [op, opConfig] of definedEntries) {
|
|
4497
4536
|
const handler = RELATION_OP_HANDLERS[op];
|
|
4498
4537
|
opSchemas[op] = handler({
|
|
4499
4538
|
model,
|
|
@@ -4510,7 +4549,7 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4510
4549
|
}
|
|
4511
4550
|
return import_zod10.z.object(opSchemas).strict();
|
|
4512
4551
|
}
|
|
4513
|
-
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults) {
|
|
4552
|
+
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults, allowRelationWrites) {
|
|
4514
4553
|
const modelFields = typeMap[model];
|
|
4515
4554
|
if (!modelFields)
|
|
4516
4555
|
throw new ShapeError(`Unknown model: ${model}`);
|
|
@@ -4540,6 +4579,11 @@ function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, s
|
|
|
4540
4579
|
continue;
|
|
4541
4580
|
}
|
|
4542
4581
|
if (fieldMeta.isRelation) {
|
|
4582
|
+
if (!allowRelationWrites) {
|
|
4583
|
+
throw new ShapeError(
|
|
4584
|
+
`Field "${fieldName}" on model "${model}" is a relation. Relation writes are not supported for this method.`
|
|
4585
|
+
);
|
|
4586
|
+
}
|
|
4543
4587
|
if (!isPlainObject(value)) {
|
|
4544
4588
|
throw new ShapeError(
|
|
4545
4589
|
`Relation field "${fieldName}" on model "${model}" requires a relation write config object`
|
|
@@ -4653,13 +4697,8 @@ function validateAndMergeData(bodyData, cached, method, modelName) {
|
|
|
4653
4697
|
try {
|
|
4654
4698
|
validated = cached.schema.parse(bodyData);
|
|
4655
4699
|
} catch (err) {
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
if (err && typeof err === "object" && "issues" in err) {
|
|
4659
|
-
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4660
|
-
throw new ShapeError(`${context}: ${formatZodError(err)}`, { cause: err });
|
|
4661
|
-
}
|
|
4662
|
-
throw err;
|
|
4700
|
+
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4701
|
+
wrapParseError(err, context);
|
|
4663
4702
|
}
|
|
4664
4703
|
return { ...validated, ...deepClone(cached.forced) };
|
|
4665
4704
|
}
|
|
@@ -4814,6 +4853,8 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
4814
4853
|
"updateManyAndReturn"
|
|
4815
4854
|
]);
|
|
4816
4855
|
var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set(["createMany", "createManyAndReturn"]);
|
|
4856
|
+
var RELATION_WRITE_CREATE_METHODS = /* @__PURE__ */ new Set(["create"]);
|
|
4857
|
+
var RELATION_WRITE_UPDATE_METHODS = /* @__PURE__ */ new Set(["update"]);
|
|
4817
4858
|
var MAX_PROJECTION_WALK_DEPTH = 10;
|
|
4818
4859
|
function walkForClientContent(obj, predicate, depth) {
|
|
4819
4860
|
if (depth > MAX_PROJECTION_WALK_DEPTH)
|
|
@@ -4964,11 +5005,11 @@ function createModelGuardExtension(config) {
|
|
|
4964
5005
|
)
|
|
4965
5006
|
);
|
|
4966
5007
|
}
|
|
4967
|
-
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
|
|
5008
|
+
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic, allowRelationWrites) {
|
|
4968
5009
|
const skipCache = wasDynamic || hasDataRefines(dataConfig);
|
|
4969
5010
|
return memoize(
|
|
4970
5011
|
dataSchemaCache,
|
|
4971
|
-
`${mode}\0${matchedKey}`,
|
|
5012
|
+
`${mode}\0${matchedKey}\0${allowRelationWrites ? "r" : "n"}`,
|
|
4972
5013
|
skipCache,
|
|
4973
5014
|
() => buildDataSchema(
|
|
4974
5015
|
modelName,
|
|
@@ -4979,7 +5020,8 @@ function createModelGuardExtension(config) {
|
|
|
4979
5020
|
enumMap,
|
|
4980
5021
|
scalarBase,
|
|
4981
5022
|
schemaBuilder,
|
|
4982
|
-
zodDefaults
|
|
5023
|
+
zodDefaults,
|
|
5024
|
+
allowRelationWrites
|
|
4983
5025
|
)
|
|
4984
5026
|
);
|
|
4985
5027
|
}
|
|
@@ -5237,6 +5279,39 @@ function createModelGuardExtension(config) {
|
|
|
5237
5279
|
const defaultProjection = buildDefaultProjectionBody(resolved.shape);
|
|
5238
5280
|
return { ...resolved.body, ...defaultProjection };
|
|
5239
5281
|
}
|
|
5282
|
+
function makeResolveMethod() {
|
|
5283
|
+
const WRITE_KEYS = ["data", "create", "update"];
|
|
5284
|
+
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
|
|
5285
|
+
return (body) => {
|
|
5286
|
+
const caller = resolveCaller();
|
|
5287
|
+
const resolved = resolveShape(input, body, contextFn, caller);
|
|
5288
|
+
for (const key of WRITE_KEYS) {
|
|
5289
|
+
if (hasOwn(resolved.shape, key)) {
|
|
5290
|
+
throw new ShapeError(
|
|
5291
|
+
`.resolve() is a read-only planning helper. Guard shape contains write key "${key}". Use the corresponding write method instead.`
|
|
5292
|
+
);
|
|
5293
|
+
}
|
|
5294
|
+
}
|
|
5295
|
+
for (const key of WRITE_KEYS) {
|
|
5296
|
+
if (hasOwn(resolved.body, key)) {
|
|
5297
|
+
throw new ShapeError(
|
|
5298
|
+
`.resolve() is a read-only planning helper. Request body contains write key "${key}".`
|
|
5299
|
+
);
|
|
5300
|
+
}
|
|
5301
|
+
}
|
|
5302
|
+
const effectiveReadBody = buildEffectiveReadBody({
|
|
5303
|
+
shape: resolved.shape,
|
|
5304
|
+
body: resolved.body
|
|
5305
|
+
});
|
|
5306
|
+
return {
|
|
5307
|
+
shape: resolved.shape,
|
|
5308
|
+
body: resolved.body,
|
|
5309
|
+
effectiveReadBody,
|
|
5310
|
+
matchedKey: resolved.matchedKey,
|
|
5311
|
+
wasDynamic: resolved.wasDynamic
|
|
5312
|
+
};
|
|
5313
|
+
};
|
|
5314
|
+
}
|
|
5240
5315
|
function makeReadMethod(method) {
|
|
5241
5316
|
return (body) => {
|
|
5242
5317
|
const caller = resolveCaller();
|
|
@@ -5270,6 +5345,7 @@ function createModelGuardExtension(config) {
|
|
|
5270
5345
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5271
5346
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5272
5347
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5348
|
+
const allowRelationWrites = RELATION_WRITE_CREATE_METHODS.has(method);
|
|
5273
5349
|
return (body) => {
|
|
5274
5350
|
const caller = resolveCaller();
|
|
5275
5351
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5295,7 +5371,8 @@ function createModelGuardExtension(config) {
|
|
|
5295
5371
|
"create",
|
|
5296
5372
|
resolved.shape.data,
|
|
5297
5373
|
resolved.matchedKey,
|
|
5298
|
-
resolved.wasDynamic
|
|
5374
|
+
resolved.wasDynamic,
|
|
5375
|
+
allowRelationWrites
|
|
5299
5376
|
);
|
|
5300
5377
|
let args;
|
|
5301
5378
|
if (method === "create") {
|
|
@@ -5343,6 +5420,7 @@ function createModelGuardExtension(config) {
|
|
|
5343
5420
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5344
5421
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5345
5422
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5423
|
+
const allowRelationWrites = RELATION_WRITE_UPDATE_METHODS.has(method);
|
|
5346
5424
|
return (body) => {
|
|
5347
5425
|
const caller = resolveCaller();
|
|
5348
5426
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5365,7 +5443,8 @@ function createModelGuardExtension(config) {
|
|
|
5365
5443
|
"update",
|
|
5366
5444
|
resolved.shape.data,
|
|
5367
5445
|
resolved.matchedKey,
|
|
5368
|
-
resolved.wasDynamic
|
|
5446
|
+
resolved.wasDynamic,
|
|
5447
|
+
allowRelationWrites
|
|
5369
5448
|
);
|
|
5370
5449
|
const data = validateAndMergeData(
|
|
5371
5450
|
resolved.body.data,
|
|
@@ -5538,7 +5617,8 @@ function createModelGuardExtension(config) {
|
|
|
5538
5617
|
"create",
|
|
5539
5618
|
resolved.shape.create,
|
|
5540
5619
|
`upsert:create\0${resolved.matchedKey}`,
|
|
5541
|
-
resolved.wasDynamic
|
|
5620
|
+
resolved.wasDynamic,
|
|
5621
|
+
true
|
|
5542
5622
|
);
|
|
5543
5623
|
const createData = validateAndMergeData(
|
|
5544
5624
|
resolved.body.create,
|
|
@@ -5550,7 +5630,8 @@ function createModelGuardExtension(config) {
|
|
|
5550
5630
|
"update",
|
|
5551
5631
|
resolved.shape.update,
|
|
5552
5632
|
`upsert:update\0${resolved.matchedKey}`,
|
|
5553
|
-
resolved.wasDynamic
|
|
5633
|
+
resolved.wasDynamic,
|
|
5634
|
+
true
|
|
5554
5635
|
);
|
|
5555
5636
|
const updateData = validateAndMergeData(
|
|
5556
5637
|
resolved.body.update,
|
|
@@ -5583,6 +5664,7 @@ function createModelGuardExtension(config) {
|
|
|
5583
5664
|
};
|
|
5584
5665
|
}
|
|
5585
5666
|
return {
|
|
5667
|
+
resolve: makeResolveMethod(),
|
|
5586
5668
|
findMany: makeReadMethod("findMany"),
|
|
5587
5669
|
findFirst: makeReadMethod("findFirst"),
|
|
5588
5670
|
findFirstOrThrow: makeReadMethod("findFirstOrThrow"),
|