prisma-guard 1.4.0 → 1.5.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.
@@ -734,7 +734,24 @@ function mergeUniqueWhereForced(where, forced) {
734
734
  return result;
735
735
  }
736
736
  function applyBuiltShape(built, body, isUniqueMethod) {
737
- const validated = built.zodSchema.parse(body);
737
+ let parseable = body;
738
+ if (built.forcedOnlyWhereKeys.size > 0 && isPlainObject(body)) {
739
+ const bodyObj = body;
740
+ if (isPlainObject(bodyObj.where)) {
741
+ const where = { ...bodyObj.where };
742
+ let stripped = false;
743
+ for (const key of built.forcedOnlyWhereKeys) {
744
+ if (key in where) {
745
+ delete where[key];
746
+ stripped = true;
747
+ }
748
+ }
749
+ if (stripped) {
750
+ parseable = { ...bodyObj, where };
751
+ }
752
+ }
753
+ }
754
+ const validated = built.zodSchema.parse(parseable);
738
755
  if (hasWhereForced(built.forcedWhere)) {
739
756
  validated.where = isUniqueMethod ? mergeUniqueWhereForced(
740
757
  validated.where,
@@ -958,7 +975,12 @@ function validateUniqueEquality(model, where, method, uniqueMap, typeMap) {
958
975
 
959
976
  // src/runtime/query-builder-where.ts
960
977
  var UNSUPPORTED_WHERE_TYPES = /* @__PURE__ */ new Set(["Json", "Bytes"]);
961
- var STRING_MODE_OPS = /* @__PURE__ */ new Set(["contains", "startsWith", "endsWith", "equals"]);
978
+ var STRING_MODE_OPS = /* @__PURE__ */ new Set([
979
+ "contains",
980
+ "startsWith",
981
+ "endsWith",
982
+ "equals"
983
+ ]);
962
984
  var MAX_WHERE_DEPTH = 10;
963
985
  function safeStringify(v) {
964
986
  if (typeof v === "bigint")
@@ -1028,9 +1050,7 @@ function mergeScalarConditions(target, source) {
1028
1050
  continue;
1029
1051
  }
1030
1052
  if (!forcedValuesEqual(existing, ops)) {
1031
- throw new ShapeError(
1032
- `Conflicting forced where values for "${field}"`
1033
- );
1053
+ throw new ShapeError(`Conflicting forced where values for "${field}"`);
1034
1054
  }
1035
1055
  }
1036
1056
  }
@@ -1044,8 +1064,14 @@ function mergeRelationForcedMaps(target, source) {
1044
1064
  if (!target[relName][op]) {
1045
1065
  target[relName][op] = forced;
1046
1066
  } else {
1047
- mergeScalarConditions(target[relName][op].conditions, forced.conditions);
1048
- mergeRelationForcedMaps(target[relName][op].relations, forced.relations);
1067
+ mergeScalarConditions(
1068
+ target[relName][op].conditions,
1069
+ forced.conditions
1070
+ );
1071
+ mergeRelationForcedMaps(
1072
+ target[relName][op].relations,
1073
+ forced.relations
1074
+ );
1049
1075
  }
1050
1076
  }
1051
1077
  }
@@ -1097,20 +1123,38 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1097
1123
  `${fieldMeta.type} field "${key}" cannot be used in where filters`
1098
1124
  );
1099
1125
  }
1100
- processScalarField(key, value, model, fieldMeta, fieldSchemas, scalarConditions);
1126
+ processScalarField(
1127
+ key,
1128
+ value,
1129
+ model,
1130
+ fieldMeta,
1131
+ fieldSchemas,
1132
+ scalarConditions
1133
+ );
1101
1134
  }
1102
1135
  const schema = Object.keys(fieldSchemas).length > 0 ? import_zod4.z.object(fieldSchemas).strict().optional() : null;
1136
+ const forcedOnlyKeys = /* @__PURE__ */ new Set();
1137
+ for (const key of Object.keys(whereConfig)) {
1138
+ if (COMBINATOR_KEYS.has(key))
1139
+ continue;
1140
+ if (!(key in fieldSchemas)) {
1141
+ forcedOnlyKeys.add(key);
1142
+ }
1143
+ }
1103
1144
  return {
1104
1145
  schema,
1105
1146
  forced: {
1106
1147
  conditions: scalarConditions,
1107
1148
  relations: relationForced
1108
- }
1149
+ },
1150
+ forcedOnlyKeys
1109
1151
  };
1110
1152
  }
