prisma-guard 1.28.1 → 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 +42 -33
- package/dist/generator/index.js.map +1 -1
- package/dist/runtime/index.cjs +257 -176
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +11 -2
- package/dist/runtime/index.d.ts +11 -2
- package/dist/runtime/index.js +257 -176
- 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,7 +2943,12 @@ 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
|
|
@@ -2924,10 +2964,10 @@ var OPERATION_SHAPE_KEYS = {
|
|
|
2924
2964
|
groupBy: ["where", "orderBy", "by", "having", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
|
|
2925
2965
|
create: ["data", "include", "select"],
|
|
2926
2966
|
createMany: ["data", "skipDuplicates"],
|
|
2927
|
-
createManyAndReturn: ["data", "select", "skipDuplicates"],
|
|
2967
|
+
createManyAndReturn: ["data", "select", "include", "skipDuplicates"],
|
|
2928
2968
|
update: ["where", "data", "include", "select"],
|
|
2929
2969
|
updateMany: ["where", "data"],
|
|
2930
|
-
updateManyAndReturn: ["where", "data", "select"],
|
|
2970
|
+
updateManyAndReturn: ["where", "data", "select", "include"],
|
|
2931
2971
|
upsert: ["where", "create", "update", "include", "select"],
|
|
2932
2972
|
delete: ["where", "include", "select"],
|
|
2933
2973
|
deleteMany: ["where"]
|
|
@@ -3241,7 +3281,17 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
3241
3281
|
let forcedIncludeCountWhere = {};
|
|
3242
3282
|
let forcedSelectCountWhere = {};
|
|
3243
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
|
+
}
|
|
3244
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
|
+
}
|
|
3245
3295
|
if (builtWhere.schema) {
|
|
3246
3296
|
schemaFields.where = builtWhere.schema;
|
|
3247
3297
|
}
|
|
@@ -4043,27 +4093,19 @@ function validateRelationOpKeys(actual, opKey, model, field, opLabel) {
|
|
|
4043
4093
|
const allowed = RELATION_OP_ALLOWED_KEYS[opKey];
|
|
4044
4094
|
if (!allowed)
|
|
4045
4095
|
return;
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4050
|
-
|
|
4051
|
-
}
|
|
4052
|
-
}
|
|
4096
|
+
assertAllowedKeys(
|
|
4097
|
+
actual,
|
|
4098
|
+
allowed,
|
|
4099
|
+
(key) => `Unknown key "${key}" in ${opLabel} config on "${model}.${field}". Allowed: ${[...allowed].join(", ")}`
|
|
4100
|
+
);
|
|
4053
4101
|
}
|
|
4054
4102
|
function validateAllowedKeys(value, allowed, method, kind) {
|
|
4055
|
-
|
|
4056
|
-
if (
|
|
4057
|
-
|
|
4058
|
-
throw new ShapeError(
|
|
4059
|
-
`Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`
|
|
4060
|
-
);
|
|
4061
|
-
}
|
|
4062
|
-
throw new ShapeError(
|
|
4063
|
-
`Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`
|
|
4064
|
-
);
|
|
4103
|
+
assertAllowedKeys(value, allowed, (key) => {
|
|
4104
|
+
if (kind === "body") {
|
|
4105
|
+
return `Unexpected key "${key}" in ${method} body. Allowed keys: ${[...allowed].join(", ")}`;
|
|
4065
4106
|
}
|
|
4066
|
-
|
|
4107
|
+
return `Shape key "${key}" not valid for ${method}. Allowed: ${[...allowed].join(", ")}`;
|
|
4108
|
+
});
|
|
4067
4109
|
}
|
|
4068
4110
|
function validateCreateCompleteness(modelName, dataConfig, typeMap, scopeFks, zodDefaults) {
|
|
4069
4111
|
const modelFields = typeMap[modelName];
|
|
@@ -4150,18 +4192,10 @@ function buildNestedDataSchema(model, config, mode, typeMap, schemaBuilder) {
|
|
|
4150
4192
|
}
|
|
4151
4193
|
return z10.object(fieldSchemas).strict();
|
|
4152
4194
|
}
|
|
4153
|
-
function requirePlainObjectConfig(value, message) {
|
|
4154
|
-
if (!isPlainObject(value))
|
|
4155
|
-
throw new ShapeError(message);
|
|
4156
|
-
return value;
|
|
4157
|
-
}
|
|
4158
4195
|
function requireNestedObject(cfg, key, message) {
|
|
4159
|
-
|
|
4160
|
-
if (!v || !isPlainObject(v))
|
|
4161
|
-
throw new ShapeError(message);
|
|
4162
|
-
return v;
|
|
4196
|
+
return requirePlainObjectConfig(cfg[key], message);
|
|
4163
4197
|
}
|
|
4164
|
-
function
|
|
4198
|
+
function buildRelatedUniqueSelector(ctx, cfg, context) {
|
|
4165
4199
|
return buildUniqueSelectorSchema(
|
|
4166
4200
|
ctx.model,
|
|
4167
4201
|
ctx.fieldName,
|
|
@@ -4174,7 +4208,7 @@ function buildUniqueSelector(ctx, cfg, context) {
|
|
|
4174
4208
|
context
|
|
4175
4209
|
);
|
|
4176
4210
|
}
|
|
4177
|
-
function
|
|
4211
|
+
function buildRelatedNestedData(ctx, cfg, mode) {
|
|
4178
4212
|
return buildNestedDataSchema(
|
|
4179
4213
|
ctx.relatedModelName,
|
|
4180
4214
|
cfg,
|
|
@@ -4188,7 +4222,7 @@ var handleConnect = (ctx) => {
|
|
|
4188
4222
|
ctx.config,
|
|
4189
4223
|
`connect config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4190
4224
|
);
|
|
4191
|
-
const schema =
|
|
4225
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "connect");
|
|
4192
4226
|
return wrapRelationOp(ctx.isList, schema);
|
|
4193
4227
|
};
|
|
4194
4228
|
var handleConnectOrCreate = (ctx) => {
|
|
@@ -4207,8 +4241,8 @@ var handleConnectOrCreate = (ctx) => {
|
|
|
4207
4241
|
"create",
|
|
4208
4242
|
`connectOrCreate on "${ctx.model}.${ctx.fieldName}" requires "create" object`
|
|
4209
4243
|
);
|
|
4210
|
-
const whereSchema =
|
|
4211
|
-
const createSchema =
|
|
4244
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "connectOrCreate.where");
|
|
4245
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4212
4246
|
const cocSchema = z10.object({ where: whereSchema, create: createSchema }).strict();
|
|
4213
4247
|
return wrapRelationOp(ctx.isList, cocSchema);
|
|
4214
4248
|
};
|
|
@@ -4217,7 +4251,7 @@ var handleCreate = (ctx) => {
|
|
|
4217
4251
|
ctx.config,
|
|
4218
4252
|
`create config on "${ctx.model}.${ctx.fieldName}" must be an object of field names`
|
|
4219
4253
|
);
|
|
4220
|
-
const createSchema =
|
|
4254
|
+
const createSchema = buildRelatedNestedData(ctx, cfg, "create");
|
|
4221
4255
|
return wrapRelationOp(ctx.isList, createSchema);
|
|
4222
4256
|
};
|
|
4223
4257
|
var handleCreateMany = (ctx) => {
|
|
@@ -4236,7 +4270,7 @@ var handleCreateMany = (ctx) => {
|
|
|
4236
4270
|
"data",
|
|
4237
4271
|
`createMany on "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4238
4272
|
);
|
|
4239
|
-
const dataSchema =
|
|
4273
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "create");
|
|
4240
4274
|
const cmSchemaFields = {
|
|
4241
4275
|
data: z10.preprocess(coerceToArray, z10.array(dataSchema))
|
|
4242
4276
|
};
|
|
@@ -4259,7 +4293,7 @@ var handleDisconnect = (ctx) => {
|
|
|
4259
4293
|
`disconnect config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4260
4294
|
);
|
|
4261
4295
|
}
|
|
4262
|
-
const schema =
|
|
4296
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "disconnect");
|
|
4263
4297
|
if (ctx.isList)
|
|
4264
4298
|
return wrapRelationOp(true, schema);
|
|
4265
4299
|
return z10.union([z10.literal(true), schema]).optional();
|
|
@@ -4278,7 +4312,7 @@ var handleDelete = (ctx) => {
|
|
|
4278
4312
|
`delete config on "${ctx.model}.${ctx.fieldName}" must be true (to-one) or an object of unique selectors`
|
|
4279
4313
|
);
|
|
4280
4314
|
}
|
|
4281
|
-
const schema =
|
|
4315
|
+
const schema = buildRelatedUniqueSelector(ctx, ctx.config, "delete");
|
|
4282
4316
|
if (ctx.isList)
|
|
4283
4317
|
return wrapRelationOp(true, schema);
|
|
4284
4318
|
return z10.union([z10.literal(true), schema]).optional();
|
|
@@ -4293,7 +4327,7 @@ var handleSet = (ctx) => {
|
|
|
4293
4327
|
ctx.config,
|
|
4294
4328
|
`set config on "${ctx.model}.${ctx.fieldName}" must be an object of unique selectors`
|
|
4295
4329
|
);
|
|
4296
|
-
const schema =
|
|
4330
|
+
const schema = buildRelatedUniqueSelector(ctx, cfg, "set");
|
|
4297
4331
|
return wrapRelationOp(true, schema);
|
|
4298
4332
|
};
|
|
4299
4333
|
var handleUpdate = (ctx) => {
|
|
@@ -4313,12 +4347,12 @@ var handleUpdate = (ctx) => {
|
|
|
4313
4347
|
"data",
|
|
4314
4348
|
`update on to-many "${ctx.model}.${ctx.fieldName}" requires "data" object`
|
|
4315
4349
|
);
|
|
4316
|
-
const whereSchema =
|
|
4317
|
-
const dataSchema2 =
|
|
4350
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "update.where");
|
|
4351
|
+
const dataSchema2 = buildRelatedNestedData(ctx, data, "update");
|
|
4318
4352
|
const updateSchema = z10.object({ where: whereSchema, data: dataSchema2 }).strict();
|
|
4319
4353
|
return wrapRelationOp(true, updateSchema);
|
|
4320
4354
|
}
|
|
4321
|
-
const dataSchema =
|
|
4355
|
+
const dataSchema = buildRelatedNestedData(ctx, cfg, "update");
|
|
4322
4356
|
return dataSchema.optional();
|
|
4323
4357
|
};
|
|
4324
4358
|
var handleUpsert = (ctx) => {
|
|
@@ -4343,15 +4377,15 @@ var handleUpsert = (ctx) => {
|
|
|
4343
4377
|
"update",
|
|
4344
4378
|
`upsert on "${ctx.model}.${ctx.fieldName}" requires "update" object`
|
|
4345
4379
|
);
|
|
4346
|
-
const createSchema =
|
|
4347
|
-
const updateSchema =
|
|
4380
|
+
const createSchema = buildRelatedNestedData(ctx, create, "create");
|
|
4381
|
+
const updateSchema = buildRelatedNestedData(ctx, update, "update");
|
|
4348
4382
|
if (ctx.isList) {
|
|
4349
4383
|
const where = requireNestedObject(
|
|
4350
4384
|
cfg,
|
|
4351
4385
|
"where",
|
|
4352
4386
|
`upsert on to-many "${ctx.model}.${ctx.fieldName}" requires "where" object`
|
|
4353
4387
|
);
|
|
4354
|
-
const whereSchema =
|
|
4388
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, where, "upsert.where");
|
|
4355
4389
|
const upsertSchema2 = z10.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4356
4390
|
return wrapRelationOp(true, upsertSchema2);
|
|
4357
4391
|
}
|
|
@@ -4362,7 +4396,7 @@ var handleUpsert = (ctx) => {
|
|
|
4362
4396
|
`upsert on to-one "${ctx.model}.${ctx.fieldName}" has invalid "where": must be a plain object of unique selectors`
|
|
4363
4397
|
);
|
|
4364
4398
|
}
|
|
4365
|
-
const whereSchema =
|
|
4399
|
+
const whereSchema = buildRelatedUniqueSelector(ctx, cfg.where, "upsert.where");
|
|
4366
4400
|
const upsertSchema2 = z10.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
4367
4401
|
return upsertSchema2.optional();
|
|
4368
4402
|
}
|
|
@@ -4406,7 +4440,7 @@ var handleUpdateMany = (ctx) => {
|
|
|
4406
4440
|
ctx.typeMap,
|
|
4407
4441
|
ctx.schemaBuilder
|
|
4408
4442
|
);
|
|
4409
|
-
const dataSchema =
|
|
4443
|
+
const dataSchema = buildRelatedNestedData(ctx, data, "update");
|
|
4410
4444
|
const umSchema = z10.object({ where: whereSchema, data: dataSchema }).strict();
|
|
4411
4445
|
return wrapRelationOp(true, umSchema);
|
|
4412
4446
|
};
|
|
@@ -4453,17 +4487,21 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4453
4487
|
throw new ShapeError(
|
|
4454
4488
|
`Unknown related model "${relatedModelName}" for field "${model}.${fieldName}"`
|
|
4455
4489
|
);
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
4459
|
-
|
|
4460
|
-
|
|
4461
|
-
|
|
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
|
+
);
|
|
4462
4502
|
}
|
|
4463
4503
|
const opSchemas = {};
|
|
4464
|
-
for (const [op, opConfig] of
|
|
4465
|
-
if (opConfig === void 0)
|
|
4466
|
-
continue;
|
|
4504
|
+
for (const [op, opConfig] of definedEntries) {
|
|
4467
4505
|
const handler = RELATION_OP_HANDLERS[op];
|
|
4468
4506
|
opSchemas[op] = handler({
|
|
4469
4507
|
model,
|
|
@@ -4480,7 +4518,7 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
4480
4518
|
}
|
|
4481
4519
|
return z10.object(opSchemas).strict();
|
|
4482
4520
|
}
|
|
4483
|
-
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults) {
|
|
4521
|
+
function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, scalarBase, schemaBuilder, zodDefaults, allowRelationWrites) {
|
|
4484
4522
|
const modelFields = typeMap[model];
|
|
4485
4523
|
if (!modelFields)
|
|
4486
4524
|
throw new ShapeError(`Unknown model: ${model}`);
|
|
@@ -4510,6 +4548,11 @@ function buildDataSchema(model, dataConfig, mode, typeMap, uniqueMap, enumMap, s
|
|
|
4510
4548
|
continue;
|
|
4511
4549
|
}
|
|
4512
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
|
+
}
|
|
4513
4556
|
if (!isPlainObject(value)) {
|
|
4514
4557
|
throw new ShapeError(
|
|
4515
4558
|
`Relation field "${fieldName}" on model "${model}" requires a relation write config object`
|
|
@@ -4623,13 +4666,8 @@ function validateAndMergeData(bodyData, cached, method, modelName) {
|
|
|
4623
4666
|
try {
|
|
4624
4667
|
validated = cached.schema.parse(bodyData);
|
|
4625
4668
|
} catch (err) {
|
|
4626
|
-
|
|
4627
|
-
|
|
4628
|
-
if (err && typeof err === "object" && "issues" in err) {
|
|
4629
|
-
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4630
|
-
throw new ShapeError(`${context}: ${formatZodError(err)}`, { cause: err });
|
|
4631
|
-
}
|
|
4632
|
-
throw err;
|
|
4669
|
+
const context = modelName ? `Invalid data for ${method} on model "${modelName}"` : `Invalid data for ${method}`;
|
|
4670
|
+
wrapParseError(err, context);
|
|
4633
4671
|
}
|
|
4634
4672
|
return { ...validated, ...deepClone(cached.forced) };
|
|
4635
4673
|
}
|
|
@@ -4784,6 +4822,8 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
4784
4822
|
"updateManyAndReturn"
|
|
4785
4823
|
]);
|
|
4786
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"]);
|
|
4787
4827
|
var MAX_PROJECTION_WALK_DEPTH = 10;
|
|
4788
4828
|
function walkForClientContent(obj, predicate, depth) {
|
|
4789
4829
|
if (depth > MAX_PROJECTION_WALK_DEPTH)
|
|
@@ -4934,11 +4974,11 @@ function createModelGuardExtension(config) {
|
|
|
4934
4974
|
)
|
|
4935
4975
|
);
|
|
4936
4976
|
}
|
|
4937
|
-
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
|
|
4977
|
+
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic, allowRelationWrites) {
|
|
4938
4978
|
const skipCache = wasDynamic || hasDataRefines(dataConfig);
|
|
4939
4979
|
return memoize(
|
|
4940
4980
|
dataSchemaCache,
|
|
4941
|
-
`${mode}\0${matchedKey}`,
|
|
4981
|
+
`${mode}\0${matchedKey}\0${allowRelationWrites ? "r" : "n"}`,
|
|
4942
4982
|
skipCache,
|
|
4943
4983
|
() => buildDataSchema(
|
|
4944
4984
|
modelName,
|
|
@@ -4949,7 +4989,8 @@ function createModelGuardExtension(config) {
|
|
|
4949
4989
|
enumMap,
|
|
4950
4990
|
scalarBase,
|
|
4951
4991
|
schemaBuilder,
|
|
4952
|
-
zodDefaults
|
|
4992
|
+
zodDefaults,
|
|
4993
|
+
allowRelationWrites
|
|
4953
4994
|
)
|
|
4954
4995
|
);
|
|
4955
4996
|
}
|
|
@@ -5207,6 +5248,39 @@ function createModelGuardExtension(config) {
|
|
|
5207
5248
|
const defaultProjection = buildDefaultProjectionBody(resolved.shape);
|
|
5208
5249
|
return { ...resolved.body, ...defaultProjection };
|
|
5209
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
|
+
}
|
|
5210
5284
|
function makeReadMethod(method) {
|
|
5211
5285
|
return (body) => {
|
|
5212
5286
|
const caller = resolveCaller();
|
|
@@ -5240,6 +5314,7 @@ function createModelGuardExtension(config) {
|
|
|
5240
5314
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5241
5315
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5242
5316
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5317
|
+
const allowRelationWrites = RELATION_WRITE_CREATE_METHODS.has(method);
|
|
5243
5318
|
return (body) => {
|
|
5244
5319
|
const caller = resolveCaller();
|
|
5245
5320
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5265,7 +5340,8 @@ function createModelGuardExtension(config) {
|
|
|
5265
5340
|
"create",
|
|
5266
5341
|
resolved.shape.data,
|
|
5267
5342
|
resolved.matchedKey,
|
|
5268
|
-
resolved.wasDynamic
|
|
5343
|
+
resolved.wasDynamic,
|
|
5344
|
+
allowRelationWrites
|
|
5269
5345
|
);
|
|
5270
5346
|
let args;
|
|
5271
5347
|
if (method === "create") {
|
|
@@ -5313,6 +5389,7 @@ function createModelGuardExtension(config) {
|
|
|
5313
5389
|
const supportsProjection = PROJECTION_MUTATION_METHODS.has(method);
|
|
5314
5390
|
const allowedBodyKeys = getAllowedBodyKeys(method, supportsProjection);
|
|
5315
5391
|
const allowedShapeKeys = getAllowedShapeKeys(method, supportsProjection);
|
|
5392
|
+
const allowRelationWrites = RELATION_WRITE_UPDATE_METHODS.has(method);
|
|
5316
5393
|
return (body) => {
|
|
5317
5394
|
const caller = resolveCaller();
|
|
5318
5395
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
@@ -5335,7 +5412,8 @@ function createModelGuardExtension(config) {
|
|
|
5335
5412
|
"update",
|
|
5336
5413
|
resolved.shape.data,
|
|
5337
5414
|
resolved.matchedKey,
|
|
5338
|
-
resolved.wasDynamic
|
|
5415
|
+
resolved.wasDynamic,
|
|
5416
|
+
allowRelationWrites
|
|
5339
5417
|
);
|
|
5340
5418
|
const data = validateAndMergeData(
|
|
5341
5419
|
resolved.body.data,
|
|
@@ -5508,7 +5586,8 @@ function createModelGuardExtension(config) {
|
|
|
5508
5586
|
"create",
|
|
5509
5587
|
resolved.shape.create,
|
|
5510
5588
|
`upsert:create\0${resolved.matchedKey}`,
|
|
5511
|
-
resolved.wasDynamic
|
|
5589
|
+
resolved.wasDynamic,
|
|
5590
|
+
true
|
|
5512
5591
|
);
|
|
5513
5592
|
const createData = validateAndMergeData(
|
|
5514
5593
|
resolved.body.create,
|
|
@@ -5520,7 +5599,8 @@ function createModelGuardExtension(config) {
|
|
|
5520
5599
|
"update",
|
|
5521
5600
|
resolved.shape.update,
|
|
5522
5601
|
`upsert:update\0${resolved.matchedKey}`,
|
|
5523
|
-
resolved.wasDynamic
|
|
5602
|
+
resolved.wasDynamic,
|
|
5603
|
+
true
|
|
5524
5604
|
);
|
|
5525
5605
|
const updateData = validateAndMergeData(
|
|
5526
5606
|
resolved.body.update,
|
|
@@ -5553,6 +5633,7 @@ function createModelGuardExtension(config) {
|
|
|
5553
5633
|
};
|
|
5554
5634
|
}
|
|
5555
5635
|
return {
|
|
5636
|
+
resolve: makeResolveMethod(),
|
|
5556
5637
|
findMany: makeReadMethod("findMany"),
|
|
5557
5638
|
findFirst: makeReadMethod("findFirst"),
|
|
5558
5639
|
findFirstOrThrow: makeReadMethod("findFirstOrThrow"),
|