prisma-guard 1.12.0 → 1.13.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/dist/runtime/index.cjs +374 -109
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +374 -109
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -2813,21 +2813,67 @@ import { z as z9 } from "zod";
|
|
|
2813
2813
|
// src/runtime/model-guard-data.ts
|
|
2814
2814
|
import { z as z8 } from "zod";
|
|
2815
2815
|
var ALLOWED_BODY_KEYS_CREATE = /* @__PURE__ */ new Set(["data"]);
|
|
2816
|
-
var ALLOWED_BODY_KEYS_CREATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2817
|
-
|
|
2818
|
-
|
|
2816
|
+
var ALLOWED_BODY_KEYS_CREATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2817
|
+
"data",
|
|
2818
|
+
"select",
|
|
2819
|
+
"include"
|
|
2820
|
+
]);
|
|
2821
|
+
var ALLOWED_BODY_KEYS_CREATE_MANY = /* @__PURE__ */ new Set([
|
|
2822
|
+
"data",
|
|
2823
|
+
"skipDuplicates"
|
|
2824
|
+
]);
|
|
2825
|
+
var ALLOWED_BODY_KEYS_CREATE_MANY_PROJECTION = /* @__PURE__ */ new Set([
|
|
2826
|
+
"data",
|
|
2827
|
+
"select",
|
|
2828
|
+
"include",
|
|
2829
|
+
"skipDuplicates"
|
|
2830
|
+
]);
|
|
2819
2831
|
var ALLOWED_BODY_KEYS_UPDATE = /* @__PURE__ */ new Set(["data", "where"]);
|
|
2820
|
-
var ALLOWED_BODY_KEYS_UPDATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2832
|
+
var ALLOWED_BODY_KEYS_UPDATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2833
|
+
"data",
|
|
2834
|
+
"where",
|
|
2835
|
+
"select",
|
|
2836
|
+
"include"
|
|
2837
|
+
]);
|
|
2821
2838
|
var ALLOWED_BODY_KEYS_DELETE = /* @__PURE__ */ new Set(["where"]);
|
|
2822
|
-
var ALLOWED_BODY_KEYS_DELETE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2823
|
-
|
|
2839
|
+
var ALLOWED_BODY_KEYS_DELETE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2840
|
+
"where",
|
|
2841
|
+
"select",
|
|
2842
|
+
"include"
|
|
2843
|
+
]);
|
|
2844
|
+
var ALLOWED_BODY_KEYS_UPSERT = /* @__PURE__ */ new Set([
|
|
2845
|
+
"where",
|
|
2846
|
+
"create",
|
|
2847
|
+
"update",
|
|
2848
|
+
"select",
|
|
2849
|
+
"include"
|
|
2850
|
+
]);
|
|
2824
2851
|
var VALID_SHAPE_KEYS_CREATE = /* @__PURE__ */ new Set(["data"]);
|
|
2825
|
-
var VALID_SHAPE_KEYS_CREATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2852
|
+
var VALID_SHAPE_KEYS_CREATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2853
|
+
"data",
|
|
2854
|
+
"select",
|
|
2855
|
+
"include"
|
|
2856
|
+
]);
|
|
2826
2857
|
var VALID_SHAPE_KEYS_UPDATE = /* @__PURE__ */ new Set(["data", "where"]);
|
|
2827
|
-
var VALID_SHAPE_KEYS_UPDATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2858
|
+
var VALID_SHAPE_KEYS_UPDATE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2859
|
+
"data",
|
|
2860
|
+
"where",
|
|
2861
|
+
"select",
|
|
2862
|
+
"include"
|
|
2863
|
+
]);
|
|
2828
2864
|
var VALID_SHAPE_KEYS_DELETE = /* @__PURE__ */ new Set(["where"]);
|
|
2829
|
-
var VALID_SHAPE_KEYS_DELETE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2830
|
-
|
|
2865
|
+
var VALID_SHAPE_KEYS_DELETE_PROJECTION = /* @__PURE__ */ new Set([
|
|
2866
|
+
"where",
|
|
2867
|
+
"select",
|
|
2868
|
+
"include"
|
|
2869
|
+
]);
|
|
2870
|
+
var VALID_SHAPE_KEYS_UPSERT = /* @__PURE__ */ new Set([
|
|
2871
|
+
"where",
|
|
2872
|
+
"create",
|
|
2873
|
+
"update",
|
|
2874
|
+
"select",
|
|
2875
|
+
"include"
|
|
2876
|
+
]);
|
|
2831
2877
|
var KNOWN_RELATION_WRITE_OPS = /* @__PURE__ */ new Set([
|
|
2832
2878
|
"connect",
|
|
2833
2879
|
"connectOrCreate",
|
|
@@ -2865,26 +2911,6 @@ function validateCreateCompleteness(modelName, dataConfig, typeMap, scopeFks, zo
|
|
|
2865
2911
|
return;
|
|
2866
2912
|
const zodDefaultFields = zodDefaults[modelName];
|
|
2867
2913
|
const zodDefaultSet = zodDefaultFields ? new Set(zodDefaultFields) : void 0;
|
|
2868
|
-
const relationFksCoveredByShape = /* @__PURE__ */ new Set();
|
|
2869
|
-
for (const [fieldName, value] of Object.entries(dataConfig)) {
|
|
2870
|
-
const meta = modelFields[fieldName];
|
|
2871
|
-
if (!meta)
|
|
2872
|
-
continue;
|
|
2873
|
-
if (meta.isRelation && isPlainObject(value)) {
|
|
2874
|
-
const relConfig = value;
|
|
2875
|
-
if (relConfig.connect || relConfig.connectOrCreate || relConfig.create) {
|
|
2876
|
-
const fkFields = Object.keys(modelFields).filter((f) => {
|
|
2877
|
-
const fm = modelFields[f];
|
|
2878
|
-
return !fm.isRelation && fieldName !== f;
|
|
2879
|
-
});
|
|
2880
|
-
for (const fk of Object.keys(modelFields)) {
|
|
2881
|
-
const fm = modelFields[fk];
|
|
2882
|
-
if (fm.isRelation)
|
|
2883
|
-
continue;
|
|
2884
|
-
}
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
}
|
|
2888
2914
|
for (const [fieldName, meta] of Object.entries(modelFields)) {
|
|
2889
2915
|
if (meta.isRelation)
|
|
2890
2916
|
continue;
|
|
@@ -2900,17 +2926,6 @@ function validateCreateCompleteness(modelName, dataConfig, typeMap, scopeFks, zo
|
|
|
2900
2926
|
continue;
|
|
2901
2927
|
if (zodDefaultSet && zodDefaultSet.has(fieldName))
|
|
2902
2928
|
continue;
|
|
2903
|
-
const coveredByRelation = Object.entries(dataConfig).some(([shapeName, shapeVal]) => {
|
|
2904
|
-
const shapeMeta = modelFields[shapeName];
|
|
2905
|
-
if (!shapeMeta || !shapeMeta.isRelation)
|
|
2906
|
-
return false;
|
|
2907
|
-
if (!isPlainObject(shapeVal))
|
|
2908
|
-
return false;
|
|
2909
|
-
const relConfig = shapeVal;
|
|
2910
|
-
return !!(relConfig.connect || relConfig.connectOrCreate || relConfig.create);
|
|
2911
|
-
});
|
|
2912
|
-
if (coveredByRelation)
|
|
2913
|
-
continue;
|
|
2914
2929
|
throw new ShapeError(
|
|
2915
2930
|
`Required field "${fieldName}" on model "${modelName}" is missing from create data shape, has no default, and is not a scope FK`
|
|
2916
2931
|
);
|
|
@@ -2921,17 +2936,26 @@ function buildWhereFieldsSchema(model, config, typeMap, schemaBuilder) {
|
|
|
2921
2936
|
if (!modelFields)
|
|
2922
2937
|
throw new ShapeError(`Unknown model: ${model}`);
|
|
2923
2938
|
const fieldSchemas = {};
|
|
2939
|
+
const fieldKeys = [];
|
|
2924
2940
|
for (const [fieldName, value] of Object.entries(config)) {
|
|
2925
2941
|
if (value !== true)
|
|
2926
|
-
throw new ShapeError(
|
|
2942
|
+
throw new ShapeError(
|
|
2943
|
+
`Field "${fieldName}" in connect/where config must be true`
|
|
2944
|
+
);
|
|
2927
2945
|
const meta = modelFields[fieldName];
|
|
2928
2946
|
if (!meta)
|
|
2929
2947
|
throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
|
|
2930
2948
|
if (meta.isRelation)
|
|
2931
|
-
throw new ShapeError(
|
|
2949
|
+
throw new ShapeError(
|
|
2950
|
+
`Relation field "${fieldName}" cannot be used in connect/where`
|
|
2951
|
+
);
|
|
2932
2952
|
fieldSchemas[fieldName] = schemaBuilder.buildFieldSchema(model, fieldName).optional();
|
|
2953
|
+
fieldKeys.push(fieldName);
|
|
2933
2954
|
}
|
|
2934
|
-
return z8.object(fieldSchemas).strict()
|
|
2955
|
+
return z8.object(fieldSchemas).strict().refine(
|
|
2956
|
+
(v) => fieldKeys.some((k) => v[k] !== void 0),
|
|
2957
|
+
{ message: `At least one field required in connect/where` }
|
|
2958
|
+
);
|
|
2935
2959
|
}
|
|
2936
2960
|
function buildNestedDataSchema(model, config, typeMap, schemaBuilder) {
|
|
2937
2961
|
const modelFields = typeMap[model];
|
|
@@ -2940,14 +2964,20 @@ function buildNestedDataSchema(model, config, typeMap, schemaBuilder) {
|
|
|
2940
2964
|
const fieldSchemas = {};
|
|
2941
2965
|
for (const [fieldName, value] of Object.entries(config)) {
|
|
2942
2966
|
if (value !== true)
|
|
2943
|
-
throw new ShapeError(
|
|
2967
|
+
throw new ShapeError(
|
|
2968
|
+
`Field "${fieldName}" in nested data config must be true`
|
|
2969
|
+
);
|
|
2944
2970
|
const meta = modelFields[fieldName];
|
|
2945
2971
|
if (!meta)
|
|
2946
2972
|
throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
|
|
2947
2973
|
if (meta.isRelation)
|
|
2948
|
-
throw new ShapeError(
|
|
2974
|
+
throw new ShapeError(
|
|
2975
|
+
`Nested relation writes inside nested data are not supported ("${model}.${fieldName}")`
|
|
2976
|
+
);
|
|
2949
2977
|
if (meta.isUpdatedAt)
|
|
2950
|
-
throw new ShapeError(
|
|
2978
|
+
throw new ShapeError(
|
|
2979
|
+
`updatedAt field "${fieldName}" cannot be used in nested data`
|
|
2980
|
+
);
|
|
2951
2981
|
let fieldSchema = schemaBuilder.buildFieldSchema(model, fieldName);
|
|
2952
2982
|
if (!meta.isRequired) {
|
|
2953
2983
|
fieldSchema = fieldSchema.nullable().optional();
|
|
@@ -2961,55 +2991,106 @@ function buildNestedDataSchema(model, config, typeMap, schemaBuilder) {
|
|
|
2961
2991
|
function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, config, typeMap, schemaBuilder) {
|
|
2962
2992
|
const relatedFields = typeMap[relatedModelName];
|
|
2963
2993
|
if (!relatedFields)
|
|
2964
|
-
throw new ShapeError(
|
|
2994
|
+
throw new ShapeError(
|
|
2995
|
+
`Unknown related model "${relatedModelName}" for field "${model}.${fieldName}"`
|
|
2996
|
+
);
|
|
2965
2997
|
for (const key of Object.keys(config)) {
|
|
2966
2998
|
if (!KNOWN_RELATION_WRITE_OPS.has(key)) {
|
|
2967
|
-
throw new ShapeError(
|
|
2999
|
+
throw new ShapeError(
|
|
3000
|
+
`Unknown relation write operation "${key}" on "${model}.${fieldName}". Allowed: ${[...KNOWN_RELATION_WRITE_OPS].join(", ")}`
|
|
3001
|
+
);
|
|
2968
3002
|
}
|
|
2969
3003
|
}
|
|
2970
3004
|
const opSchemas = {};
|
|
2971
3005
|
if (config.connect !== void 0) {
|
|
2972
3006
|
if (!isPlainObject(config.connect)) {
|
|
2973
|
-
throw new ShapeError(
|
|
3007
|
+
throw new ShapeError(
|
|
3008
|
+
`connect config on "${model}.${fieldName}" must be an object of field names`
|
|
3009
|
+
);
|
|
2974
3010
|
}
|
|
2975
|
-
const connectSchema = buildWhereFieldsSchema(
|
|
2976
|
-
|
|
3011
|
+
const connectSchema = buildWhereFieldsSchema(
|
|
3012
|
+
relatedModelName,
|
|
3013
|
+
config.connect,
|
|
3014
|
+
typeMap,
|
|
3015
|
+
schemaBuilder
|
|
3016
|
+
);
|
|
3017
|
+
opSchemas["connect"] = isList ? z8.union([
|
|
3018
|
+
connectSchema,
|
|
3019
|
+
z8.preprocess(coerceToArray, z8.array(connectSchema))
|
|
3020
|
+
]).optional() : connectSchema.optional();
|
|
2977
3021
|
}
|
|
2978
3022
|
if (config.connectOrCreate !== void 0) {
|
|
2979
3023
|
if (!isPlainObject(config.connectOrCreate)) {
|
|
2980
|
-
throw new ShapeError(
|
|
3024
|
+
throw new ShapeError(
|
|
3025
|
+
`connectOrCreate config on "${model}.${fieldName}" must be an object with "where" and "create"`
|
|
3026
|
+
);
|
|
2981
3027
|
}
|
|
2982
3028
|
const coc = config.connectOrCreate;
|
|
2983
3029
|
if (!coc.where || !isPlainObject(coc.where)) {
|
|
2984
|
-
throw new ShapeError(
|
|
3030
|
+
throw new ShapeError(
|
|
3031
|
+
`connectOrCreate on "${model}.${fieldName}" requires "where" object`
|
|
3032
|
+
);
|
|
2985
3033
|
}
|
|
2986
3034
|
if (!coc.create || !isPlainObject(coc.create)) {
|
|
2987
|
-
throw new ShapeError(
|
|
3035
|
+
throw new ShapeError(
|
|
3036
|
+
`connectOrCreate on "${model}.${fieldName}" requires "create" object`
|
|
3037
|
+
);
|
|
2988
3038
|
}
|
|
2989
|
-
const whereSchema = buildWhereFieldsSchema(
|
|
2990
|
-
|
|
3039
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3040
|
+
relatedModelName,
|
|
3041
|
+
coc.where,
|
|
3042
|
+
typeMap,
|
|
3043
|
+
schemaBuilder
|
|
3044
|
+
);
|
|
3045
|
+
const createSchema = buildNestedDataSchema(
|
|
3046
|
+
relatedModelName,
|
|
3047
|
+
coc.create,
|
|
3048
|
+
typeMap,
|
|
3049
|
+
schemaBuilder
|
|
3050
|
+
);
|
|
2991
3051
|
const cocSchema = z8.object({ where: whereSchema, create: createSchema }).strict();
|
|
2992
3052
|
opSchemas["connectOrCreate"] = isList ? z8.union([cocSchema, z8.preprocess(coerceToArray, z8.array(cocSchema))]).optional() : cocSchema.optional();
|
|
2993
3053
|
}
|
|
2994
3054
|
if (config.create !== void 0) {
|
|
2995
3055
|
if (!isPlainObject(config.create)) {
|
|
2996
|
-
throw new ShapeError(
|
|
3056
|
+
throw new ShapeError(
|
|
3057
|
+
`create config on "${model}.${fieldName}" must be an object of field names`
|
|
3058
|
+
);
|
|
2997
3059
|
}
|
|
2998
|
-
const createSchema = buildNestedDataSchema(
|
|
2999
|
-
|
|
3060
|
+
const createSchema = buildNestedDataSchema(
|
|
3061
|
+
relatedModelName,
|
|
3062
|
+
config.create,
|
|
3063
|
+
typeMap,
|
|
3064
|
+
schemaBuilder
|
|
3065
|
+
);
|
|
3066
|
+
opSchemas["create"] = isList ? z8.union([
|
|
3067
|
+
createSchema,
|
|
3068
|
+
z8.preprocess(coerceToArray, z8.array(createSchema))
|
|
3069
|
+
]).optional() : createSchema.optional();
|
|
3000
3070
|
}
|
|
3001
3071
|
if (config.createMany !== void 0) {
|
|
3002
3072
|
if (!isList) {
|
|
3003
|
-
throw new ShapeError(
|
|
3073
|
+
throw new ShapeError(
|
|
3074
|
+
`createMany is only valid on to-many relations ("${model}.${fieldName}")`
|
|
3075
|
+
);
|
|
3004
3076
|
}
|
|
3005
3077
|
if (!isPlainObject(config.createMany)) {
|
|
3006
|
-
throw new ShapeError(
|
|
3078
|
+
throw new ShapeError(
|
|
3079
|
+
`createMany config on "${model}.${fieldName}" must be an object`
|
|
3080
|
+
);
|
|
3007
3081
|
}
|
|
3008
3082
|
const cmConfig = config.createMany;
|
|
3009
3083
|
if (!cmConfig.data || !isPlainObject(cmConfig.data)) {
|
|
3010
|
-
throw new ShapeError(
|
|
3084
|
+
throw new ShapeError(
|
|
3085
|
+
`createMany on "${model}.${fieldName}" requires "data" object`
|
|
3086
|
+
);
|
|
3011
3087
|
}
|
|
3012
|
-
const dataSchema = buildNestedDataSchema(
|
|
3088
|
+
const dataSchema = buildNestedDataSchema(
|
|
3089
|
+
relatedModelName,
|
|
3090
|
+
cmConfig.data,
|
|
3091
|
+
typeMap,
|
|
3092
|
+
schemaBuilder
|
|
3093
|
+
);
|
|
3013
3094
|
const cmSchemaFields = {
|
|
3014
3095
|
data: z8.preprocess(coerceToArray, z8.array(dataSchema))
|
|
3015
3096
|
};
|
|
@@ -3021,111 +3102,280 @@ function buildRelationWriteSchema(model, fieldName, relatedModelName, isList, co
|
|
|
3021
3102
|
if (config.disconnect !== void 0) {
|
|
3022
3103
|
if (config.disconnect === true) {
|
|
3023
3104
|
if (isList) {
|
|
3024
|
-
throw new ShapeError(
|
|
3105
|
+
throw new ShapeError(
|
|
3106
|
+
`disconnect on to-many relation "${model}.${fieldName}" requires field config, not true`
|
|
3107
|
+
);
|
|
3025
3108
|
}
|
|
3026
3109
|
opSchemas["disconnect"] = z8.literal(true).optional();
|
|
3027
3110
|
} else if (isPlainObject(config.disconnect)) {
|
|
3028
|
-
const disconnectSchema = buildWhereFieldsSchema(
|
|
3029
|
-
|
|
3111
|
+
const disconnectSchema = buildWhereFieldsSchema(
|
|
3112
|
+
relatedModelName,
|
|
3113
|
+
config.disconnect,
|
|
3114
|
+
typeMap,
|
|
3115
|
+
schemaBuilder
|
|
3116
|
+
);
|
|
3117
|
+
if (isList) {
|
|
3118
|
+
opSchemas["disconnect"] = z8.union([
|
|
3119
|
+
disconnectSchema,
|
|
3120
|
+
z8.preprocess(coerceToArray, z8.array(disconnectSchema))
|
|
3121
|
+
]).optional();
|
|
3122
|
+
} else {
|
|
3123
|
+
opSchemas["disconnect"] = z8.union([z8.literal(true), disconnectSchema]).optional();
|
|
3124
|
+
}
|
|
3030
3125
|
} else {
|
|
3031
|
-
throw new ShapeError(
|
|
3126
|
+
throw new ShapeError(
|
|
3127
|
+
`disconnect config on "${model}.${fieldName}" must be true (to-one) or an object of field names`
|
|
3128
|
+
);
|
|
3032
3129
|
}
|
|
3033
3130
|
}
|
|
3034
3131
|
if (config.delete !== void 0) {
|
|
3035
3132
|
if (config.delete === true) {
|
|
3036
3133
|
if (isList) {
|
|
3037
|
-
throw new ShapeError(
|
|
3134
|
+
throw new ShapeError(
|
|
3135
|
+
`delete on to-many relation "${model}.${fieldName}" requires field config, not true`
|
|
3136
|
+
);
|
|
3038
3137
|
}
|
|
3039
3138
|
opSchemas["delete"] = z8.literal(true).optional();
|
|
3040
3139
|
} else if (isPlainObject(config.delete)) {
|
|
3041
|
-
const deleteSchema = buildWhereFieldsSchema(
|
|
3042
|
-
|
|
3140
|
+
const deleteSchema = buildWhereFieldsSchema(
|
|
3141
|
+
relatedModelName,
|
|
3142
|
+
config.delete,
|
|
3143
|
+
typeMap,
|
|
3144
|
+
schemaBuilder
|
|
3145
|
+
);
|
|
3146
|
+
if (isList) {
|
|
3147
|
+
opSchemas["delete"] = z8.union([
|
|
3148
|
+
deleteSchema,
|
|
3149
|
+
z8.preprocess(coerceToArray, z8.array(deleteSchema))
|
|
3150
|
+
]).optional();
|
|
3151
|
+
} else {
|
|
3152
|
+
opSchemas["delete"] = z8.union([z8.literal(true), deleteSchema]).optional();
|
|
3153
|
+
}
|
|
3043
3154
|
} else {
|
|
3044
|
-
throw new ShapeError(
|
|
3155
|
+
throw new ShapeError(
|
|
3156
|
+
`delete config on "${model}.${fieldName}" must be true (to-one) or an object of field names`
|
|
3157
|
+
);
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
if (config.delete !== void 0) {
|
|
3161
|
+
if (config.delete === true) {
|
|
3162
|
+
if (isList) {
|
|
3163
|
+
throw new ShapeError(
|
|
3164
|
+
`delete on to-many relation "${model}.${fieldName}" requires field config, not true`
|
|
3165
|
+
);
|
|
3166
|
+
}
|
|
3167
|
+
opSchemas["delete"] = z8.literal(true).optional();
|
|
3168
|
+
} else if (isPlainObject(config.delete)) {
|
|
3169
|
+
const deleteSchema = buildWhereFieldsSchema(
|
|
3170
|
+
relatedModelName,
|
|
3171
|
+
config.delete,
|
|
3172
|
+
typeMap,
|
|
3173
|
+
schemaBuilder
|
|
3174
|
+
);
|
|
3175
|
+
opSchemas["delete"] = isList ? z8.union([
|
|
3176
|
+
deleteSchema,
|
|
3177
|
+
z8.preprocess(coerceToArray, z8.array(deleteSchema))
|
|
3178
|
+
]).optional() : deleteSchema.optional();
|
|
3179
|
+
} else {
|
|
3180
|
+
throw new ShapeError(
|
|
3181
|
+
`delete config on "${model}.${fieldName}" must be true (to-one) or an object of field names`
|
|
3182
|
+
);
|
|
3045
3183
|
}
|
|
3046
3184
|
}
|
|
3047
3185
|
if (config.set !== void 0) {
|
|
3048
3186
|
if (!isList) {
|
|
3049
|
-
throw new ShapeError(
|
|
3187
|
+
throw new ShapeError(
|
|
3188
|
+
`set is only valid on to-many relations ("${model}.${fieldName}")`
|
|
3189
|
+
);
|
|
3050
3190
|
}
|
|
3051
3191
|
if (!isPlainObject(config.set)) {
|
|
3052
|
-
throw new ShapeError(
|
|
3192
|
+
throw new ShapeError(
|
|
3193
|
+
`set config on "${model}.${fieldName}" must be an object of field names`
|
|
3194
|
+
);
|
|
3053
3195
|
}
|
|
3054
|
-
const setSchema = buildWhereFieldsSchema(
|
|
3196
|
+
const setSchema = buildWhereFieldsSchema(
|
|
3197
|
+
relatedModelName,
|
|
3198
|
+
config.set,
|
|
3199
|
+
typeMap,
|
|
3200
|
+
schemaBuilder
|
|
3201
|
+
);
|
|
3055
3202
|
opSchemas["set"] = z8.preprocess(coerceToArray, z8.array(setSchema)).optional();
|
|
3056
3203
|
}
|
|
3057
3204
|
if (config.update !== void 0) {
|
|
3058
3205
|
if (!isPlainObject(config.update)) {
|
|
3059
|
-
throw new ShapeError(
|
|
3206
|
+
throw new ShapeError(
|
|
3207
|
+
`update config on "${model}.${fieldName}" must be an object`
|
|
3208
|
+
);
|
|
3060
3209
|
}
|
|
3061
3210
|
const updateConfig = config.update;
|
|
3062
3211
|
if (isList) {
|
|
3063
3212
|
if (!updateConfig.where || !isPlainObject(updateConfig.where)) {
|
|
3064
|
-
throw new ShapeError(
|
|
3213
|
+
throw new ShapeError(
|
|
3214
|
+
`update on to-many "${model}.${fieldName}" requires "where" object`
|
|
3215
|
+
);
|
|
3065
3216
|
}
|
|
3066
3217
|
if (!updateConfig.data || !isPlainObject(updateConfig.data)) {
|
|
3067
|
-
throw new ShapeError(
|
|
3218
|
+
throw new ShapeError(
|
|
3219
|
+
`update on to-many "${model}.${fieldName}" requires "data" object`
|
|
3220
|
+
);
|
|
3068
3221
|
}
|
|
3069
|
-
const whereSchema = buildWhereFieldsSchema(
|
|
3070
|
-
|
|
3222
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3223
|
+
relatedModelName,
|
|
3224
|
+
updateConfig.where,
|
|
3225
|
+
typeMap,
|
|
3226
|
+
schemaBuilder
|
|
3227
|
+
);
|
|
3228
|
+
const dataSchema = buildNestedDataSchema(
|
|
3229
|
+
relatedModelName,
|
|
3230
|
+
updateConfig.data,
|
|
3231
|
+
typeMap,
|
|
3232
|
+
schemaBuilder
|
|
3233
|
+
);
|
|
3071
3234
|
const updateSchema = z8.object({ where: whereSchema, data: dataSchema }).strict();
|
|
3072
|
-
opSchemas["update"] = z8.union([
|
|
3235
|
+
opSchemas["update"] = z8.union([
|
|
3236
|
+
updateSchema,
|
|
3237
|
+
z8.preprocess(coerceToArray, z8.array(updateSchema))
|
|
3238
|
+
]).optional();
|
|
3073
3239
|
} else {
|
|
3074
|
-
const dataSchema = buildNestedDataSchema(
|
|
3240
|
+
const dataSchema = buildNestedDataSchema(
|
|
3241
|
+
relatedModelName,
|
|
3242
|
+
updateConfig,
|
|
3243
|
+
typeMap,
|
|
3244
|
+
schemaBuilder
|
|
3245
|
+
);
|
|
3075
3246
|
opSchemas["update"] = dataSchema.optional();
|
|
3076
3247
|
}
|
|
3077
3248
|
}
|
|
3078
3249
|
if (config.upsert !== void 0) {
|
|
3079
3250
|
if (!isPlainObject(config.upsert)) {
|
|
3080
|
-
throw new ShapeError(
|
|
3251
|
+
throw new ShapeError(
|
|
3252
|
+
`upsert config on "${model}.${fieldName}" must be an object`
|
|
3253
|
+
);
|
|
3081
3254
|
}
|
|
3082
3255
|
const upsertConfig = config.upsert;
|
|
3083
|
-
if (!upsertConfig.where || !isPlainObject(upsertConfig.where)) {
|
|
3084
|
-
throw new ShapeError(`upsert on "${model}.${fieldName}" requires "where" object`);
|
|
3085
|
-
}
|
|
3086
3256
|
if (!upsertConfig.create || !isPlainObject(upsertConfig.create)) {
|
|
3087
|
-
throw new ShapeError(
|
|
3257
|
+
throw new ShapeError(
|
|
3258
|
+
`upsert on "${model}.${fieldName}" requires "create" object`
|
|
3259
|
+
);
|
|
3088
3260
|
}
|
|
3089
3261
|
if (!upsertConfig.update || !isPlainObject(upsertConfig.update)) {
|
|
3090
|
-
throw new ShapeError(
|
|
3262
|
+
throw new ShapeError(
|
|
3263
|
+
`upsert on "${model}.${fieldName}" requires "update" object`
|
|
3264
|
+
);
|
|
3265
|
+
}
|
|
3266
|
+
const createSchema = buildNestedDataSchema(
|
|
3267
|
+
relatedModelName,
|
|
3268
|
+
upsertConfig.create,
|
|
3269
|
+
typeMap,
|
|
3270
|
+
schemaBuilder
|
|
3271
|
+
);
|
|
3272
|
+
const updateSchema = buildNestedDataSchema(
|
|
3273
|
+
relatedModelName,
|
|
3274
|
+
upsertConfig.update,
|
|
3275
|
+
typeMap,
|
|
3276
|
+
schemaBuilder
|
|
3277
|
+
);
|
|
3278
|
+
if (isList) {
|
|
3279
|
+
if (!upsertConfig.where || !isPlainObject(upsertConfig.where)) {
|
|
3280
|
+
throw new ShapeError(
|
|
3281
|
+
`upsert on to-many "${model}.${fieldName}" requires "where" object`
|
|
3282
|
+
);
|
|
3283
|
+
}
|
|
3284
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3285
|
+
relatedModelName,
|
|
3286
|
+
upsertConfig.where,
|
|
3287
|
+
typeMap,
|
|
3288
|
+
schemaBuilder
|
|
3289
|
+
);
|
|
3290
|
+
const upsertSchema = z8.object({
|
|
3291
|
+
where: whereSchema,
|
|
3292
|
+
create: createSchema,
|
|
3293
|
+
update: updateSchema
|
|
3294
|
+
}).strict();
|
|
3295
|
+
opSchemas["upsert"] = z8.union([
|
|
3296
|
+
upsertSchema,
|
|
3297
|
+
z8.preprocess(coerceToArray, z8.array(upsertSchema))
|
|
3298
|
+
]).optional();
|
|
3299
|
+
} else {
|
|
3300
|
+
if (upsertConfig.where) {
|
|
3301
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3302
|
+
relatedModelName,
|
|
3303
|
+
upsertConfig.where,
|
|
3304
|
+
typeMap,
|
|
3305
|
+
schemaBuilder
|
|
3306
|
+
);
|
|
3307
|
+
const upsertSchema = z8.object({
|
|
3308
|
+
where: whereSchema,
|
|
3309
|
+
create: createSchema,
|
|
3310
|
+
update: updateSchema
|
|
3311
|
+
}).strict();
|
|
3312
|
+
opSchemas["upsert"] = upsertSchema.optional();
|
|
3313
|
+
} else {
|
|
3314
|
+
const upsertSchema = z8.object({ create: createSchema, update: updateSchema }).strict();
|
|
3315
|
+
opSchemas["upsert"] = upsertSchema.optional();
|
|
3316
|
+
}
|
|
3091
3317
|
}
|
|
3092
|
-
const whereSchema = buildWhereFieldsSchema(relatedModelName, upsertConfig.where, typeMap, schemaBuilder);
|
|
3093
|
-
const createSchema = buildNestedDataSchema(relatedModelName, upsertConfig.create, typeMap, schemaBuilder);
|
|
3094
|
-
const updateSchema = buildNestedDataSchema(relatedModelName, upsertConfig.update, typeMap, schemaBuilder);
|
|
3095
|
-
const upsertSchema = z8.object({ where: whereSchema, create: createSchema, update: updateSchema }).strict();
|
|
3096
|
-
opSchemas["upsert"] = isList ? z8.union([upsertSchema, z8.preprocess(coerceToArray, z8.array(upsertSchema))]).optional() : upsertSchema.optional();
|
|
3097
3318
|
}
|
|
3098
3319
|
if (config.updateMany !== void 0) {
|
|
3099
3320
|
if (!isList) {
|
|
3100
|
-
throw new ShapeError(
|
|
3321
|
+
throw new ShapeError(
|
|
3322
|
+
`updateMany is only valid on to-many relations ("${model}.${fieldName}")`
|
|
3323
|
+
);
|
|
3101
3324
|
}
|
|
3102
3325
|
if (!isPlainObject(config.updateMany)) {
|
|
3103
|
-
throw new ShapeError(
|
|
3326
|
+
throw new ShapeError(
|
|
3327
|
+
`updateMany config on "${model}.${fieldName}" must be an object`
|
|
3328
|
+
);
|
|
3104
3329
|
}
|
|
3105
3330
|
const umConfig = config.updateMany;
|
|
3106
3331
|
if (!umConfig.where || !isPlainObject(umConfig.where)) {
|
|
3107
|
-
throw new ShapeError(
|
|
3332
|
+
throw new ShapeError(
|
|
3333
|
+
`updateMany on "${model}.${fieldName}" requires "where" object`
|
|
3334
|
+
);
|
|
3108
3335
|
}
|
|
3109
3336
|
if (!umConfig.data || !isPlainObject(umConfig.data)) {
|
|
3110
|
-
throw new ShapeError(
|
|
3337
|
+
throw new ShapeError(
|
|
3338
|
+
`updateMany on "${model}.${fieldName}" requires "data" object`
|
|
3339
|
+
);
|
|
3111
3340
|
}
|
|
3112
|
-
const whereSchema = buildWhereFieldsSchema(
|
|
3113
|
-
|
|
3341
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3342
|
+
relatedModelName,
|
|
3343
|
+
umConfig.where,
|
|
3344
|
+
typeMap,
|
|
3345
|
+
schemaBuilder
|
|
3346
|
+
);
|
|
3347
|
+
const dataSchema = buildNestedDataSchema(
|
|
3348
|
+
relatedModelName,
|
|
3349
|
+
umConfig.data,
|
|
3350
|
+
typeMap,
|
|
3351
|
+
schemaBuilder
|
|
3352
|
+
);
|
|
3114
3353
|
const umSchema = z8.object({ where: whereSchema, data: dataSchema }).strict();
|
|
3115
3354
|
opSchemas["updateMany"] = z8.union([umSchema, z8.preprocess(coerceToArray, z8.array(umSchema))]).optional();
|
|
3116
3355
|
}
|
|
3117
3356
|
if (config.deleteMany !== void 0) {
|
|
3118
3357
|
if (!isList) {
|
|
3119
|
-
throw new ShapeError(
|
|
3358
|
+
throw new ShapeError(
|
|
3359
|
+
`deleteMany is only valid on to-many relations ("${model}.${fieldName}")`
|
|
3360
|
+
);
|
|
3120
3361
|
}
|
|
3121
3362
|
if (!isPlainObject(config.deleteMany)) {
|
|
3122
|
-
throw new ShapeError(
|
|
3363
|
+
throw new ShapeError(
|
|
3364
|
+
`deleteMany config on "${model}.${fieldName}" must be an object`
|
|
3365
|
+
);
|
|
3123
3366
|
}
|
|
3124
3367
|
const dmConfig = config.deleteMany;
|
|
3125
3368
|
if (!dmConfig.where || !isPlainObject(dmConfig.where)) {
|
|
3126
|
-
throw new ShapeError(
|
|
3369
|
+
throw new ShapeError(
|
|
3370
|
+
`deleteMany on "${model}.${fieldName}" requires "where" object`
|
|
3371
|
+
);
|
|
3127
3372
|
}
|
|
3128
|
-
const whereSchema = buildWhereFieldsSchema(
|
|
3373
|
+
const whereSchema = buildWhereFieldsSchema(
|
|
3374
|
+
relatedModelName,
|
|
3375
|
+
dmConfig.where,
|
|
3376
|
+
typeMap,
|
|
3377
|
+
schemaBuilder
|
|
3378
|
+
);
|
|
3129
3379
|
const dmSchema = z8.object({ where: whereSchema }).strict();
|
|
3130
3380
|
opSchemas["deleteMany"] = z8.union([dmSchema, z8.preprocess(coerceToArray, z8.array(dmSchema))]).optional();
|
|
3131
3381
|
}
|
|
@@ -3145,7 +3395,9 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3145
3395
|
throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
|
|
3146
3396
|
if (fieldMeta.isRelation) {
|
|
3147
3397
|
if (!isPlainObject(value)) {
|
|
3148
|
-
throw new ShapeError(
|
|
3398
|
+
throw new ShapeError(
|
|
3399
|
+
`Relation field "${fieldName}" on model "${model}" requires a relation write config object`
|
|
3400
|
+
);
|
|
3149
3401
|
}
|
|
3150
3402
|
schemaMap[fieldName] = buildRelationWriteSchema(
|
|
3151
3403
|
model,
|
|
@@ -3159,9 +3411,14 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3159
3411
|
continue;
|
|
3160
3412
|
}
|
|
3161
3413
|
if (fieldMeta.isUpdatedAt)
|
|
3162
|
-
throw new ShapeError(
|
|
3414
|
+
throw new ShapeError(
|
|
3415
|
+
`updatedAt field "${fieldName}" cannot be used in data shape`
|
|
3416
|
+
);
|
|
3163
3417
|
if (typeof value === "function") {
|
|
3164
|
-
let baseSchema = schemaBuilder.buildBaseFieldSchema(
|
|
3418
|
+
let baseSchema = schemaBuilder.buildBaseFieldSchema(
|
|
3419
|
+
model,
|
|
3420
|
+
fieldName
|
|
3421
|
+
);
|
|
3165
3422
|
let refined;
|
|
3166
3423
|
try {
|
|
3167
3424
|
refined = value(baseSchema);
|
|
@@ -3172,7 +3429,9 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3172
3429
|
);
|
|
3173
3430
|
}
|
|
3174
3431
|
if (!isZodSchema(refined)) {
|
|
3175
|
-
throw new ShapeError(
|
|
3432
|
+
throw new ShapeError(
|
|
3433
|
+
`Inline refine for "${model}.${fieldName}" must return a Zod schema`
|
|
3434
|
+
);
|
|
3176
3435
|
}
|
|
3177
3436
|
let fieldSchema = refined;
|
|
3178
3437
|
const handlesUndefined = schemaProducesValueForUndefined(fieldSchema);
|
|
@@ -3193,7 +3452,10 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3193
3452
|
}
|
|
3194
3453
|
schemaMap[fieldName] = fieldSchema;
|
|
3195
3454
|
} else if (value === true) {
|
|
3196
|
-
let fieldSchema = schemaBuilder.buildFieldSchema(
|
|
3455
|
+
let fieldSchema = schemaBuilder.buildFieldSchema(
|
|
3456
|
+
model,
|
|
3457
|
+
fieldName
|
|
3458
|
+
);
|
|
3197
3459
|
const isZodDefaultField = zodDefaultSet !== void 0 && zodDefaultSet.has(fieldName);
|
|
3198
3460
|
if (mode === "create") {
|
|
3199
3461
|
if (!fieldMeta.isRequired) {
|
|
@@ -3213,7 +3475,10 @@ function buildDataSchema(model, dataConfig, mode, typeMap, schemaBuilder, zodDef
|
|
|
3213
3475
|
schemaMap[fieldName] = fieldSchema;
|
|
3214
3476
|
} else {
|
|
3215
3477
|
const actualValue = isForcedValue(value) ? value.value : value;
|
|
3216
|
-
let fieldSchema = schemaBuilder.buildFieldSchema(
|
|
3478
|
+
let fieldSchema = schemaBuilder.buildFieldSchema(
|
|
3479
|
+
model,
|
|
3480
|
+
fieldName
|
|
3481
|
+
);
|
|
3217
3482
|
if (!fieldMeta.isRequired) {
|
|
3218
3483
|
fieldSchema = fieldSchema.nullable();
|
|
3219
3484
|
}
|