prisma-guard 1.4.0 → 1.4.1
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 +469 -94
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +469 -94
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.js
CHANGED
|
@@ -704,7 +704,24 @@ function mergeUniqueWhereForced(where, forced) {
|
|
|
704
704
|
return result;
|
|
705
705
|
}
|
|
706
706
|
function applyBuiltShape(built, body, isUniqueMethod) {
|
|
707
|
-
|
|
707
|
+
let parseable = body;
|
|
708
|
+
if (built.forcedOnlyWhereKeys.size > 0 && isPlainObject(body)) {
|
|
709
|
+
const bodyObj = body;
|
|
710
|
+
if (isPlainObject(bodyObj.where)) {
|
|
711
|
+
const where = { ...bodyObj.where };
|
|
712
|
+
let stripped = false;
|
|
713
|
+
for (const key of built.forcedOnlyWhereKeys) {
|
|
714
|
+
if (key in where) {
|
|
715
|
+
delete where[key];
|
|
716
|
+
stripped = true;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
if (stripped) {
|
|
720
|
+
parseable = { ...bodyObj, where };
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
const validated = built.zodSchema.parse(parseable);
|
|
708
725
|
if (hasWhereForced(built.forcedWhere)) {
|
|
709
726
|
validated.where = isUniqueMethod ? mergeUniqueWhereForced(
|
|
710
727
|
validated.where,
|
|
@@ -928,7 +945,12 @@ function validateUniqueEquality(model, where, method, uniqueMap, typeMap) {
|
|
|
928
945
|
|
|
929
946
|
// src/runtime/query-builder-where.ts
|
|
930
947
|
var UNSUPPORTED_WHERE_TYPES = /* @__PURE__ */ new Set(["Json", "Bytes"]);
|
|
931
|
-
var STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
948
|
+
var STRING_MODE_OPS = /* @__PURE__ */ new Set([
|
|
949
|
+
"contains",
|
|
950
|
+
"startsWith",
|
|
951
|
+
"endsWith",
|
|
952
|
+
"equals"
|
|
953
|
+
]);
|
|
932
954
|
var MAX_WHERE_DEPTH = 10;
|
|
933
955
|
function safeStringify(v) {
|
|
934
956
|
if (typeof v === "bigint")
|
|
@@ -998,9 +1020,7 @@ function mergeScalarConditions(target, source) {
|
|
|
998
1020
|
continue;
|
|
999
1021
|
}
|
|
1000
1022
|
if (!forcedValuesEqual(existing, ops)) {
|
|
1001
|
-
throw new ShapeError(
|
|
1002
|
-
`Conflicting forced where values for "${field}"`
|
|
1003
|
-
);
|
|
1023
|
+
throw new ShapeError(`Conflicting forced where values for "${field}"`);
|
|
1004
1024
|
}
|
|
1005
1025
|
}
|
|
1006
1026
|
}
|
|
@@ -1014,8 +1034,14 @@ function mergeRelationForcedMaps(target, source) {
|
|
|
1014
1034
|
if (!target[relName][op]) {
|
|
1015
1035
|
target[relName][op] = forced;
|
|
1016
1036
|
} else {
|
|
1017
|
-
mergeScalarConditions(
|
|
1018
|
-
|
|
1037
|
+
mergeScalarConditions(
|
|
1038
|
+
target[relName][op].conditions,
|
|
1039
|
+
forced.conditions
|
|
1040
|
+
);
|
|
1041
|
+
mergeRelationForcedMaps(
|
|
1042
|
+
target[relName][op].relations,
|
|
1043
|
+
forced.relations
|
|
1044
|
+
);
|
|
1019
1045
|
}
|
|
1020
1046
|
}
|
|
1021
1047
|
}
|
|
@@ -1067,20 +1093,38 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1067
1093
|
`${fieldMeta.type} field "${key}" cannot be used in where filters`
|
|
1068
1094
|
);
|
|
1069
1095
|
}
|
|
1070
|
-
processScalarField(
|
|
1096
|
+
processScalarField(
|
|
1097
|
+
key,
|
|
1098
|
+
value,
|
|
1099
|
+
model,
|
|
1100
|
+
fieldMeta,
|
|
1101
|
+
fieldSchemas,
|
|
1102
|
+
scalarConditions
|
|
1103
|
+
);
|
|
1071
1104
|
}
|
|
1072
1105
|
const schema = Object.keys(fieldSchemas).length > 0 ? z4.object(fieldSchemas).strict().optional() : null;
|
|
1106
|
+
const forcedOnlyKeys = /* @__PURE__ */ new Set();
|
|
1107
|
+
for (const key of Object.keys(whereConfig)) {
|
|
1108
|
+
if (COMBINATOR_KEYS.has(key))
|
|
1109
|
+
continue;
|
|
1110
|
+
if (!(key in fieldSchemas)) {
|
|
1111
|
+
forcedOnlyKeys.add(key);
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1073
1114
|
return {
|
|
1074
1115
|
schema,
|
|
1075
1116
|
forced: {
|
|
1076
1117
|
conditions: scalarConditions,
|
|
1077
1118
|
relations: relationForced
|
|
1078
|
-
}
|
|
1119
|
+
},
|
|
1120
|
+
forcedOnlyKeys
|
|
1079
1121
|
};
|
|
1080
1122
|
}
|
|
1081
1123
|
function processCombinator(key, value, model, fieldSchemas, parentConditions, parentRelations, depth) {
|
|
1082
1124
|
if (!isPlainObject(value)) {
|
|
1083
|
-
throw new ShapeError(
|
|
1125
|
+
throw new ShapeError(
|
|
1126
|
+
`"${key}" in where shape must be an object defining allowed fields`
|
|
1127
|
+
);
|
|
1084
1128
|
}
|
|
1085
1129
|
const result = buildWhereSchema(model, value, depth + 1);
|
|
1086
1130
|
if (!result.schema && !hasWhereForced(result.forced)) {
|
|
@@ -1121,7 +1165,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1121
1165
|
}
|
|
1122
1166
|
function processRelationFilter(key, value, fieldMeta, model, fieldSchemas, parentRelations, depth) {
|
|
1123
1167
|
if (!isPlainObject(value)) {
|
|
1124
|
-
throw new ShapeError(
|
|
1168
|
+
throw new ShapeError(
|
|
1169
|
+
`Relation filter for "${key}" must be an object with operators (some, every, none, is, isNot)`
|
|
1170
|
+
);
|
|
1125
1171
|
}
|
|
1126
1172
|
const allowedOps = fieldMeta.isList ? TO_MANY_RELATION_OPS : TO_ONE_RELATION_OPS;
|
|
1127
1173
|
if (Object.keys(value).length === 0) {
|
|
@@ -1154,7 +1200,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1154
1200
|
if (!hasWhereForced(nested.forced)) {
|
|
1155
1201
|
opSchemas[op] = nested.schema.refine(
|
|
1156
1202
|
(v) => v === void 0 || Object.keys(v).length > 0,
|
|
1157
|
-
{
|
|
1203
|
+
{
|
|
1204
|
+
message: `Relation filter "${key}.${op}" requires at least one condition`
|
|
1205
|
+
}
|
|
1158
1206
|
);
|
|
1159
1207
|
} else {
|
|
1160
1208
|
opSchemas[op] = nested.schema;
|
|
@@ -1175,7 +1223,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1175
1223
|
const opObjSchema = z4.object(opSchemas).strict();
|
|
1176
1224
|
if (Object.keys(opForced).length === 0) {
|
|
1177
1225
|
fieldSchemas[key] = opObjSchema.refine(
|
|
1178
|
-
(v) => clientOpKeys.some(
|
|
1226
|
+
(v) => clientOpKeys.some(
|
|
1227
|
+
(k) => v[k] !== void 0
|
|
1228
|
+
),
|
|
1179
1229
|
{ message: `At least one relation operator required for "${key}"` }
|
|
1180
1230
|
).optional();
|
|
1181
1231
|
} else {
|
|
@@ -1199,7 +1249,12 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1199
1249
|
const clientOpKeys = [];
|
|
1200
1250
|
for (const [op, opValue] of Object.entries(operators)) {
|
|
1201
1251
|
if (opValue === true) {
|
|
1202
|
-
opSchemas[op] = createOperatorSchema(
|
|
1252
|
+
opSchemas[op] = createOperatorSchema(
|
|
1253
|
+
fieldMeta,
|
|
1254
|
+
op,
|
|
1255
|
+
enumMap,
|
|
1256
|
+
scalarBase
|
|
1257
|
+
).optional();
|
|
1203
1258
|
hasClientOps = true;
|
|
1204
1259
|
clientOpKeys.push(op);
|
|
1205
1260
|
if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
|
|
@@ -1207,7 +1262,12 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1207
1262
|
}
|
|
1208
1263
|
} else {
|
|
1209
1264
|
const actualOpValue = isForcedValue(opValue) ? opValue.value : opValue;
|
|
1210
|
-
const opSchema = createOperatorSchema(
|
|
1265
|
+
const opSchema = createOperatorSchema(
|
|
1266
|
+
fieldMeta,
|
|
1267
|
+
op,
|
|
1268
|
+
enumMap,
|
|
1269
|
+
scalarBase
|
|
1270
|
+
);
|
|
1211
1271
|
let parsed;
|
|
1212
1272
|
try {
|
|
1213
1273
|
parsed = opSchema.parse(actualOpValue);
|
|
@@ -1230,8 +1290,12 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
|
|
|
1230
1290
|
if (hasClientOps) {
|
|
1231
1291
|
const opObj = z4.object(opSchemas).strict();
|
|
1232
1292
|
fieldSchemas[fieldName] = opObj.refine(
|
|
1233
|
-
(v) => clientOpKeys.some(
|
|
1234
|
-
|
|
1293
|
+
(v) => clientOpKeys.some(
|
|
1294
|
+
(k) => v[k] !== void 0
|
|
1295
|
+
),
|
|
1296
|
+
{
|
|
1297
|
+
message: `At least one operator required for where field "${fieldName}"`
|
|
1298
|
+
}
|
|
1235
1299
|
).optional();
|
|
1236
1300
|
}
|
|
1237
1301
|
if (Object.keys(fieldForced).length > 0) {
|
|
@@ -1897,19 +1961,77 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
|
|
|
1897
1961
|
|
|
1898
1962
|
// src/runtime/query-builder.ts
|
|
1899
1963
|
var METHOD_ALLOWED_ARGS = {
|
|
1900
|
-
findMany: /* @__PURE__ */ new Set([
|
|
1901
|
-
|
|
1902
|
-
|
|
1964
|
+
findMany: /* @__PURE__ */ new Set([
|
|
1965
|
+
"where",
|
|
1966
|
+
"include",
|
|
1967
|
+
"select",
|
|
1968
|
+
"orderBy",
|
|
1969
|
+
"cursor",
|
|
1970
|
+
"take",
|
|
1971
|
+
"skip",
|
|
1972
|
+
"distinct"
|
|
1973
|
+
]),
|
|
1974
|
+
findFirst: /* @__PURE__ */ new Set([
|
|
1975
|
+
"where",
|
|
1976
|
+
"include",
|
|
1977
|
+
"select",
|
|
1978
|
+
"orderBy",
|
|
1979
|
+
"cursor",
|
|
1980
|
+
"take",
|
|
1981
|
+
"skip",
|
|
1982
|
+
"distinct"
|
|
1983
|
+
]),
|
|
1984
|
+
findFirstOrThrow: /* @__PURE__ */ new Set([
|
|
1985
|
+
"where",
|
|
1986
|
+
"include",
|
|
1987
|
+
"select",
|
|
1988
|
+
"orderBy",
|
|
1989
|
+
"cursor",
|
|
1990
|
+
"take",
|
|
1991
|
+
"skip",
|
|
1992
|
+
"distinct"
|
|
1993
|
+
]),
|
|
1903
1994
|
findUnique: /* @__PURE__ */ new Set(["where", "include", "select"]),
|
|
1904
1995
|
findUniqueOrThrow: /* @__PURE__ */ new Set(["where", "include", "select"]),
|
|
1905
1996
|
count: /* @__PURE__ */ new Set(["where", "select", "cursor", "orderBy", "skip", "take"]),
|
|
1906
|
-
aggregate: /* @__PURE__ */ new Set([
|
|
1907
|
-
|
|
1997
|
+
aggregate: /* @__PURE__ */ new Set([
|
|
1998
|
+
"where",
|
|
1999
|
+
"orderBy",
|
|
2000
|
+
"cursor",
|
|
2001
|
+
"take",
|
|
2002
|
+
"skip",
|
|
2003
|
+
"_count",
|
|
2004
|
+
"_avg",
|
|
2005
|
+
"_sum",
|
|
2006
|
+
"_min",
|
|
2007
|
+
"_max"
|
|
2008
|
+
]),
|
|
2009
|
+
groupBy: /* @__PURE__ */ new Set([
|
|
2010
|
+
"where",
|
|
2011
|
+
"by",
|
|
2012
|
+
"having",
|
|
2013
|
+
"_count",
|
|
2014
|
+
"_avg",
|
|
2015
|
+
"_sum",
|
|
2016
|
+
"_min",
|
|
2017
|
+
"_max",
|
|
2018
|
+
"orderBy",
|
|
2019
|
+
"take",
|
|
2020
|
+
"skip"
|
|
2021
|
+
])
|
|
1908
2022
|
};
|
|
1909
|
-
var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set([
|
|
2023
|
+
var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set([
|
|
2024
|
+
"findUnique",
|
|
2025
|
+
"findUniqueOrThrow"
|
|
2026
|
+
]);
|
|
1910
2027
|
function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
1911
2028
|
const whereBuilder = createWhereBuilder(typeMap, enumMap, scalarBase);
|
|
1912
|
-
const argsBuilder = createArgsBuilder(
|
|
2029
|
+
const argsBuilder = createArgsBuilder(
|
|
2030
|
+
typeMap,
|
|
2031
|
+
enumMap,
|
|
2032
|
+
uniqueMap,
|
|
2033
|
+
scalarBase
|
|
2034
|
+
);
|
|
1913
2035
|
const projectionBuilder = createProjectionBuilder(typeMap, enumMap, {
|
|
1914
2036
|
buildWhereSchema: whereBuilder.buildWhereSchema,
|
|
1915
2037
|
buildOrderBySchema: argsBuilder.buildOrderBySchema,
|
|
@@ -1934,7 +2056,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
1934
2056
|
throw new ShapeError(`${method} shape must define "where"`);
|
|
1935
2057
|
}
|
|
1936
2058
|
if (shape.include && shape.select) {
|
|
1937
|
-
throw new ShapeError(
|
|
2059
|
+
throw new ShapeError(
|
|
2060
|
+
'Shape config cannot define both "include" and "select".'
|
|
2061
|
+
);
|
|
1938
2062
|
}
|
|
1939
2063
|
if (method === "groupBy" && !shape.by)
|
|
1940
2064
|
throw new ShapeError('groupBy shape must define "by"');
|
|
@@ -1950,7 +2074,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
1950
2074
|
const bySet = new Set(shape.by);
|
|
1951
2075
|
for (const fieldName of Object.keys(shape.orderBy)) {
|
|
1952
2076
|
if (!bySet.has(fieldName)) {
|
|
1953
|
-
throw new ShapeError(
|
|
2077
|
+
throw new ShapeError(
|
|
2078
|
+
`orderBy field "${fieldName}" must be included in "by" for groupBy`
|
|
2079
|
+
);
|
|
1954
2080
|
}
|
|
1955
2081
|
}
|
|
1956
2082
|
}
|
|
@@ -1958,7 +2084,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
1958
2084
|
const bySet = new Set(shape.by);
|
|
1959
2085
|
for (const fieldName of Object.keys(shape.having)) {
|
|
1960
2086
|
if (!bySet.has(fieldName)) {
|
|
1961
|
-
throw new ShapeError(
|
|
2087
|
+
throw new ShapeError(
|
|
2088
|
+
`having field "${fieldName}" must be included in "by" for groupBy`
|
|
2089
|
+
);
|
|
1962
2090
|
}
|
|
1963
2091
|
}
|
|
1964
2092
|
}
|
|
@@ -1975,7 +2103,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
1975
2103
|
requireContext(ctx, "shape function");
|
|
1976
2104
|
const result = shapeOrFn(ctx);
|
|
1977
2105
|
if (!isPlainObject(result)) {
|
|
1978
|
-
throw new ShapeError(
|
|
2106
|
+
throw new ShapeError(
|
|
2107
|
+
"Dynamic shape function must return a plain object"
|
|
2108
|
+
);
|
|
1979
2109
|
}
|
|
1980
2110
|
return result;
|
|
1981
2111
|
}
|
|
@@ -1986,15 +2116,20 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
1986
2116
|
validateUniqueWhere(model, method, shape);
|
|
1987
2117
|
const schemaFields = {};
|
|
1988
2118
|
let forcedWhere = EMPTY_WHERE_FORCED;
|
|
2119
|
+
let forcedOnlyWhereKeys = /* @__PURE__ */ new Set();
|
|
1989
2120
|
let forcedIncludeTree = {};
|
|
1990
2121
|
let forcedSelectTree = {};
|
|
1991
2122
|
let forcedIncludeCountWhere = {};
|
|
1992
2123
|
let forcedSelectCountWhere = {};
|
|
1993
2124
|
if (shape.where) {
|
|
1994
|
-
const { schema, forced } = whereBuilder.buildWhereSchema(
|
|
2125
|
+
const { schema, forced, forcedOnlyKeys } = whereBuilder.buildWhereSchema(
|
|
2126
|
+
model,
|
|
2127
|
+
shape.where
|
|
2128
|
+
);
|
|
1995
2129
|
if (schema)
|
|
1996
2130
|
schemaFields["where"] = schema;
|
|
1997
2131
|
forcedWhere = forced;
|
|
2132
|
+
forcedOnlyWhereKeys = forcedOnlyKeys;
|
|
1998
2133
|
}
|
|
1999
2134
|
if (shape.include) {
|
|
2000
2135
|
const result = projectionBuilder.buildIncludeSchema(model, shape.include);
|
|
@@ -2004,7 +2139,10 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2004
2139
|
}
|
|
2005
2140
|
if (shape.select) {
|
|
2006
2141
|
if (method === "count") {
|
|
2007
|
-
schemaFields["select"] = argsBuilder.buildCountSelectSchema(
|
|
2142
|
+
schemaFields["select"] = argsBuilder.buildCountSelectSchema(
|
|
2143
|
+
model,
|
|
2144
|
+
shape.select
|
|
2145
|
+
);
|
|
2008
2146
|
} else {
|
|
2009
2147
|
const result = projectionBuilder.buildSelectSchema(model, shape.select);
|
|
2010
2148
|
schemaFields["select"] = result.schema;
|
|
@@ -2013,9 +2151,15 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2013
2151
|
}
|
|
2014
2152
|
}
|
|
2015
2153
|
if (shape.orderBy)
|
|
2016
|
-
schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
|
|
2154
|
+
schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
|
|
2155
|
+
model,
|
|
2156
|
+
shape.orderBy
|
|
2157
|
+
);
|
|
2017
2158
|
if (shape.cursor)
|
|
2018
|
-
schemaFields["cursor"] = argsBuilder.buildCursorSchema(
|
|
2159
|
+
schemaFields["cursor"] = argsBuilder.buildCursorSchema(
|
|
2160
|
+
model,
|
|
2161
|
+
shape.cursor
|
|
2162
|
+
);
|
|
2019
2163
|
if (shape.take)
|
|
2020
2164
|
schemaFields["take"] = argsBuilder.buildTakeSchema(shape.take);
|
|
2021
2165
|
if (shape.skip !== void 0) {
|
|
@@ -2025,24 +2169,51 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2025
2169
|
schemaFields["skip"] = z7.number().int().min(0).optional();
|
|
2026
2170
|
}
|
|
2027
2171
|
if (shape.distinct)
|
|
2028
|
-
schemaFields["distinct"] = argsBuilder.buildDistinctSchema(
|
|
2172
|
+
schemaFields["distinct"] = argsBuilder.buildDistinctSchema(
|
|
2173
|
+
model,
|
|
2174
|
+
shape.distinct
|
|
2175
|
+
);
|
|
2029
2176
|
if (shape._count)
|
|
2030
|
-
schemaFields["_count"] = argsBuilder.buildCountFieldSchema(
|
|
2177
|
+
schemaFields["_count"] = argsBuilder.buildCountFieldSchema(
|
|
2178
|
+
model,
|
|
2179
|
+
shape._count,
|
|
2180
|
+
"_count"
|
|
2181
|
+
);
|
|
2031
2182
|
if (shape._avg)
|
|
2032
|
-
schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(
|
|
2183
|
+
schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(
|
|
2184
|
+
model,
|
|
2185
|
+
"_avg",
|
|
2186
|
+
shape._avg
|
|
2187
|
+
);
|
|
2033
2188
|
if (shape._sum)
|
|
2034
|
-
schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(
|
|
2189
|
+
schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(
|
|
2190
|
+
model,
|
|
2191
|
+
"_sum",
|
|
2192
|
+
shape._sum
|
|
2193
|
+
);
|
|
2035
2194
|
if (shape._min)
|
|
2036
|
-
schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(
|
|
2195
|
+
schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(
|
|
2196
|
+
model,
|
|
2197
|
+
"_min",
|
|
2198
|
+
shape._min
|
|
2199
|
+
);
|
|
2037
2200
|
if (shape._max)
|
|
2038
|
-
schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(
|
|
2201
|
+
schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(
|
|
2202
|
+
model,
|
|
2203
|
+
"_max",
|
|
2204
|
+
shape._max
|
|
2205
|
+
);
|
|
2039
2206
|
if (shape.by)
|
|
2040
2207
|
schemaFields["by"] = argsBuilder.buildBySchema(model, shape.by);
|
|
2041
2208
|
if (shape.having)
|
|
2042
|
-
schemaFields["having"] = argsBuilder.buildHavingSchema(
|
|
2209
|
+
schemaFields["having"] = argsBuilder.buildHavingSchema(
|
|
2210
|
+
model,
|
|
2211
|
+
shape.having
|
|
2212
|
+
);
|
|
2043
2213
|
return {
|
|
2044
2214
|
zodSchema: z7.object(schemaFields).strict(),
|
|
2045
2215
|
forcedWhere,
|
|
2216
|
+
forcedOnlyWhereKeys,
|
|
2046
2217
|
forcedIncludeTree,
|
|
2047
2218
|
forcedSelectTree,
|
|
2048
2219
|
forcedIncludeCountWhere,
|
|
@@ -2059,17 +2230,27 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2059
2230
|
const isSingle = typeof config === "function" || isShapeConfig(config);
|
|
2060
2231
|
const builtCache = /* @__PURE__ */ new Map();
|
|
2061
2232
|
if (isSingle && typeof config !== "function") {
|
|
2062
|
-
builtCache.set(
|
|
2233
|
+
builtCache.set(
|
|
2234
|
+
"_default",
|
|
2235
|
+
buildShapeZodSchema(model, method, config)
|
|
2236
|
+
);
|
|
2063
2237
|
}
|
|
2064
2238
|
if (!isSingle) {
|
|
2065
2239
|
for (const key of Object.keys(config)) {
|
|
2066
2240
|
if (SHAPE_CONFIG_KEYS.has(key)) {
|
|
2067
|
-
throw new ShapeError(
|
|
2241
|
+
throw new ShapeError(
|
|
2242
|
+
`Caller key "${key}" collides with reserved shape config key. Rename the caller path.`
|
|
2243
|
+
);
|
|
2068
2244
|
}
|
|
2069
2245
|
}
|
|
2070
|
-
for (const [key, shapeOrFn] of Object.entries(
|
|
2246
|
+
for (const [key, shapeOrFn] of Object.entries(
|
|
2247
|
+
config
|
|
2248
|
+
)) {
|
|
2071
2249
|
if (typeof shapeOrFn !== "function") {
|
|
2072
|
-
builtCache.set(
|
|
2250
|
+
builtCache.set(
|
|
2251
|
+
key,
|
|
2252
|
+
buildShapeZodSchema(model, method, shapeOrFn)
|
|
2253
|
+
);
|
|
2073
2254
|
}
|
|
2074
2255
|
}
|
|
2075
2256
|
}
|
|
@@ -2098,14 +2279,21 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
|
|
|
2098
2279
|
}
|
|
2099
2280
|
const caller = opts?.caller;
|
|
2100
2281
|
if (typeof caller !== "string") {
|
|
2101
|
-
const allowed = Object.keys(
|
|
2282
|
+
const allowed = Object.keys(
|
|
2283
|
+
config
|
|
2284
|
+
);
|
|
2102
2285
|
throw new CallerError(
|
|
2103
2286
|
`Missing caller. This query uses named shape routing with keys: ${allowed.map((k) => `"${k}"`).join(", ")}. Provide caller via opts.caller.`
|
|
2104
2287
|
);
|
|
2105
2288
|
}
|
|
2106
|
-
const matched = matchCaller(
|
|
2289
|
+
const matched = matchCaller(
|
|
2290
|
+
config,
|
|
2291
|
+
caller
|
|
2292
|
+
);
|
|
2107
2293
|
if (!matched) {
|
|
2108
|
-
const allowed = Object.keys(
|
|
2294
|
+
const allowed = Object.keys(
|
|
2295
|
+
config
|
|
2296
|
+
);
|
|
2109
2297
|
throw new CallerError(
|
|
2110
2298
|
`Unknown caller: "${caller}". Allowed: ${allowed.map((k) => `"${k}"`).join(", ")}`
|
|
2111
2299
|
);
|
|
@@ -2738,7 +2926,10 @@ function resolveShape(input, body, contextFn, caller) {
|
|
|
2738
2926
|
|
|
2739
2927
|
// src/runtime/model-guard.ts
|
|
2740
2928
|
var UNIQUE_MUTATION_METHODS = /* @__PURE__ */ new Set(["update", "delete", "upsert"]);
|
|
2741
|
-
var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set([
|
|
2929
|
+
var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set([
|
|
2930
|
+
"findUnique",
|
|
2931
|
+
"findUniqueOrThrow"
|
|
2932
|
+
]);
|
|
2742
2933
|
var BULK_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
2743
2934
|
"updateMany",
|
|
2744
2935
|
"updateManyAndReturn",
|
|
@@ -2752,15 +2943,14 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
|
|
|
2752
2943
|
"createManyAndReturn",
|
|
2753
2944
|
"updateManyAndReturn"
|
|
2754
2945
|
]);
|
|
2755
|
-
var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set([
|
|
2756
|
-
"createMany",
|
|
2757
|
-
"createManyAndReturn"
|
|
2758
|
-
]);
|
|
2946
|
+
var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set(["createMany", "createManyAndReturn"]);
|
|
2759
2947
|
function buildDefaultSelectInput(config) {
|
|
2760
2948
|
const result = {};
|
|
2761
2949
|
for (const [key, value] of Object.entries(config)) {
|
|
2762
2950
|
if (key === "_count") {
|
|
2763
|
-
result[key] = buildDefaultCountInput(
|
|
2951
|
+
result[key] = buildDefaultCountInput(
|
|
2952
|
+
value
|
|
2953
|
+
);
|
|
2764
2954
|
continue;
|
|
2765
2955
|
}
|
|
2766
2956
|
if (value === true) {
|
|
@@ -2778,7 +2968,9 @@ function buildDefaultIncludeInput(config) {
|
|
|
2778
2968
|
const result = {};
|
|
2779
2969
|
for (const [key, value] of Object.entries(config)) {
|
|
2780
2970
|
if (key === "_count") {
|
|
2781
|
-
result[key] = buildDefaultCountInput(
|
|
2971
|
+
result[key] = buildDefaultCountInput(
|
|
2972
|
+
value
|
|
2973
|
+
);
|
|
2782
2974
|
continue;
|
|
2783
2975
|
}
|
|
2784
2976
|
if (value === true) {
|
|
@@ -2892,12 +3084,32 @@ function hasNestedClientControlledArgs(shape) {
|
|
|
2892
3084
|
return false;
|
|
2893
3085
|
}
|
|
2894
3086
|
function createModelGuardExtension(config) {
|
|
2895
|
-
const {
|
|
3087
|
+
const {
|
|
3088
|
+
typeMap,
|
|
3089
|
+
enumMap,
|
|
3090
|
+
zodChains,
|
|
3091
|
+
zodDefaults,
|
|
3092
|
+
uniqueMap,
|
|
3093
|
+
scopeMap,
|
|
3094
|
+
guardConfig,
|
|
3095
|
+
contextFn
|
|
3096
|
+
} = config;
|
|
2896
3097
|
const wrapZodErrors = config.wrapZodErrors ?? false;
|
|
2897
3098
|
const enforceProjection = guardConfig.enforceProjection ?? false;
|
|
2898
3099
|
const scalarBase = createScalarBase(guardConfig.strictDecimal ?? false);
|
|
2899
|
-
const schemaBuilder = createSchemaBuilder(
|
|
2900
|
-
|
|
3100
|
+
const schemaBuilder = createSchemaBuilder(
|
|
3101
|
+
typeMap,
|
|
3102
|
+
zodChains,
|
|
3103
|
+
enumMap,
|
|
3104
|
+
scalarBase,
|
|
3105
|
+
zodDefaults
|
|
3106
|
+
);
|
|
3107
|
+
const queryBuilder = createQueryBuilder(
|
|
3108
|
+
typeMap,
|
|
3109
|
+
enumMap,
|
|
3110
|
+
uniqueMap,
|
|
3111
|
+
scalarBase
|
|
3112
|
+
);
|
|
2901
3113
|
const modelScopeFks = /* @__PURE__ */ new Map();
|
|
2902
3114
|
for (const [model, entries] of Object.entries(scopeMap)) {
|
|
2903
3115
|
const fks = /* @__PURE__ */ new Set();
|
|
@@ -2915,7 +3127,9 @@ function createModelGuardExtension(config) {
|
|
|
2915
3127
|
function createGuardedMethods(modelName, modelDelegate, input, explicitCaller) {
|
|
2916
3128
|
function callDelegate(method, args) {
|
|
2917
3129
|
if (typeof modelDelegate[method] !== "function") {
|
|
2918
|
-
throw new ShapeError(
|
|
3130
|
+
throw new ShapeError(
|
|
3131
|
+
`Method "${method}" is not available on this model`
|
|
3132
|
+
);
|
|
2919
3133
|
}
|
|
2920
3134
|
return modelDelegate[method](args);
|
|
2921
3135
|
}
|
|
@@ -2938,11 +3152,19 @@ function createModelGuardExtension(config) {
|
|
|
2938
3152
|
const cached = readShapeCache.get(cacheKey);
|
|
2939
3153
|
if (cached)
|
|
2940
3154
|
return cached;
|
|
2941
|
-
const built = queryBuilder.buildShapeZodSchema(
|
|
3155
|
+
const built = queryBuilder.buildShapeZodSchema(
|
|
3156
|
+
modelName,
|
|
3157
|
+
method,
|
|
3158
|
+
queryShape
|
|
3159
|
+
);
|
|
2942
3160
|
readShapeCache.set(cacheKey, built);
|
|
2943
3161
|
return built;
|
|
2944
3162
|
}
|
|
2945
|
-
return queryBuilder.buildShapeZodSchema(
|
|
3163
|
+
return queryBuilder.buildShapeZodSchema(
|
|
3164
|
+
modelName,
|
|
3165
|
+
method,
|
|
3166
|
+
queryShape
|
|
3167
|
+
);
|
|
2946
3168
|
}
|
|
2947
3169
|
function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
|
|
2948
3170
|
if (!wasDynamic && !hasDataRefines(dataConfig)) {
|
|
@@ -2950,11 +3172,25 @@ function createModelGuardExtension(config) {
|
|
|
2950
3172
|
const cached = dataSchemaCache.get(cacheKey);
|
|
2951
3173
|
if (cached)
|
|
2952
3174
|
return cached;
|
|
2953
|
-
const built = buildDataSchema(
|
|
3175
|
+
const built = buildDataSchema(
|
|
3176
|
+
modelName,
|
|
3177
|
+
dataConfig,
|
|
3178
|
+
mode,
|
|
3179
|
+
typeMap,
|
|
3180
|
+
schemaBuilder,
|
|
3181
|
+
zodDefaults
|
|
3182
|
+
);
|
|
2954
3183
|
dataSchemaCache.set(cacheKey, built);
|
|
2955
3184
|
return built;
|
|
2956
3185
|
}
|
|
2957
|
-
return buildDataSchema(
|
|
3186
|
+
return buildDataSchema(
|
|
3187
|
+
modelName,
|
|
3188
|
+
dataConfig,
|
|
3189
|
+
mode,
|
|
3190
|
+
typeMap,
|
|
3191
|
+
schemaBuilder,
|
|
3192
|
+
zodDefaults
|
|
3193
|
+
);
|
|
2958
3194
|
}
|
|
2959
3195
|
function getWhereBuilt(whereConfig, matchedKey, wasDynamic) {
|
|
2960
3196
|
if (!wasDynamic) {
|
|
@@ -3073,12 +3309,28 @@ function createModelGuardExtension(config) {
|
|
|
3073
3309
|
const built = getWhereBuilt(shape.where, matchedKey, wasDynamic);
|
|
3074
3310
|
let validatedWhere;
|
|
3075
3311
|
if (built.schema) {
|
|
3076
|
-
|
|
3312
|
+
let sanitizedWhere = bodyWhere;
|
|
3313
|
+
if (built.forcedOnlyKeys.size > 0 && isPlainObject(bodyWhere)) {
|
|
3314
|
+
const w = { ...bodyWhere };
|
|
3315
|
+
for (const key of built.forcedOnlyKeys) {
|
|
3316
|
+
delete w[key];
|
|
3317
|
+
}
|
|
3318
|
+
sanitizedWhere = w;
|
|
3319
|
+
}
|
|
3320
|
+
validatedWhere = built.schema.parse(sanitizedWhere);
|
|
3077
3321
|
} else if (bodyWhere !== void 0) {
|
|
3078
3322
|
if (bodyWhere === null || !isPlainObject(bodyWhere) || Object.keys(bodyWhere).length > 0) {
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3323
|
+
let hasOnlyForcedKeys = false;
|
|
3324
|
+
if (isPlainObject(bodyWhere) && built.forcedOnlyKeys.size > 0) {
|
|
3325
|
+
hasOnlyForcedKeys = Object.keys(bodyWhere).every(
|
|
3326
|
+
(k) => built.forcedOnlyKeys.has(k)
|
|
3327
|
+
);
|
|
3328
|
+
}
|
|
3329
|
+
if (!hasOnlyForcedKeys) {
|
|
3330
|
+
throw new ShapeError(
|
|
3331
|
+
"Guard shape where contains only forced conditions. Client where input is not accepted."
|
|
3332
|
+
);
|
|
3333
|
+
}
|
|
3082
3334
|
}
|
|
3083
3335
|
}
|
|
3084
3336
|
if (hasWhereForced(built.forced)) {
|
|
@@ -3087,7 +3339,13 @@ function createModelGuardExtension(config) {
|
|
|
3087
3339
|
return validatedWhere ?? {};
|
|
3088
3340
|
}
|
|
3089
3341
|
function requireWhere(shape, bodyWhere, method, preserveUnique, matchedKey, wasDynamic) {
|
|
3090
|
-
const where = buildWhereFromShape(
|
|
3342
|
+
const where = buildWhereFromShape(
|
|
3343
|
+
shape,
|
|
3344
|
+
bodyWhere,
|
|
3345
|
+
preserveUnique,
|
|
3346
|
+
matchedKey,
|
|
3347
|
+
wasDynamic
|
|
3348
|
+
);
|
|
3091
3349
|
if (Object.keys(where).length === 0) {
|
|
3092
3350
|
throw new ShapeError(`${method} requires a where condition`);
|
|
3093
3351
|
}
|
|
@@ -3101,7 +3359,12 @@ function createModelGuardExtension(config) {
|
|
|
3101
3359
|
throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
|
|
3102
3360
|
}
|
|
3103
3361
|
const { data: _, ...queryShape } = resolved.shape;
|
|
3104
|
-
const built = getReadShape(
|
|
3362
|
+
const built = getReadShape(
|
|
3363
|
+
method,
|
|
3364
|
+
queryShape,
|
|
3365
|
+
resolved.matchedKey,
|
|
3366
|
+
resolved.wasDynamic
|
|
3367
|
+
);
|
|
3105
3368
|
const isUnique = UNIQUE_READ_METHODS.has(method);
|
|
3106
3369
|
const args = applyBuiltShape(built, resolved.body, isUnique);
|
|
3107
3370
|
if (isUnique && args.where) {
|
|
@@ -3134,14 +3397,33 @@ function createModelGuardExtension(config) {
|
|
|
3134
3397
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
3135
3398
|
if (!resolved.shape.data)
|
|
3136
3399
|
throw new ShapeError(`Guard shape requires "data" for ${method}`);
|
|
3137
|
-
validateMutationShapeKeys(
|
|
3400
|
+
validateMutationShapeKeys(
|
|
3401
|
+
resolved.shape,
|
|
3402
|
+
allowedShapeKeys,
|
|
3403
|
+
method
|
|
3404
|
+
);
|
|
3138
3405
|
validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
|
|
3139
3406
|
const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
|
|
3140
|
-
validateCreateCompleteness(
|
|
3141
|
-
|
|
3407
|
+
validateCreateCompleteness(
|
|
3408
|
+
modelName,
|
|
3409
|
+
resolved.shape.data,
|
|
3410
|
+
typeMap,
|
|
3411
|
+
fks,
|
|
3412
|
+
zodDefaults
|
|
3413
|
+
);
|
|
3414
|
+
const dataSchema = getDataSchema(
|
|
3415
|
+
"create",
|
|
3416
|
+
resolved.shape.data,
|
|
3417
|
+
resolved.matchedKey,
|
|
3418
|
+
resolved.wasDynamic
|
|
3419
|
+
);
|
|
3142
3420
|
let args;
|
|
3143
3421
|
if (method === "create") {
|
|
3144
|
-
const data = validateAndMergeData(
|
|
3422
|
+
const data = validateAndMergeData(
|
|
3423
|
+
resolved.body.data,
|
|
3424
|
+
dataSchema,
|
|
3425
|
+
method
|
|
3426
|
+
);
|
|
3145
3427
|
args = { data };
|
|
3146
3428
|
} else {
|
|
3147
3429
|
if (!Array.isArray(resolved.body.data))
|
|
@@ -3160,7 +3442,13 @@ function createModelGuardExtension(config) {
|
|
|
3160
3442
|
args.skipDuplicates = resolved.body.skipDuplicates;
|
|
3161
3443
|
}
|
|
3162
3444
|
if (supportsProjection) {
|
|
3163
|
-
const projectionArgs = resolveProjection(
|
|
3445
|
+
const projectionArgs = resolveProjection(
|
|
3446
|
+
resolved.shape,
|
|
3447
|
+
resolved.body,
|
|
3448
|
+
method,
|
|
3449
|
+
resolved.matchedKey,
|
|
3450
|
+
resolved.wasDynamic
|
|
3451
|
+
);
|
|
3164
3452
|
Object.assign(args, projectionArgs);
|
|
3165
3453
|
}
|
|
3166
3454
|
return callDelegate(method, args);
|
|
@@ -3177,24 +3465,60 @@ function createModelGuardExtension(config) {
|
|
|
3177
3465
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
3178
3466
|
if (!resolved.shape.data)
|
|
3179
3467
|
throw new ShapeError(`Guard shape requires "data" for ${method}`);
|
|
3180
|
-
validateMutationShapeKeys(
|
|
3468
|
+
validateMutationShapeKeys(
|
|
3469
|
+
resolved.shape,
|
|
3470
|
+
allowedShapeKeys,
|
|
3471
|
+
method
|
|
3472
|
+
);
|
|
3181
3473
|
validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
|
|
3182
3474
|
if (isBulk && !resolved.shape.where) {
|
|
3183
|
-
throw new ShapeError(
|
|
3475
|
+
throw new ShapeError(
|
|
3476
|
+
`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
|
|
3477
|
+
);
|
|
3184
3478
|
}
|
|
3185
3479
|
maybeValidateUniqueWhere(modelName, resolved.shape, method);
|
|
3186
|
-
const dataSchema = getDataSchema(
|
|
3187
|
-
|
|
3188
|
-
|
|
3480
|
+
const dataSchema = getDataSchema(
|
|
3481
|
+
"update",
|
|
3482
|
+
resolved.shape.data,
|
|
3483
|
+
resolved.matchedKey,
|
|
3484
|
+
resolved.wasDynamic
|
|
3485
|
+
);
|
|
3486
|
+
const data = validateAndMergeData(
|
|
3487
|
+
resolved.body.data,
|
|
3488
|
+
dataSchema,
|
|
3489
|
+
method
|
|
3490
|
+
);
|
|
3491
|
+
const where = isUniqueWhere ? requireWhere(
|
|
3492
|
+
resolved.shape,
|
|
3493
|
+
resolved.body.where,
|
|
3494
|
+
method,
|
|
3495
|
+
true,
|
|
3496
|
+
resolved.matchedKey,
|
|
3497
|
+
resolved.wasDynamic
|
|
3498
|
+
) : buildWhereFromShape(
|
|
3499
|
+
resolved.shape,
|
|
3500
|
+
resolved.body.where,
|
|
3501
|
+
false,
|
|
3502
|
+
resolved.matchedKey,
|
|
3503
|
+
resolved.wasDynamic
|
|
3504
|
+
);
|
|
3189
3505
|
if (isBulk && Object.keys(where).length === 0) {
|
|
3190
|
-
throw new ShapeError(
|
|
3506
|
+
throw new ShapeError(
|
|
3507
|
+
`${method} requires at least one where condition`
|
|
3508
|
+
);
|
|
3191
3509
|
}
|
|
3192
3510
|
if (isUniqueWhere) {
|
|
3193
3511
|
validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
|
|
3194
3512
|
}
|
|
3195
3513
|
const args = { data, where };
|
|
3196
3514
|
if (supportsProjection) {
|
|
3197
|
-
const projectionArgs = resolveProjection(
|
|
3515
|
+
const projectionArgs = resolveProjection(
|
|
3516
|
+
resolved.shape,
|
|
3517
|
+
resolved.body,
|
|
3518
|
+
method,
|
|
3519
|
+
resolved.matchedKey,
|
|
3520
|
+
resolved.wasDynamic
|
|
3521
|
+
);
|
|
3198
3522
|
Object.assign(args, projectionArgs);
|
|
3199
3523
|
}
|
|
3200
3524
|
return callDelegate(method, args);
|
|
@@ -3211,22 +3535,49 @@ function createModelGuardExtension(config) {
|
|
|
3211
3535
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
3212
3536
|
if (resolved.shape.data)
|
|
3213
3537
|
throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
|
|
3214
|
-
validateMutationShapeKeys(
|
|
3538
|
+
validateMutationShapeKeys(
|
|
3539
|
+
resolved.shape,
|
|
3540
|
+
allowedShapeKeys,
|
|
3541
|
+
method
|
|
3542
|
+
);
|
|
3215
3543
|
validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
|
|
3216
3544
|
if (isBulk && !resolved.shape.where) {
|
|
3217
|
-
throw new ShapeError(
|
|
3545
|
+
throw new ShapeError(
|
|
3546
|
+
`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
|
|
3547
|
+
);
|
|
3218
3548
|
}
|
|
3219
3549
|
maybeValidateUniqueWhere(modelName, resolved.shape, method);
|
|
3220
|
-
const where = isUniqueWhere ? requireWhere(
|
|
3550
|
+
const where = isUniqueWhere ? requireWhere(
|
|
3551
|
+
resolved.shape,
|
|
3552
|
+
resolved.body.where,
|
|
3553
|
+
method,
|
|
3554
|
+
true,
|
|
3555
|
+
resolved.matchedKey,
|
|
3556
|
+
resolved.wasDynamic
|
|
3557
|
+
) : buildWhereFromShape(
|
|
3558
|
+
resolved.shape,
|
|
3559
|
+
resolved.body.where,
|
|
3560
|
+
false,
|
|
3561
|
+
resolved.matchedKey,
|
|
3562
|
+
resolved.wasDynamic
|
|
3563
|
+
);
|
|
3221
3564
|
if (isBulk && Object.keys(where).length === 0) {
|
|
3222
|
-
throw new ShapeError(
|
|
3565
|
+
throw new ShapeError(
|
|
3566
|
+
`${method} requires at least one where condition`
|
|
3567
|
+
);
|
|
3223
3568
|
}
|
|
3224
3569
|
if (isUniqueWhere) {
|
|
3225
3570
|
validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
|
|
3226
3571
|
}
|
|
3227
3572
|
const args = { where };
|
|
3228
3573
|
if (supportsProjection) {
|
|
3229
|
-
const projectionArgs = resolveProjection(
|
|
3574
|
+
const projectionArgs = resolveProjection(
|
|
3575
|
+
resolved.shape,
|
|
3576
|
+
resolved.body,
|
|
3577
|
+
method,
|
|
3578
|
+
resolved.matchedKey,
|
|
3579
|
+
resolved.wasDynamic
|
|
3580
|
+
);
|
|
3230
3581
|
Object.assign(args, projectionArgs);
|
|
3231
3582
|
}
|
|
3232
3583
|
return callDelegate(method, args);
|
|
@@ -3237,7 +3588,9 @@ function createModelGuardExtension(config) {
|
|
|
3237
3588
|
const caller = resolveCaller();
|
|
3238
3589
|
const resolved = resolveShape(input, body, contextFn, caller);
|
|
3239
3590
|
if (resolved.shape.data) {
|
|
3240
|
-
throw new ShapeError(
|
|
3591
|
+
throw new ShapeError(
|
|
3592
|
+
'Guard shape "data" is not valid for upsert. Use "create" and "update" instead.'
|
|
3593
|
+
);
|
|
3241
3594
|
}
|
|
3242
3595
|
if (!resolved.shape.create) {
|
|
3243
3596
|
throw new ShapeError('Guard shape requires "create" for upsert');
|
|
@@ -3253,24 +3606,42 @@ function createModelGuardExtension(config) {
|
|
|
3253
3606
|
VALID_SHAPE_KEYS_UPSERT,
|
|
3254
3607
|
"upsert"
|
|
3255
3608
|
);
|
|
3256
|
-
validateMutationBodyKeys(
|
|
3609
|
+
validateMutationBodyKeys(
|
|
3610
|
+
resolved.body,
|
|
3611
|
+
ALLOWED_BODY_KEYS_UPSERT,
|
|
3612
|
+
"upsert"
|
|
3613
|
+
);
|
|
3257
3614
|
maybeValidateUniqueWhere(modelName, resolved.shape, "upsert");
|
|
3258
3615
|
const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
|
|
3259
|
-
validateCreateCompleteness(
|
|
3616
|
+
validateCreateCompleteness(
|
|
3617
|
+
modelName,
|
|
3618
|
+
resolved.shape.create,
|
|
3619
|
+
typeMap,
|
|
3620
|
+
fks,
|
|
3621
|
+
zodDefaults
|
|
3622
|
+
);
|
|
3260
3623
|
const createDataSchema = getDataSchema(
|
|
3261
3624
|
"create",
|
|
3262
3625
|
resolved.shape.create,
|
|
3263
3626
|
`upsert:create\0${resolved.matchedKey}`,
|
|
3264
3627
|
resolved.wasDynamic
|
|
3265
3628
|
);
|
|
3266
|
-
const createData = validateAndMergeData(
|
|
3629
|
+
const createData = validateAndMergeData(
|
|
3630
|
+
resolved.body.create,
|
|
3631
|
+
createDataSchema,
|
|
3632
|
+
"upsert (create)"
|
|
3633
|
+
);
|
|
3267
3634
|
const updateDataSchema = getDataSchema(
|
|
3268
3635
|
"update",
|
|
3269
3636
|
resolved.shape.update,
|
|
3270
3637
|
`upsert:update\0${resolved.matchedKey}`,
|
|
3271
3638
|
resolved.wasDynamic
|
|
3272
3639
|
);
|
|
3273
|
-
const updateData = validateAndMergeData(
|
|
3640
|
+
const updateData = validateAndMergeData(
|
|
3641
|
+
resolved.body.update,
|
|
3642
|
+
updateDataSchema,
|
|
3643
|
+
"upsert (update)"
|
|
3644
|
+
);
|
|
3274
3645
|
const where = requireWhere(
|
|
3275
3646
|
resolved.shape,
|
|
3276
3647
|
resolved.body.where,
|
|
@@ -3324,10 +3695,9 @@ function createModelGuardExtension(config) {
|
|
|
3324
3695
|
return fn(body);
|
|
3325
3696
|
} catch (err) {
|
|
3326
3697
|
if (err instanceof z9.ZodError) {
|
|
3327
|
-
throw new ShapeError(
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
);
|
|
3698
|
+
throw new ShapeError(`Validation failed: ${formatZodError(err)}`, {
|
|
3699
|
+
cause: err
|
|
3700
|
+
});
|
|
3331
3701
|
}
|
|
3332
3702
|
throw err;
|
|
3333
3703
|
}
|
|
@@ -3346,7 +3716,12 @@ function createModelGuardExtension(config) {
|
|
|
3346
3716
|
`Could not resolve Prisma delegate for model "${modelName}" (key: "${delegateKey}")`
|
|
3347
3717
|
);
|
|
3348
3718
|
}
|
|
3349
|
-
const methods = createGuardedMethods(
|
|
3719
|
+
const methods = createGuardedMethods(
|
|
3720
|
+
modelName,
|
|
3721
|
+
modelDelegate,
|
|
3722
|
+
input,
|
|
3723
|
+
caller
|
|
3724
|
+
);
|
|
3350
3725
|
if (!wrapZodErrors)
|
|
3351
3726
|
return methods;
|
|
3352
3727
|
return wrapMethods(methods);
|