1111
1153
  function processCombinator(key, value, model, fieldSchemas, parentConditions, parentRelations, depth) {
1112
1154
  if (!isPlainObject(value)) {
1113
- throw new ShapeError(`"${key}" in where shape must be an object defining allowed fields`);
1155
+ throw new ShapeError(
1156
+ `"${key}" in where shape must be an object defining allowed fields`
1157
+ );
1114
1158
  }
1115
1159
  const result = buildWhereSchema(model, value, depth + 1);
1116
1160
  if (!result.schema && !hasWhereForced(result.forced)) {
@@ -1151,7 +1195,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1151
1195
  }
1152
1196
  function processRelationFilter(key, value, fieldMeta, model, fieldSchemas, parentRelations, depth) {
1153
1197
  if (!isPlainObject(value)) {
1154
- throw new ShapeError(`Relation filter for "${key}" must be an object with operators (some, every, none, is, isNot)`);
1198
+ throw new ShapeError(
1199
+ `Relation filter for "${key}" must be an object with operators (some, every, none, is, isNot)`
1200
+ );
1155
1201
  }
1156
1202
  const allowedOps = fieldMeta.isList ? TO_MANY_RELATION_OPS : TO_ONE_RELATION_OPS;
1157
1203
  if (Object.keys(value).length === 0) {
@@ -1184,7 +1230,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1184
1230
  if (!hasWhereForced(nested.forced)) {
1185
1231
  opSchemas[op] = nested.schema.refine(
1186
1232
  (v) => v === void 0 || Object.keys(v).length > 0,
1187
- { message: `Relation filter "${key}.${op}" requires at least one condition` }
1233
+ {
1234
+ message: `Relation filter "${key}.${op}" requires at least one condition`
1235
+ }
1188
1236
  );
1189
1237
  } else {
1190
1238
  opSchemas[op] = nested.schema;
@@ -1205,7 +1253,9 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1205
1253
  const opObjSchema = import_zod4.z.object(opSchemas).strict();
1206
1254
  if (Object.keys(opForced).length === 0) {
1207
1255
  fieldSchemas[key] = opObjSchema.refine(
1208
- (v) => clientOpKeys.some((k) => v[k] !== void 0),
1256
+ (v) => clientOpKeys.some(
1257
+ (k) => v[k] !== void 0
1258
+ ),
1209
1259
  { message: `At least one relation operator required for "${key}"` }
1210
1260
  ).optional();
1211
1261
  } else {
@@ -1227,9 +1277,21 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1227
1277
  let hasClientOps = false;
1228
1278
  let hasStringModeOp = false;
1229
1279
  const clientOpKeys = [];
1280
+ let modeConfigValue = void 0;
1281
+ let hasModeConfig = false;
1230
1282
  for (const [op, opValue] of Object.entries(operators)) {
1283
+ if (op === "mode") {
1284
+ hasModeConfig = true;
1285
+ modeConfigValue = opValue;
1286
+ continue;
1287
+ }
1231
1288
  if (opValue === true) {
1232
- opSchemas[op] = createOperatorSchema(fieldMeta, op, enumMap, scalarBase).optional();
1289
+ opSchemas[op] = createOperatorSchema(
1290
+ fieldMeta,
1291
+ op,
1292
+ enumMap,
1293
+ scalarBase
1294
+ ).optional();
1233
1295
  hasClientOps = true;
1234
1296
  clientOpKeys.push(op);
1235
1297
  if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
@@ -1237,7 +1299,12 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1237
1299
  }
1238
1300
  } else {
1239
1301
  const actualOpValue = isForcedValue(opValue) ? opValue.value : opValue;
1240
- const opSchema = createOperatorSchema(fieldMeta, op, enumMap, scalarBase);
1302
+ const opSchema = createOperatorSchema(
1303
+ fieldMeta,
1304
+ op,
1305
+ enumMap,
1306
+ scalarBase
1307
+ );
1241
1308
  let parsed;
1242
1309
  try {
1243
1310
  parsed = opSchema.parse(actualOpValue);
@@ -1247,21 +1314,54 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1247
1314
  );
1248
1315
  }
1249
1316
  fieldForced[op] = parsed;
1317
+ if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
1318
+ hasStringModeOp = true;
1319
+ }
1250
1320
  }
1251
1321
  }
1252
1322
  if (!hasClientOps && Object.keys(fieldForced).length === 0) {
1323
+ if (hasModeConfig) {
1324
+ throw new ShapeError(
1325
+ `Where field "${fieldName}" on model "${model}" has "mode" but no operators. Add at least one operator (contains, startsWith, endsWith, equals).`
1326
+ );
1327
+ }
1253
1328
  throw new ShapeError(
1254
1329
  `Empty operator config for where field "${fieldName}" on model "${model}". Define at least one operator.`
1255
1330
  );
1256
1331
  }
1257
- if (hasStringModeOp) {
1332
+ if (hasModeConfig) {
1333
+ if (!hasStringModeOp) {
1334
+ throw new ShapeError(
1335
+ `"mode" on where field "${fieldName}" on model "${model}" requires a compatible String operator (contains, startsWith, endsWith, equals)`
1336
+ );
1337
+ }
1338
+ if (modeConfigValue === true) {
1339
+ opSchemas["mode"] = import_zod4.z.enum(["default", "insensitive"]).optional();
1340
+ } else {
1341
+ const actualModeValue = isForcedValue(modeConfigValue) ? modeConfigValue.value : modeConfigValue;
1342
+ const modeSchema = import_zod4.z.enum(["default", "insensitive"]);
1343
+ let parsed;
1344
+ try {
1345
+ parsed = modeSchema.parse(actualModeValue);
1346
+ } catch (err) {
1347
+ throw new ShapeError(
1348
+ `Invalid forced value for "${model}.${fieldName}.mode": ${err.message}`
1349
+ );
1350
+ }
1351
+ fieldForced["mode"] = parsed;
1352
+ }
1353
+ } else if (hasStringModeOp) {
1258
1354
  opSchemas["mode"] = import_zod4.z.enum(["default", "insensitive"]).optional();
1259
1355
  }
1260
1356
  if (hasClientOps) {
1261
1357
  const opObj = import_zod4.z.object(opSchemas).strict();
1262
1358
  fieldSchemas[fieldName] = opObj.refine(
1263
- (v) => clientOpKeys.some((k) => v[k] !== void 0),
1264
- { message: `At least one operator required for where field "${fieldName}"` }
1359
+ (v) => clientOpKeys.some(
1360
+ (k) => v[k] !== void 0
1361
+ ),
1362
+ {
1363
+ message: `At least one operator required for where field "${fieldName}"`
1364
+ }
1265
1365
  ).optional();
1266
1366
  }
1267
1367
  if (Object.keys(fieldForced).length > 0) {
@@ -1927,19 +2027,77 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
1927
2027
 
1928
2028
  // src/runtime/query-builder.ts
1929
2029
  var METHOD_ALLOWED_ARGS = {
1930
- findMany: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
1931
- findFirst: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
1932
- findFirstOrThrow: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
2030
+ findMany: /* @__PURE__ */ new Set([
2031
+ "where",
2032
+ "include",
2033
+ "select",
2034
+ "orderBy",
2035
+ "cursor",
2036
+ "take",
2037
+ "skip",
2038
+ "distinct"
2039
+ ]),
2040
+ findFirst: /* @__PURE__ */ new Set([
2041
+ "where",
2042
+ "include",
2043
+ "select",
2044
+ "orderBy",
2045
+ "cursor",
2046
+ "take",
2047
+ "skip",
2048
+ "distinct"
2049
+ ]),
2050
+ findFirstOrThrow: /* @__PURE__ */ new Set([
2051
+ "where",
2052
+ "include",
2053
+ "select",
2054
+ "orderBy",
2055
+ "cursor",
2056
+ "take",
2057
+ "skip",
2058
+ "distinct"
2059
+ ]),
1933
2060
  findUnique: /* @__PURE__ */ new Set(["where", "include", "select"]),
1934
2061
  findUniqueOrThrow: /* @__PURE__ */ new Set(["where", "include", "select"]),
1935
2062
  count: /* @__PURE__ */ new Set(["where", "select", "cursor", "orderBy", "skip", "take"]),
1936
- aggregate: /* @__PURE__ */ new Set(["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"]),
1937
- groupBy: /* @__PURE__ */ new Set(["where", "by", "having", "_count", "_avg", "_sum", "_min", "_max", "orderBy", "take", "skip"])
2063
+ aggregate: /* @__PURE__ */ new Set([
2064
+ "where",
2065
+ "orderBy",
2066
+ "cursor",
2067
+ "take",
2068
+ "skip",
2069
+ "_count",
2070
+ "_avg",
2071
+ "_sum",
2072
+ "_min",
2073
+ "_max"
2074
+ ]),
2075
+ groupBy: /* @__PURE__ */ new Set([
2076
+ "where",
2077
+ "by",
2078
+ "having",
2079
+ "_count",
2080
+ "_avg",
2081
+ "_sum",
2082
+ "_min",
2083
+ "_max",
2084
+ "orderBy",
2085
+ "take",
2086
+ "skip"
2087
+ ])
1938
2088
  };
1939
- var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set(["findUnique", "findUniqueOrThrow"]);
2089
+ var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set([
2090
+ "findUnique",
2091
+ "findUniqueOrThrow"
2092
+ ]);
1940
2093
  function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1941
2094
  const whereBuilder = createWhereBuilder(typeMap, enumMap, scalarBase);
1942
- const argsBuilder = createArgsBuilder(typeMap, enumMap, uniqueMap, scalarBase);
2095
+ const argsBuilder = createArgsBuilder(
2096
+ typeMap,
2097
+ enumMap,
2098
+ uniqueMap,
2099
+ scalarBase
2100
+ );
1943
2101
  const projectionBuilder = createProjectionBuilder(typeMap, enumMap, {
1944
2102
  buildWhereSchema: whereBuilder.buildWhereSchema,
1945
2103
  buildOrderBySchema: argsBuilder.buildOrderBySchema,
@@ -1964,7 +2122,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1964
2122
  throw new ShapeError(`${method} shape must define "where"`);
1965
2123
  }
1966
2124
  if (shape.include && shape.select) {
1967
- throw new ShapeError('Shape config cannot define both "include" and "select".');
2125
+ throw new ShapeError(
2126
+ 'Shape config cannot define both "include" and "select".'
2127
+ );
1968
2128
  }
1969
2129
  if (method === "groupBy" && !shape.by)
1970
2130
  throw new ShapeError('groupBy shape must define "by"');
@@ -1980,7 +2140,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1980
2140
  const bySet = new Set(shape.by);
1981
2141
  for (const fieldName of Object.keys(shape.orderBy)) {
1982
2142
  if (!bySet.has(fieldName)) {
1983
- throw new ShapeError(`orderBy field "${fieldName}" must be included in "by" for groupBy`);
2143
+ throw new ShapeError(
2144
+ `orderBy field "${fieldName}" must be included in "by" for groupBy`
2145
+ );
1984
2146
  }
1985
2147
  }
1986
2148
  }
@@ -1988,7 +2150,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1988
2150
  const bySet = new Set(shape.by);
1989
2151
  for (const fieldName of Object.keys(shape.having)) {
1990
2152
  if (!bySet.has(fieldName)) {
1991
- throw new ShapeError(`having field "${fieldName}" must be included in "by" for groupBy`);
2153
+ throw new ShapeError(
2154
+ `having field "${fieldName}" must be included in "by" for groupBy`
2155
+ );
1992
2156
  }
1993
2157
  }
1994
2158
  }
@@ -2005,7 +2169,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2005
2169
  requireContext(ctx, "shape function");
2006
2170
  const result = shapeOrFn(ctx);
2007
2171
  if (!isPlainObject(result)) {
2008
- throw new ShapeError("Dynamic shape function must return a plain object");
2172
+ throw new ShapeError(
2173
+ "Dynamic shape function must return a plain object"
2174
+ );
2009
2175
  }
2010
2176
  return result;
2011
2177
  }
@@ -2016,15 +2182,20 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2016
2182
  validateUniqueWhere(model, method, shape);
2017
2183
  const schemaFields = {};
2018
2184
  let forcedWhere = EMPTY_WHERE_FORCED;
2185
+ let forcedOnlyWhereKeys = /* @__PURE__ */ new Set();
2019
2186
  let forcedIncludeTree = {};
2020
2187
  let forcedSelectTree = {};
2021
2188
  let forcedIncludeCountWhere = {};
2022
2189
  let forcedSelectCountWhere = {};
2023
2190
  if (shape.where) {
2024
- const { schema, forced } = whereBuilder.buildWhereSchema(model, shape.where);
2191
+ const { schema, forced, forcedOnlyKeys } = whereBuilder.buildWhereSchema(
2192
+ model,
2193
+ shape.where
2194
+ );
2025
2195
  if (schema)
2026
2196
  schemaFields["where"] = schema;
2027
2197
  forcedWhere = forced;
2198
+ forcedOnlyWhereKeys = forcedOnlyKeys;
2028
2199
  }
2029
2200
  if (shape.include) {
2030
2201
  const result = projectionBuilder.buildIncludeSchema(model, shape.include);
@@ -2034,7 +2205,10 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2034
2205
  }
2035
2206
  if (shape.select) {
2036
2207
  if (method === "count") {
2037
- schemaFields["select"] = argsBuilder.buildCountSelectSchema(model, shape.select);
2208
+ schemaFields["select"] = argsBuilder.buildCountSelectSchema(
2209
+ model,
2210
+ shape.select
2211
+ );
2038
2212
  } else {
2039
2213
  const result = projectionBuilder.buildSelectSchema(model, shape.select);
2040
2214
  schemaFields["select"] = result.schema;
@@ -2043,9 +2217,15 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2043
2217
  }
2044
2218
  }
2045
2219
  if (shape.orderBy)
2046
- schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(model, shape.orderBy);
2220
+ schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
2221
+ model,
2222
+ shape.orderBy
2223
+ );
2047
2224
  if (shape.cursor)
2048
- schemaFields["cursor"] = argsBuilder.buildCursorSchema(model, shape.cursor);
2225
+ schemaFields["cursor"] = argsBuilder.buildCursorSchema(
2226
+ model,
2227
+ shape.cursor
2228
+ );
2049
2229
  if (shape.take)
2050
2230
  schemaFields["take"] = argsBuilder.buildTakeSchema(shape.take);
2051
2231
  if (shape.skip !== void 0) {
@@ -2055,24 +2235,51 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2055
2235
  schemaFields["skip"] = import_zod7.z.number().int().min(0).optional();
2056
2236
  }
2057
2237
  if (shape.distinct)
2058
- schemaFields["distinct"] = argsBuilder.buildDistinctSchema(model, shape.distinct);
2238
+ schemaFields["distinct"] = argsBuilder.buildDistinctSchema(
2239
+ model,
2240
+ shape.distinct
2241
+ );
2059
2242
  if (shape._count)
2060
- schemaFields["_count"] = argsBuilder.buildCountFieldSchema(model, shape._count, "_count");
2243
+ schemaFields["_count"] = argsBuilder.buildCountFieldSchema(
2244
+ model,
2245
+ shape._count,
2246
+ "_count"
2247
+ );
2061
2248
  if (shape._avg)
2062
- schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(model, "_avg", shape._avg);
2249
+ schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(
2250
+ model,
2251
+ "_avg",
2252
+ shape._avg
2253
+ );
2063
2254
  if (shape._sum)
2064
- schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(model, "_sum", shape._sum);
2255
+ schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(
2256
+ model,
2257
+ "_sum",
2258
+ shape._sum
2259
+ );
2065
2260
  if (shape._min)
2066
- schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(model, "_min", shape._min);
2261
+ schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(
2262
+ model,
2263
+ "_min",
2264
+ shape._min
2265
+ );
2067
2266
  if (shape._max)
2068
- schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(model, "_max", shape._max);
2267
+ schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(
2268
+ model,
2269
+ "_max",
2270
+ shape._max
2271
+ );
2069
2272
  if (shape.by)
2070
2273
  schemaFields["by"] = argsBuilder.buildBySchema(model, shape.by);
2071
2274
  if (shape.having)
2072
- schemaFields["having"] = argsBuilder.buildHavingSchema(model, shape.having);
2275
+ schemaFields["having"] = argsBuilder.buildHavingSchema(
2276
+ model,
2277
+ shape.having
2278
+ );
2073
2279
  return {
2074
2280
  zodSchema: import_zod7.z.object(schemaFields).strict(),
2075
2281
  forcedWhere,
2282
+ forcedOnlyWhereKeys,
2076
2283
  forcedIncludeTree,
2077
2284
  forcedSelectTree,
2078
2285
  forcedIncludeCountWhere,
@@ -2089,17 +2296,27 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2089
2296
  const isSingle = typeof config === "function" || isShapeConfig(config);
2090
2297
  const builtCache = /* @__PURE__ */ new Map();
2091
2298
  if (isSingle && typeof config !== "function") {
2092
- builtCache.set("_default", buildShapeZodSchema(model, method, config));
2299
+ builtCache.set(
2300
+ "_default",
2301
+ buildShapeZodSchema(model, method, config)
2302
+ );
2093
2303
  }
2094
2304
  if (!isSingle) {
2095
2305
  for (const key of Object.keys(config)) {
2096
2306
  if (SHAPE_CONFIG_KEYS.has(key)) {
2097
- throw new ShapeError(`Caller key "${key}" collides with reserved shape config key. Rename the caller path.`);
2307
+ throw new ShapeError(
2308
+ `Caller key "${key}" collides with reserved shape config key. Rename the caller path.`
2309
+ );
2098
2310
  }
2099
2311
  }
2100
- for (const [key, shapeOrFn] of Object.entries(config)) {
2312
+ for (const [key, shapeOrFn] of Object.entries(
2313
+ config
2314
+ )) {
2101
2315
  if (typeof shapeOrFn !== "function") {
2102
- builtCache.set(key, buildShapeZodSchema(model, method, shapeOrFn));
2316
+ builtCache.set(
2317
+ key,
2318
+ buildShapeZodSchema(model, method, shapeOrFn)
2319
+ );
2103
2320
  }
2104
2321
  }
2105
2322
  }
@@ -2128,14 +2345,21 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2128
2345
  }
2129
2346
  const caller = opts?.caller;
2130
2347
  if (typeof caller !== "string") {
2131
- const allowed = Object.keys(config);
2348
+ const allowed = Object.keys(
2349
+ config
2350
+ );
2132
2351
  throw new CallerError(
2133
2352
  `Missing caller. This query uses named shape routing with keys: ${allowed.map((k) => `"${k}"`).join(", ")}. Provide caller via opts.caller.`
2134
2353
  );
2135
2354
  }
2136
- const matched = matchCaller(config, caller);
2355
+ const matched = matchCaller(
2356
+ config,
2357
+ caller
2358
+ );
2137
2359
  if (!matched) {
2138
- const allowed = Object.keys(config);
2360
+ const allowed = Object.keys(
2361
+ config
2362
+ );
2139
2363
  throw new CallerError(
2140
2364
  `Unknown caller: "${caller}". Allowed: ${allowed.map((k) => `"${k}"`).join(", ")}`
2141
2365
  );
@@ -2768,7 +2992,10 @@ function resolveShape(input, body, contextFn, caller) {
2768
2992
 
2769
2993
  // src/runtime/model-guard.ts
2770
2994
  var UNIQUE_MUTATION_METHODS = /* @__PURE__ */ new Set(["update", "delete", "upsert"]);
2771
- var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set(["findUnique", "findUniqueOrThrow"]);
2995
+ var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set([
2996
+ "findUnique",
2997
+ "findUniqueOrThrow"
2998
+ ]);
2772
2999
  var BULK_MUTATION_METHODS = /* @__PURE__ */ new Set([
2773
3000
  "updateMany",
2774
3001
  "updateManyAndReturn",
@@ -2782,15 +3009,14 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
2782
3009
  "createManyAndReturn",
2783
3010
  "updateManyAndReturn"
2784
3011
  ]);
2785
- var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set([
2786
- "createMany",
2787
- "createManyAndReturn"
2788
- ]);
3012
+ var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set(["createMany", "createManyAndReturn"]);
2789
3013
  function buildDefaultSelectInput(config) {
2790
3014
  const result = {};
2791
3015
  for (const [key, value] of Object.entries(config)) {
2792
3016
  if (key === "_count") {
2793
- result[key] = buildDefaultCountInput(value);
3017
+ result[key] = buildDefaultCountInput(
3018
+ value
3019
+ );
2794
3020
  continue;
2795
3021
  }
2796
3022
  if (value === true) {
@@ -2808,7 +3034,9 @@ function buildDefaultIncludeInput(config) {
2808
3034
  const result = {};
2809
3035
  for (const [key, value] of Object.entries(config)) {
2810
3036
  if (key === "_count") {
2811
- result[key] = buildDefaultCountInput(value);
3037
+ result[key] = buildDefaultCountInput(
3038
+ value
3039
+ );
2812
3040
  continue;
2813
3041
  }
2814
3042
  if (value === true) {
@@ -2922,12 +3150,32 @@ function hasNestedClientControlledArgs(shape) {
2922
3150
  return false;
2923
3151
  }
2924
3152
  function createModelGuardExtension(config) {
2925
- const { typeMap, enumMap, zodChains, zodDefaults, uniqueMap, scopeMap, guardConfig, contextFn } = config;
3153
+ const {
3154
+ typeMap,
3155
+ enumMap,
3156
+ zodChains,
3157
+ zodDefaults,
3158
+ uniqueMap,
3159
+ scopeMap,
3160
+ guardConfig,
3161
+ contextFn
3162
+ } = config;
2926
3163
  const wrapZodErrors = config.wrapZodErrors ?? false;
2927
3164
  const enforceProjection = guardConfig.enforceProjection ?? false;
2928
3165
  const scalarBase = createScalarBase(guardConfig.strictDecimal ?? false);
2929
- const schemaBuilder = createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefaults);
2930
- const queryBuilder = createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase);
3166
+ const schemaBuilder = createSchemaBuilder(
3167
+ typeMap,
3168
+ zodChains,
3169
+ enumMap,
3170
+ scalarBase,
3171
+ zodDefaults
3172
+ );
3173
+ const queryBuilder = createQueryBuilder(
3174
+ typeMap,
3175
+ enumMap,
3176
+ uniqueMap,
3177
+ scalarBase
3178
+ );
2931
3179
  const modelScopeFks = /* @__PURE__ */ new Map();
2932
3180
  for (const [model, entries] of Object.entries(scopeMap)) {
2933
3181
  const fks = /* @__PURE__ */ new Set();
@@ -2945,7 +3193,9 @@ function createModelGuardExtension(config) {
2945
3193
  function createGuardedMethods(modelName, modelDelegate, input, explicitCaller) {
2946
3194
  function callDelegate(method, args) {
2947
3195
  if (typeof modelDelegate[method] !== "function") {
2948
- throw new ShapeError(`Method "${method}" is not available on this model`);
3196
+ throw new ShapeError(
3197
+ `Method "${method}" is not available on this model`
3198
+ );
2949
3199
  }
2950
3200
  return modelDelegate[method](args);
2951
3201
  }
@@ -2968,11 +3218,19 @@ function createModelGuardExtension(config) {
2968
3218
  const cached = readShapeCache.get(cacheKey);
2969
3219
  if (cached)
2970
3220
  return cached;
2971
- const built = queryBuilder.buildShapeZodSchema(modelName, method, queryShape);
3221
+ const built = queryBuilder.buildShapeZodSchema(
3222
+ modelName,
3223
+ method,
3224
+ queryShape
3225
+ );
2972
3226
  readShapeCache.set(cacheKey, built);
2973
3227
  return built;
2974
3228
  }
2975
- return queryBuilder.buildShapeZodSchema(modelName, method, queryShape);
3229
+ return queryBuilder.buildShapeZodSchema(
3230
+ modelName,
3231
+ method,
3232
+ queryShape
3233
+ );
2976
3234
  }
2977
3235
  function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
2978
3236
  if (!wasDynamic && !hasDataRefines(dataConfig)) {
@@ -2980,11 +3238,25 @@ function createModelGuardExtension(config) {
2980
3238
  const cached = dataSchemaCache.get(cacheKey);
2981
3239
  if (cached)
2982
3240
  return cached;
2983
- const built = buildDataSchema(modelName, dataConfig, mode, typeMap, schemaBuilder, zodDefaults);
3241
+ const built = buildDataSchema(
3242
+ modelName,
3243
+ dataConfig,
3244
+ mode,
3245
+ typeMap,
3246
+ schemaBuilder,
3247
+ zodDefaults
3248
+ );
2984
3249
  dataSchemaCache.set(cacheKey, built);
2985
3250
  return built;
2986
3251
  }
2987
- return buildDataSchema(modelName, dataConfig, mode, typeMap, schemaBuilder, zodDefaults);
3252
+ return buildDataSchema(
3253
+ modelName,
3254
+ dataConfig,
3255
+ mode,
3256
+ typeMap,
3257
+ schemaBuilder,
3258
+ zodDefaults
3259
+ );
2988
3260
  }
2989
3261
  function getWhereBuilt(whereConfig, matchedKey, wasDynamic) {
2990
3262
  if (!wasDynamic) {
@@ -3103,12 +3375,28 @@ function createModelGuardExtension(config) {
3103
3375
  const built = getWhereBuilt(shape.where, matchedKey, wasDynamic);
3104
3376
  let validatedWhere;
3105
3377
  if (built.schema) {
3106
- validatedWhere = built.schema.parse(bodyWhere);
3378
+ let sanitizedWhere = bodyWhere;
3379
+ if (built.forcedOnlyKeys.size > 0 && isPlainObject(bodyWhere)) {
3380
+ const w = { ...bodyWhere };
3381
+ for (const key of built.forcedOnlyKeys) {
3382
+ delete w[key];
3383
+ }
3384
+ sanitizedWhere = w;
3385
+ }
3386
+ validatedWhere = built.schema.parse(sanitizedWhere);
3107
3387
  } else if (bodyWhere !== void 0) {
3108
3388
  if (bodyWhere === null || !isPlainObject(bodyWhere) || Object.keys(bodyWhere).length > 0) {
3109
- throw new ShapeError(
3110
- "Guard shape where contains only forced conditions. Client where input is not accepted."
3111
- );
3389
+ let hasOnlyForcedKeys = false;
3390
+ if (isPlainObject(bodyWhere) && built.forcedOnlyKeys.size > 0) {
3391
+ hasOnlyForcedKeys = Object.keys(bodyWhere).every(
3392
+ (k) => built.forcedOnlyKeys.has(k)
3393
+ );
3394
+ }
3395
+ if (!hasOnlyForcedKeys) {
3396
+ throw new ShapeError(
3397
+ "Guard shape where contains only forced conditions. Client where input is not accepted."
3398
+ );
3399
+ }
3112
3400
  }
3113
3401
  }
3114
3402
  if (hasWhereForced(built.forced)) {
@@ -3117,7 +3405,13 @@ function createModelGuardExtension(config) {
3117
3405
  return validatedWhere ?? {};
3118
3406
  }
3119
3407
  function requireWhere(shape, bodyWhere, method, preserveUnique, matchedKey, wasDynamic) {
3120
- const where = buildWhereFromShape(shape, bodyWhere, preserveUnique, matchedKey, wasDynamic);
3408
+ const where = buildWhereFromShape(
3409
+ shape,
3410
+ bodyWhere,
3411
+ preserveUnique,
3412
+ matchedKey,
3413
+ wasDynamic
3414
+ );
3121
3415
  if (Object.keys(where).length === 0) {
3122
3416
  throw new ShapeError(`${method} requires a where condition`);
3123
3417
  }
@@ -3131,7 +3425,12 @@ function createModelGuardExtension(config) {
3131
3425
  throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
3132
3426
  }
3133
3427
  const { data: _, ...queryShape } = resolved.shape;
3134
- const built = getReadShape(method, queryShape, resolved.matchedKey, resolved.wasDynamic);
3428
+ const built = getReadShape(
3429
+ method,
3430
+ queryShape,
3431
+ resolved.matchedKey,
3432
+ resolved.wasDynamic
3433
+ );
3135
3434
  const isUnique = UNIQUE_READ_METHODS.has(method);
3136
3435
  const args = applyBuiltShape(built, resolved.body, isUnique);
3137
3436
  if (isUnique && args.where) {
@@ -3164,14 +3463,33 @@ function createModelGuardExtension(config) {
3164
3463
  const resolved = resolveShape(input, body, contextFn, caller);
3165
3464
  if (!resolved.shape.data)
3166
3465
  throw new ShapeError(`Guard shape requires "data" for ${method}`);
3167
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3466
+ validateMutationShapeKeys(
3467
+ resolved.shape,
3468
+ allowedShapeKeys,
3469
+ method
3470
+ );
3168
3471
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3169
3472
  const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
3170
- validateCreateCompleteness(modelName, resolved.shape.data, typeMap, fks, zodDefaults);
3171
- const dataSchema = getDataSchema("create", resolved.shape.data, resolved.matchedKey, resolved.wasDynamic);
3473
+ validateCreateCompleteness(
3474
+ modelName,
3475
+ resolved.shape.data,
3476
+ typeMap,
3477
+ fks,
3478
+ zodDefaults
3479
+ );
3480
+ const dataSchema = getDataSchema(
3481
+ "create",
3482
+ resolved.shape.data,
3483
+ resolved.matchedKey,
3484
+ resolved.wasDynamic
3485
+ );
3172
3486
  let args;
3173
3487
  if (method === "create") {
3174
- const data = validateAndMergeData(resolved.body.data, dataSchema, method);
3488
+ const data = validateAndMergeData(
3489
+ resolved.body.data,
3490
+ dataSchema,
3491
+ method
3492
+ );
3175
3493
  args = { data };
3176
3494
  } else {
3177
3495
  if (!Array.isArray(resolved.body.data))
@@ -3190,7 +3508,13 @@ function createModelGuardExtension(config) {
3190
3508
  args.skipDuplicates = resolved.body.skipDuplicates;
3191
3509
  }
3192
3510
  if (supportsProjection) {
3193
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3511
+ const projectionArgs = resolveProjection(
3512
+ resolved.shape,
3513
+ resolved.body,
3514
+ method,
3515
+ resolved.matchedKey,
3516
+ resolved.wasDynamic
3517
+ );
3194
3518
  Object.assign(args, projectionArgs);
3195
3519
  }
3196
3520
  return callDelegate(method, args);
@@ -3207,24 +3531,60 @@ function createModelGuardExtension(config) {
3207
3531
  const resolved = resolveShape(input, body, contextFn, caller);
3208
3532
  if (!resolved.shape.data)
3209
3533
  throw new ShapeError(`Guard shape requires "data" for ${method}`);
3210
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3534
+ validateMutationShapeKeys(
3535
+ resolved.shape,
3536
+ allowedShapeKeys,
3537
+ method
3538
+ );
3211
3539
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3212
3540
  if (isBulk && !resolved.shape.where) {
3213
- throw new ShapeError(`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`);
3541
+ throw new ShapeError(
3542
+ `Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
3543
+ );
3214
3544
  }
3215
3545
  maybeValidateUniqueWhere(modelName, resolved.shape, method);
3216
- const dataSchema = getDataSchema("update", resolved.shape.data, resolved.matchedKey, resolved.wasDynamic);
3217
- const data = validateAndMergeData(resolved.body.data, dataSchema, method);
3218
- const where = isUniqueWhere ? requireWhere(resolved.shape, resolved.body.where, method, true, resolved.matchedKey, resolved.wasDynamic) : buildWhereFromShape(resolved.shape, resolved.body.where, false, resolved.matchedKey, resolved.wasDynamic);
3546
+ const dataSchema = getDataSchema(
3547
+ "update",
3548
+ resolved.shape.data,
3549
+ resolved.matchedKey,
3550
+ resolved.wasDynamic
3551
+ );
3552
+ const data = validateAndMergeData(
3553
+ resolved.body.data,
3554
+ dataSchema,
3555
+ method
3556
+ );
3557
+ const where = isUniqueWhere ? requireWhere(
3558
+ resolved.shape,
3559
+ resolved.body.where,
3560
+ method,
3561
+ true,
3562
+ resolved.matchedKey,
3563
+ resolved.wasDynamic
3564
+ ) : buildWhereFromShape(
3565
+ resolved.shape,
3566
+ resolved.body.where,
3567
+ false,
3568
+ resolved.matchedKey,
3569
+ resolved.wasDynamic
3570
+ );
3219
3571
  if (isBulk && Object.keys(where).length === 0) {
3220
- throw new ShapeError(`${method} requires at least one where condition`);
3572
+ throw new ShapeError(
3573
+ `${method} requires at least one where condition`
3574
+ );
3221
3575
  }
3222
3576
  if (isUniqueWhere) {
3223
3577
  validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
3224
3578
  }
3225
3579
  const args = { data, where };
3226
3580
  if (supportsProjection) {
3227
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3581
+ const projectionArgs = resolveProjection(
3582
+ resolved.shape,
3583
+ resolved.body,
3584
+ method,
3585
+ resolved.matchedKey,
3586
+ resolved.wasDynamic
3587
+ );
3228
3588
  Object.assign(args, projectionArgs);
3229
3589
  }
3230
3590
  return callDelegate(method, args);
@@ -3241,22 +3601,49 @@ function createModelGuardExtension(config) {
3241
3601
  const resolved = resolveShape(input, body, contextFn, caller);
3242
3602
  if (resolved.shape.data)
3243
3603
  throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
3244
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3604
+ validateMutationShapeKeys(
3605
+ resolved.shape,
3606
+ allowedShapeKeys,
3607
+ method
3608
+ );
3245
3609
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3246
3610
  if (isBulk && !resolved.shape.where) {
3247
- throw new ShapeError(`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`);
3611
+ throw new ShapeError(
3612
+ `Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
3613
+ );
3248
3614
  }
3249
3615
  maybeValidateUniqueWhere(modelName, resolved.shape, method);
3250
- const where = isUniqueWhere ? requireWhere(resolved.shape, resolved.body.where, method, true, resolved.matchedKey, resolved.wasDynamic) : buildWhereFromShape(resolved.shape, resolved.body.where, false, resolved.matchedKey, resolved.wasDynamic);
3616
+ const where = isUniqueWhere ? requireWhere(
3617
+ resolved.shape,
3618
+ resolved.body.where,
3619
+ method,
3620
+ true,
3621
+ resolved.matchedKey,
3622
+ resolved.wasDynamic
3623
+ ) : buildWhereFromShape(
3624
+ resolved.shape,
3625
+ resolved.body.where,
3626
+ false,
3627
+ resolved.matchedKey,
3628
+ resolved.wasDynamic
3629
+ );
3251
3630
  if (isBulk && Object.keys(where).length === 0) {
3252
- throw new ShapeError(`${method} requires at least one where condition`);
3631
+ throw new ShapeError(
3632
+ `${method} requires at least one where condition`
3633
+ );
3253
3634
  }
3254
3635
  if (isUniqueWhere) {
3255
3636
  validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
3256
3637
  }
3257
3638
  const args = { where };
3258
3639
  if (supportsProjection) {
3259
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3640
+ const projectionArgs = resolveProjection(
3641
+ resolved.shape,
3642
+ resolved.body,
3643
+ method,
3644
+ resolved.matchedKey,
3645
+ resolved.wasDynamic
3646
+ );
3260
3647
  Object.assign(args, projectionArgs);
3261
3648
  }
3262
3649
  return callDelegate(method, args);
@@ -3267,7 +3654,9 @@ function createModelGuardExtension(config) {
3267
3654
  const caller = resolveCaller();
3268
3655
  const resolved = resolveShape(input, body, contextFn, caller);
3269
3656
  if (resolved.shape.data) {
3270
- throw new ShapeError('Guard shape "data" is not valid for upsert. Use "create" and "update" instead.');
3657
+ throw new ShapeError(
3658
+ 'Guard shape "data" is not valid for upsert. Use "create" and "update" instead.'
3659
+ );
3271
3660
  }
3272
3661
  if (!resolved.shape.create) {
3273
3662
  throw new ShapeError('Guard shape requires "create" for upsert');
@@ -3283,24 +3672,42 @@ function createModelGuardExtension(config) {
3283
3672
  VALID_SHAPE_KEYS_UPSERT,
3284
3673
  "upsert"
3285
3674
  );
3286
- validateMutationBodyKeys(resolved.body, ALLOWED_BODY_KEYS_UPSERT, "upsert");
3675
+ validateMutationBodyKeys(
3676
+ resolved.body,
3677
+ ALLOWED_BODY_KEYS_UPSERT,
3678
+ "upsert"
3679
+ );
3287
3680
  maybeValidateUniqueWhere(modelName, resolved.shape, "upsert");
3288
3681
  const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
3289
- validateCreateCompleteness(modelName, resolved.shape.create, typeMap, fks, zodDefaults);
3682
+ validateCreateCompleteness(
3683
+ modelName,
3684
+ resolved.shape.create,
3685
+ typeMap,
3686
+ fks,
3687
+ zodDefaults
3688
+ );
3290
3689
  const createDataSchema = getDataSchema(
3291
3690
  "create",
3292
3691
  resolved.shape.create,
3293
3692
  `upsert:create\0${resolved.matchedKey}`,
3294
3693
  resolved.wasDynamic
3295
3694
  );
3296
- const createData = validateAndMergeData(resolved.body.create, createDataSchema, "upsert (create)");
3695
+ const createData = validateAndMergeData(
3696
+ resolved.body.create,
3697
+ createDataSchema,
3698
+ "upsert (create)"
3699
+ );
3297
3700
  const updateDataSchema = getDataSchema(
3298
3701
  "update",
3299
3702
  resolved.shape.update,
3300
3703
  `upsert:update\0${resolved.matchedKey}`,
3301
3704
  resolved.wasDynamic
3302
3705
  );
3303
- const updateData = validateAndMergeData(resolved.body.update, updateDataSchema, "upsert (update)");
3706
+ const updateData = validateAndMergeData(
3707
+ resolved.body.update,
3708
+ updateDataSchema,
3709
+ "upsert (update)"
3710
+ );
3304
3711
  const where = requireWhere(
3305
3712
  resolved.shape,
3306
3713
  resolved.body.where,
@@ -3354,10 +3761,9 @@ function createModelGuardExtension(config) {
3354
3761
  return fn(body);
3355
3762
  } catch (err) {
3356
3763
  if (err instanceof import_zod9.z.ZodError) {
3357
- throw new ShapeError(
3358
- `Validation failed: ${formatZodError(err)}`,
3359
- { cause: err }
3360
- );
3764
+ throw new ShapeError(`Validation failed: ${formatZodError(err)}`, {
3765
+ cause: err
3766
+ });
3361
3767
  }
3362
3768
  throw err;
3363
3769
  }
@@ -3376,7 +3782,12 @@ function createModelGuardExtension(config) {
3376
3782
  `Could not resolve Prisma delegate for model "${modelName}" (key: "${delegateKey}")`
3377
3783
  );
3378
3784
  }
3379
- const methods = createGuardedMethods(modelName, modelDelegate, input, caller);
3785
+ const methods = createGuardedMethods(
3786
+ modelName,
3787
+ modelDelegate,
3788
+ input,
3789
+ caller
3790
+ );
3380
3791
  if (!wrapZodErrors)
3381
3792
  return methods;
3382
3793
  return wrapMethods(methods);