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.
@@ -704,7 +704,24 @@ function mergeUniqueWhereForced(where, forced) {
704
704
  return result;
705
705
  }
706
706
  function applyBuiltShape(built, body, isUniqueMethod) {
707
- const validated = built.zodSchema.parse(body);
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(["contains", "startsWith", "endsWith", "equals"]);
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(target[relName][op].conditions, forced.conditions);
1018
- mergeRelationForcedMaps(target[relName][op].relations, forced.relations);
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(key, value, model, fieldMeta, fieldSchemas, scalarConditions);
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(`"${key}" in where shape must be an object defining allowed fields`);
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(`Relation filter for "${key}" must be an object with operators (some, every, none, is, isNot)`);
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
- { message: `Relation filter "${key}.${op}" requires at least one condition` }
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((k) => v[k] !== void 0),
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 {
@@ -1197,9 +1247,21 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1197
1247
  let hasClientOps = false;
1198
1248
  let hasStringModeOp = false;
1199
1249
  const clientOpKeys = [];
1250
+ let modeConfigValue = void 0;
1251
+ let hasModeConfig = false;
1200
1252
  for (const [op, opValue] of Object.entries(operators)) {
1253
+ if (op === "mode") {
1254
+ hasModeConfig = true;
1255
+ modeConfigValue = opValue;
1256
+ continue;
1257
+ }
1201
1258
  if (opValue === true) {
1202
- opSchemas[op] = createOperatorSchema(fieldMeta, op, enumMap, scalarBase).optional();
1259
+ opSchemas[op] = createOperatorSchema(
1260
+ fieldMeta,
1261
+ op,
1262
+ enumMap,
1263
+ scalarBase
1264
+ ).optional();
1203
1265
  hasClientOps = true;
1204
1266
  clientOpKeys.push(op);
1205
1267
  if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
@@ -1207,7 +1269,12 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1207
1269
  }
1208
1270
  } else {
1209
1271
  const actualOpValue = isForcedValue(opValue) ? opValue.value : opValue;
1210
- const opSchema = createOperatorSchema(fieldMeta, op, enumMap, scalarBase);
1272
+ const opSchema = createOperatorSchema(
1273
+ fieldMeta,
1274
+ op,
1275
+ enumMap,
1276
+ scalarBase
1277
+ );
1211
1278
  let parsed;
1212
1279
  try {
1213
1280
  parsed = opSchema.parse(actualOpValue);
@@ -1217,21 +1284,54 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1217
1284
  );
1218
1285
  }
1219
1286
  fieldForced[op] = parsed;
1287
+ if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
1288
+ hasStringModeOp = true;
1289
+ }
1220
1290
  }
1221
1291
  }
1222
1292
  if (!hasClientOps && Object.keys(fieldForced).length === 0) {
1293
+ if (hasModeConfig) {
1294
+ throw new ShapeError(
1295
+ `Where field "${fieldName}" on model "${model}" has "mode" but no operators. Add at least one operator (contains, startsWith, endsWith, equals).`
1296
+ );
1297
+ }
1223
1298
  throw new ShapeError(
1224
1299
  `Empty operator config for where field "${fieldName}" on model "${model}". Define at least one operator.`
1225
1300
  );
1226
1301
  }
1227
- if (hasStringModeOp) {
1302
+ if (hasModeConfig) {
1303
+ if (!hasStringModeOp) {
1304
+ throw new ShapeError(
1305
+ `"mode" on where field "${fieldName}" on model "${model}" requires a compatible String operator (contains, startsWith, endsWith, equals)`
1306
+ );
1307
+ }
1308
+ if (modeConfigValue === true) {
1309
+ opSchemas["mode"] = z4.enum(["default", "insensitive"]).optional();
1310
+ } else {
1311
+ const actualModeValue = isForcedValue(modeConfigValue) ? modeConfigValue.value : modeConfigValue;
1312
+ const modeSchema = z4.enum(["default", "insensitive"]);
1313
+ let parsed;
1314
+ try {
1315
+ parsed = modeSchema.parse(actualModeValue);
1316
+ } catch (err) {
1317
+ throw new ShapeError(
1318
+ `Invalid forced value for "${model}.${fieldName}.mode": ${err.message}`
1319
+ );
1320
+ }
1321
+ fieldForced["mode"] = parsed;
1322
+ }
1323
+ } else if (hasStringModeOp) {
1228
1324
  opSchemas["mode"] = z4.enum(["default", "insensitive"]).optional();
1229
1325
  }
1230
1326
  if (hasClientOps) {
1231
1327
  const opObj = z4.object(opSchemas).strict();
1232
1328
  fieldSchemas[fieldName] = opObj.refine(
1233
- (v) => clientOpKeys.some((k) => v[k] !== void 0),
1234
- { message: `At least one operator required for where field "${fieldName}"` }
1329
+ (v) => clientOpKeys.some(
1330
+ (k) => v[k] !== void 0
1331
+ ),
1332
+ {
1333
+ message: `At least one operator required for where field "${fieldName}"`
1334
+ }
1235
1335
  ).optional();
1236
1336
  }
1237
1337
  if (Object.keys(fieldForced).length > 0) {
@@ -1897,19 +1997,77 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
1897
1997
 
1898
1998
  // src/runtime/query-builder.ts
1899
1999
  var METHOD_ALLOWED_ARGS = {
1900
- findMany: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
1901
- findFirst: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
1902
- findFirstOrThrow: /* @__PURE__ */ new Set(["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"]),
2000
+ findMany: /* @__PURE__ */ new Set([
2001
+ "where",
2002
+ "include",
2003
+ "select",
2004
+ "orderBy",
2005
+ "cursor",
2006
+ "take",
2007
+ "skip",
2008
+ "distinct"
2009
+ ]),
2010
+ findFirst: /* @__PURE__ */ new Set([
2011
+ "where",
2012
+ "include",
2013
+ "select",
2014
+ "orderBy",
2015
+ "cursor",
2016
+ "take",
2017
+ "skip",
2018
+ "distinct"
2019
+ ]),
2020
+ findFirstOrThrow: /* @__PURE__ */ new Set([
2021
+ "where",
2022
+ "include",
2023
+ "select",
2024
+ "orderBy",
2025
+ "cursor",
2026
+ "take",
2027
+ "skip",
2028
+ "distinct"
2029
+ ]),
1903
2030
  findUnique: /* @__PURE__ */ new Set(["where", "include", "select"]),
1904
2031
  findUniqueOrThrow: /* @__PURE__ */ new Set(["where", "include", "select"]),
1905
2032
  count: /* @__PURE__ */ new Set(["where", "select", "cursor", "orderBy", "skip", "take"]),
1906
- aggregate: /* @__PURE__ */ new Set(["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"]),
1907
- groupBy: /* @__PURE__ */ new Set(["where", "by", "having", "_count", "_avg", "_sum", "_min", "_max", "orderBy", "take", "skip"])
2033
+ aggregate: /* @__PURE__ */ new Set([
2034
+ "where",
2035
+ "orderBy",
2036
+ "cursor",
2037
+ "take",
2038
+ "skip",
2039
+ "_count",
2040
+ "_avg",
2041
+ "_sum",
2042
+ "_min",
2043
+ "_max"
2044
+ ]),
2045
+ groupBy: /* @__PURE__ */ new Set([
2046
+ "where",
2047
+ "by",
2048
+ "having",
2049
+ "_count",
2050
+ "_avg",
2051
+ "_sum",
2052
+ "_min",
2053
+ "_max",
2054
+ "orderBy",
2055
+ "take",
2056
+ "skip"
2057
+ ])
1908
2058
  };
1909
- var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set(["findUnique", "findUniqueOrThrow"]);
2059
+ var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set([
2060
+ "findUnique",
2061
+ "findUniqueOrThrow"
2062
+ ]);
1910
2063
  function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1911
2064
  const whereBuilder = createWhereBuilder(typeMap, enumMap, scalarBase);
1912
- const argsBuilder = createArgsBuilder(typeMap, enumMap, uniqueMap, scalarBase);
2065
+ const argsBuilder = createArgsBuilder(
2066
+ typeMap,
2067
+ enumMap,
2068
+ uniqueMap,
2069
+ scalarBase
2070
+ );
1913
2071
  const projectionBuilder = createProjectionBuilder(typeMap, enumMap, {
1914
2072
  buildWhereSchema: whereBuilder.buildWhereSchema,
1915
2073
  buildOrderBySchema: argsBuilder.buildOrderBySchema,
@@ -1934,7 +2092,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1934
2092
  throw new ShapeError(`${method} shape must define "where"`);
1935
2093
  }
1936
2094
  if (shape.include && shape.select) {
1937
- throw new ShapeError('Shape config cannot define both "include" and "select".');
2095
+ throw new ShapeError(
2096
+ 'Shape config cannot define both "include" and "select".'
2097
+ );
1938
2098
  }
1939
2099
  if (method === "groupBy" && !shape.by)
1940
2100
  throw new ShapeError('groupBy shape must define "by"');
@@ -1950,7 +2110,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1950
2110
  const bySet = new Set(shape.by);
1951
2111
  for (const fieldName of Object.keys(shape.orderBy)) {
1952
2112
  if (!bySet.has(fieldName)) {
1953
- throw new ShapeError(`orderBy field "${fieldName}" must be included in "by" for groupBy`);
2113
+ throw new ShapeError(
2114
+ `orderBy field "${fieldName}" must be included in "by" for groupBy`
2115
+ );
1954
2116
  }
1955
2117
  }
1956
2118
  }
@@ -1958,7 +2120,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1958
2120
  const bySet = new Set(shape.by);
1959
2121
  for (const fieldName of Object.keys(shape.having)) {
1960
2122
  if (!bySet.has(fieldName)) {
1961
- throw new ShapeError(`having field "${fieldName}" must be included in "by" for groupBy`);
2123
+ throw new ShapeError(
2124
+ `having field "${fieldName}" must be included in "by" for groupBy`
2125
+ );
1962
2126
  }
1963
2127
  }
1964
2128
  }
@@ -1975,7 +2139,9 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1975
2139
  requireContext(ctx, "shape function");
1976
2140
  const result = shapeOrFn(ctx);
1977
2141
  if (!isPlainObject(result)) {
1978
- throw new ShapeError("Dynamic shape function must return a plain object");
2142
+ throw new ShapeError(
2143
+ "Dynamic shape function must return a plain object"
2144
+ );
1979
2145
  }
1980
2146
  return result;
1981
2147
  }
@@ -1986,15 +2152,20 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1986
2152
  validateUniqueWhere(model, method, shape);
1987
2153
  const schemaFields = {};
1988
2154
  let forcedWhere = EMPTY_WHERE_FORCED;
2155
+ let forcedOnlyWhereKeys = /* @__PURE__ */ new Set();
1989
2156
  let forcedIncludeTree = {};
1990
2157
  let forcedSelectTree = {};
1991
2158
  let forcedIncludeCountWhere = {};
1992
2159
  let forcedSelectCountWhere = {};
1993
2160
  if (shape.where) {
1994
- const { schema, forced } = whereBuilder.buildWhereSchema(model, shape.where);
2161
+ const { schema, forced, forcedOnlyKeys } = whereBuilder.buildWhereSchema(
2162
+ model,
2163
+ shape.where
2164
+ );
1995
2165
  if (schema)
1996
2166
  schemaFields["where"] = schema;
1997
2167
  forcedWhere = forced;
2168
+ forcedOnlyWhereKeys = forcedOnlyKeys;
1998
2169
  }
1999
2170
  if (shape.include) {
2000
2171
  const result = projectionBuilder.buildIncludeSchema(model, shape.include);
@@ -2004,7 +2175,10 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2004
2175
  }
2005
2176
  if (shape.select) {
2006
2177
  if (method === "count") {
2007
- schemaFields["select"] = argsBuilder.buildCountSelectSchema(model, shape.select);
2178
+ schemaFields["select"] = argsBuilder.buildCountSelectSchema(
2179
+ model,
2180
+ shape.select
2181
+ );
2008
2182
  } else {
2009
2183
  const result = projectionBuilder.buildSelectSchema(model, shape.select);
2010
2184
  schemaFields["select"] = result.schema;
@@ -2013,9 +2187,15 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2013
2187
  }
2014
2188
  }
2015
2189
  if (shape.orderBy)
2016
- schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(model, shape.orderBy);
2190
+ schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
2191
+ model,
2192
+ shape.orderBy
2193
+ );
2017
2194
  if (shape.cursor)
2018
- schemaFields["cursor"] = argsBuilder.buildCursorSchema(model, shape.cursor);
2195
+ schemaFields["cursor"] = argsBuilder.buildCursorSchema(
2196
+ model,
2197
+ shape.cursor
2198
+ );
2019
2199
  if (shape.take)
2020
2200
  schemaFields["take"] = argsBuilder.buildTakeSchema(shape.take);
2021
2201
  if (shape.skip !== void 0) {
@@ -2025,24 +2205,51 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2025
2205
  schemaFields["skip"] = z7.number().int().min(0).optional();
2026
2206
  }
2027
2207
  if (shape.distinct)
2028
- schemaFields["distinct"] = argsBuilder.buildDistinctSchema(model, shape.distinct);
2208
+ schemaFields["distinct"] = argsBuilder.buildDistinctSchema(
2209
+ model,
2210
+ shape.distinct
2211
+ );
2029
2212
  if (shape._count)
2030
- schemaFields["_count"] = argsBuilder.buildCountFieldSchema(model, shape._count, "_count");
2213
+ schemaFields["_count"] = argsBuilder.buildCountFieldSchema(
2214
+ model,
2215
+ shape._count,
2216
+ "_count"
2217
+ );
2031
2218
  if (shape._avg)
2032
- schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(model, "_avg", shape._avg);
2219
+ schemaFields["_avg"] = argsBuilder.buildAggregateFieldSchema(
2220
+ model,
2221
+ "_avg",
2222
+ shape._avg
2223
+ );
2033
2224
  if (shape._sum)
2034
- schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(model, "_sum", shape._sum);
2225
+ schemaFields["_sum"] = argsBuilder.buildAggregateFieldSchema(
2226
+ model,
2227
+ "_sum",
2228
+ shape._sum
2229
+ );
2035
2230
  if (shape._min)
2036
- schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(model, "_min", shape._min);
2231
+ schemaFields["_min"] = argsBuilder.buildAggregateFieldSchema(
2232
+ model,
2233
+ "_min",
2234
+ shape._min
2235
+ );
2037
2236
  if (shape._max)
2038
- schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(model, "_max", shape._max);
2237
+ schemaFields["_max"] = argsBuilder.buildAggregateFieldSchema(
2238
+ model,
2239
+ "_max",
2240
+ shape._max
2241
+ );
2039
2242
  if (shape.by)
2040
2243
  schemaFields["by"] = argsBuilder.buildBySchema(model, shape.by);
2041
2244
  if (shape.having)
2042
- schemaFields["having"] = argsBuilder.buildHavingSchema(model, shape.having);
2245
+ schemaFields["having"] = argsBuilder.buildHavingSchema(
2246
+ model,
2247
+ shape.having
2248
+ );
2043
2249
  return {
2044
2250
  zodSchema: z7.object(schemaFields).strict(),
2045
2251
  forcedWhere,
2252
+ forcedOnlyWhereKeys,
2046
2253
  forcedIncludeTree,
2047
2254
  forcedSelectTree,
2048
2255
  forcedIncludeCountWhere,
@@ -2059,17 +2266,27 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2059
2266
  const isSingle = typeof config === "function" || isShapeConfig(config);
2060
2267
  const builtCache = /* @__PURE__ */ new Map();
2061
2268
  if (isSingle && typeof config !== "function") {
2062
- builtCache.set("_default", buildShapeZodSchema(model, method, config));
2269
+ builtCache.set(
2270
+ "_default",
2271
+ buildShapeZodSchema(model, method, config)
2272
+ );
2063
2273
  }
2064
2274
  if (!isSingle) {
2065
2275
  for (const key of Object.keys(config)) {
2066
2276
  if (SHAPE_CONFIG_KEYS.has(key)) {
2067
- throw new ShapeError(`Caller key "${key}" collides with reserved shape config key. Rename the caller path.`);
2277
+ throw new ShapeError(
2278
+ `Caller key "${key}" collides with reserved shape config key. Rename the caller path.`
2279
+ );
2068
2280
  }
2069
2281
  }
2070
- for (const [key, shapeOrFn] of Object.entries(config)) {
2282
+ for (const [key, shapeOrFn] of Object.entries(
2283
+ config
2284
+ )) {
2071
2285
  if (typeof shapeOrFn !== "function") {
2072
- builtCache.set(key, buildShapeZodSchema(model, method, shapeOrFn));
2286
+ builtCache.set(
2287
+ key,
2288
+ buildShapeZodSchema(model, method, shapeOrFn)
2289
+ );
2073
2290
  }
2074
2291
  }
2075
2292
  }
@@ -2098,14 +2315,21 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2098
2315
  }
2099
2316
  const caller = opts?.caller;
2100
2317
  if (typeof caller !== "string") {
2101
- const allowed = Object.keys(config);
2318
+ const allowed = Object.keys(
2319
+ config
2320
+ );
2102
2321
  throw new CallerError(
2103
2322
  `Missing caller. This query uses named shape routing with keys: ${allowed.map((k) => `"${k}"`).join(", ")}. Provide caller via opts.caller.`
2104
2323
  );
2105
2324
  }
2106
- const matched = matchCaller(config, caller);
2325
+ const matched = matchCaller(
2326
+ config,
2327
+ caller
2328
+ );
2107
2329
  if (!matched) {
2108
- const allowed = Object.keys(config);
2330
+ const allowed = Object.keys(
2331
+ config
2332
+ );
2109
2333
  throw new CallerError(
2110
2334
  `Unknown caller: "${caller}". Allowed: ${allowed.map((k) => `"${k}"`).join(", ")}`
2111
2335
  );
@@ -2738,7 +2962,10 @@ function resolveShape(input, body, contextFn, caller) {
2738
2962
 
2739
2963
  // src/runtime/model-guard.ts
2740
2964
  var UNIQUE_MUTATION_METHODS = /* @__PURE__ */ new Set(["update", "delete", "upsert"]);
2741
- var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set(["findUnique", "findUniqueOrThrow"]);
2965
+ var UNIQUE_READ_METHODS = /* @__PURE__ */ new Set([
2966
+ "findUnique",
2967
+ "findUniqueOrThrow"
2968
+ ]);
2742
2969
  var BULK_MUTATION_METHODS = /* @__PURE__ */ new Set([
2743
2970
  "updateMany",
2744
2971
  "updateManyAndReturn",
@@ -2752,15 +2979,14 @@ var PROJECTION_MUTATION_METHODS = /* @__PURE__ */ new Set([
2752
2979
  "createManyAndReturn",
2753
2980
  "updateManyAndReturn"
2754
2981
  ]);
2755
- var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set([
2756
- "createMany",
2757
- "createManyAndReturn"
2758
- ]);
2982
+ var BATCH_CREATE_METHODS = /* @__PURE__ */ new Set(["createMany", "createManyAndReturn"]);
2759
2983
  function buildDefaultSelectInput(config) {
2760
2984
  const result = {};
2761
2985
  for (const [key, value] of Object.entries(config)) {
2762
2986
  if (key === "_count") {
2763
- result[key] = buildDefaultCountInput(value);
2987
+ result[key] = buildDefaultCountInput(
2988
+ value
2989
+ );
2764
2990
  continue;
2765
2991
  }
2766
2992
  if (value === true) {
@@ -2778,7 +3004,9 @@ function buildDefaultIncludeInput(config) {
2778
3004
  const result = {};
2779
3005
  for (const [key, value] of Object.entries(config)) {
2780
3006
  if (key === "_count") {
2781
- result[key] = buildDefaultCountInput(value);
3007
+ result[key] = buildDefaultCountInput(
3008
+ value
3009
+ );
2782
3010
  continue;
2783
3011
  }
2784
3012
  if (value === true) {
@@ -2892,12 +3120,32 @@ function hasNestedClientControlledArgs(shape) {
2892
3120
  return false;
2893
3121
  }
2894
3122
  function createModelGuardExtension(config) {
2895
- const { typeMap, enumMap, zodChains, zodDefaults, uniqueMap, scopeMap, guardConfig, contextFn } = config;
3123
+ const {
3124
+ typeMap,
3125
+ enumMap,
3126
+ zodChains,
3127
+ zodDefaults,
3128
+ uniqueMap,
3129
+ scopeMap,
3130
+ guardConfig,
3131
+ contextFn
3132
+ } = config;
2896
3133
  const wrapZodErrors = config.wrapZodErrors ?? false;
2897
3134
  const enforceProjection = guardConfig.enforceProjection ?? false;
2898
3135
  const scalarBase = createScalarBase(guardConfig.strictDecimal ?? false);
2899
- const schemaBuilder = createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefaults);
2900
- const queryBuilder = createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase);
3136
+ const schemaBuilder = createSchemaBuilder(
3137
+ typeMap,
3138
+ zodChains,
3139
+ enumMap,
3140
+ scalarBase,
3141
+ zodDefaults
3142
+ );
3143
+ const queryBuilder = createQueryBuilder(
3144
+ typeMap,
3145
+ enumMap,
3146
+ uniqueMap,
3147
+ scalarBase
3148
+ );
2901
3149
  const modelScopeFks = /* @__PURE__ */ new Map();
2902
3150
  for (const [model, entries] of Object.entries(scopeMap)) {
2903
3151
  const fks = /* @__PURE__ */ new Set();
@@ -2915,7 +3163,9 @@ function createModelGuardExtension(config) {
2915
3163
  function createGuardedMethods(modelName, modelDelegate, input, explicitCaller) {
2916
3164
  function callDelegate(method, args) {
2917
3165
  if (typeof modelDelegate[method] !== "function") {
2918
- throw new ShapeError(`Method "${method}" is not available on this model`);
3166
+ throw new ShapeError(
3167
+ `Method "${method}" is not available on this model`
3168
+ );
2919
3169
  }
2920
3170
  return modelDelegate[method](args);
2921
3171
  }
@@ -2938,11 +3188,19 @@ function createModelGuardExtension(config) {
2938
3188
  const cached = readShapeCache.get(cacheKey);
2939
3189
  if (cached)
2940
3190
  return cached;
2941
- const built = queryBuilder.buildShapeZodSchema(modelName, method, queryShape);
3191
+ const built = queryBuilder.buildShapeZodSchema(
3192
+ modelName,
3193
+ method,
3194
+ queryShape
3195
+ );
2942
3196
  readShapeCache.set(cacheKey, built);
2943
3197
  return built;
2944
3198
  }
2945
- return queryBuilder.buildShapeZodSchema(modelName, method, queryShape);
3199
+ return queryBuilder.buildShapeZodSchema(
3200
+ modelName,
3201
+ method,
3202
+ queryShape
3203
+ );
2946
3204
  }
2947
3205
  function getDataSchema(mode, dataConfig, matchedKey, wasDynamic) {
2948
3206
  if (!wasDynamic && !hasDataRefines(dataConfig)) {
@@ -2950,11 +3208,25 @@ function createModelGuardExtension(config) {
2950
3208
  const cached = dataSchemaCache.get(cacheKey);
2951
3209
  if (cached)
2952
3210
  return cached;
2953
- const built = buildDataSchema(modelName, dataConfig, mode, typeMap, schemaBuilder, zodDefaults);
3211
+ const built = buildDataSchema(
3212
+ modelName,
3213
+ dataConfig,
3214
+ mode,
3215
+ typeMap,
3216
+ schemaBuilder,
3217
+ zodDefaults
3218
+ );
2954
3219
  dataSchemaCache.set(cacheKey, built);
2955
3220
  return built;
2956
3221
  }
2957
- return buildDataSchema(modelName, dataConfig, mode, typeMap, schemaBuilder, zodDefaults);
3222
+ return buildDataSchema(
3223
+ modelName,
3224
+ dataConfig,
3225
+ mode,
3226
+ typeMap,
3227
+ schemaBuilder,
3228
+ zodDefaults
3229
+ );
2958
3230
  }
2959
3231
  function getWhereBuilt(whereConfig, matchedKey, wasDynamic) {
2960
3232
  if (!wasDynamic) {
@@ -3073,12 +3345,28 @@ function createModelGuardExtension(config) {
3073
3345
  const built = getWhereBuilt(shape.where, matchedKey, wasDynamic);
3074
3346
  let validatedWhere;
3075
3347
  if (built.schema) {
3076
- validatedWhere = built.schema.parse(bodyWhere);
3348
+ let sanitizedWhere = bodyWhere;
3349
+ if (built.forcedOnlyKeys.size > 0 && isPlainObject(bodyWhere)) {
3350
+ const w = { ...bodyWhere };
3351
+ for (const key of built.forcedOnlyKeys) {
3352
+ delete w[key];
3353
+ }
3354
+ sanitizedWhere = w;
3355
+ }
3356
+ validatedWhere = built.schema.parse(sanitizedWhere);
3077
3357
  } else if (bodyWhere !== void 0) {
3078
3358
  if (bodyWhere === null || !isPlainObject(bodyWhere) || Object.keys(bodyWhere).length > 0) {
3079
- throw new ShapeError(
3080
- "Guard shape where contains only forced conditions. Client where input is not accepted."
3081
- );
3359
+ let hasOnlyForcedKeys = false;
3360
+ if (isPlainObject(bodyWhere) && built.forcedOnlyKeys.size > 0) {
3361
+ hasOnlyForcedKeys = Object.keys(bodyWhere).every(
3362
+ (k) => built.forcedOnlyKeys.has(k)
3363
+ );
3364
+ }
3365
+ if (!hasOnlyForcedKeys) {
3366
+ throw new ShapeError(
3367
+ "Guard shape where contains only forced conditions. Client where input is not accepted."
3368
+ );
3369
+ }
3082
3370
  }
3083
3371
  }
3084
3372
  if (hasWhereForced(built.forced)) {
@@ -3087,7 +3375,13 @@ function createModelGuardExtension(config) {
3087
3375
  return validatedWhere ?? {};
3088
3376
  }
3089
3377
  function requireWhere(shape, bodyWhere, method, preserveUnique, matchedKey, wasDynamic) {
3090
- const where = buildWhereFromShape(shape, bodyWhere, preserveUnique, matchedKey, wasDynamic);
3378
+ const where = buildWhereFromShape(
3379
+ shape,
3380
+ bodyWhere,
3381
+ preserveUnique,
3382
+ matchedKey,
3383
+ wasDynamic
3384
+ );
3091
3385
  if (Object.keys(where).length === 0) {
3092
3386
  throw new ShapeError(`${method} requires a where condition`);
3093
3387
  }
@@ -3101,7 +3395,12 @@ function createModelGuardExtension(config) {
3101
3395
  throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
3102
3396
  }
3103
3397
  const { data: _, ...queryShape } = resolved.shape;
3104
- const built = getReadShape(method, queryShape, resolved.matchedKey, resolved.wasDynamic);
3398
+ const built = getReadShape(
3399
+ method,
3400
+ queryShape,
3401
+ resolved.matchedKey,
3402
+ resolved.wasDynamic
3403
+ );
3105
3404
  const isUnique = UNIQUE_READ_METHODS.has(method);
3106
3405
  const args = applyBuiltShape(built, resolved.body, isUnique);
3107
3406
  if (isUnique && args.where) {
@@ -3134,14 +3433,33 @@ function createModelGuardExtension(config) {
3134
3433
  const resolved = resolveShape(input, body, contextFn, caller);
3135
3434
  if (!resolved.shape.data)
3136
3435
  throw new ShapeError(`Guard shape requires "data" for ${method}`);
3137
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3436
+ validateMutationShapeKeys(
3437
+ resolved.shape,
3438
+ allowedShapeKeys,
3439
+ method
3440
+ );
3138
3441
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3139
3442
  const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
3140
- validateCreateCompleteness(modelName, resolved.shape.data, typeMap, fks, zodDefaults);
3141
- const dataSchema = getDataSchema("create", resolved.shape.data, resolved.matchedKey, resolved.wasDynamic);
3443
+ validateCreateCompleteness(
3444
+ modelName,
3445
+ resolved.shape.data,
3446
+ typeMap,
3447
+ fks,
3448
+ zodDefaults
3449
+ );
3450
+ const dataSchema = getDataSchema(
3451
+ "create",
3452
+ resolved.shape.data,
3453
+ resolved.matchedKey,
3454
+ resolved.wasDynamic
3455
+ );
3142
3456
  let args;
3143
3457
  if (method === "create") {
3144
- const data = validateAndMergeData(resolved.body.data, dataSchema, method);
3458
+ const data = validateAndMergeData(
3459
+ resolved.body.data,
3460
+ dataSchema,
3461
+ method
3462
+ );
3145
3463
  args = { data };
3146
3464
  } else {
3147
3465
  if (!Array.isArray(resolved.body.data))
@@ -3160,7 +3478,13 @@ function createModelGuardExtension(config) {
3160
3478
  args.skipDuplicates = resolved.body.skipDuplicates;
3161
3479
  }
3162
3480
  if (supportsProjection) {
3163
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3481
+ const projectionArgs = resolveProjection(
3482
+ resolved.shape,
3483
+ resolved.body,
3484
+ method,
3485
+ resolved.matchedKey,
3486
+ resolved.wasDynamic
3487
+ );
3164
3488
  Object.assign(args, projectionArgs);
3165
3489
  }
3166
3490
  return callDelegate(method, args);
@@ -3177,24 +3501,60 @@ function createModelGuardExtension(config) {
3177
3501
  const resolved = resolveShape(input, body, contextFn, caller);
3178
3502
  if (!resolved.shape.data)
3179
3503
  throw new ShapeError(`Guard shape requires "data" for ${method}`);
3180
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3504
+ validateMutationShapeKeys(
3505
+ resolved.shape,
3506
+ allowedShapeKeys,
3507
+ method
3508
+ );
3181
3509
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3182
3510
  if (isBulk && !resolved.shape.where) {
3183
- throw new ShapeError(`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`);
3511
+ throw new ShapeError(
3512
+ `Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
3513
+ );
3184
3514
  }
3185
3515
  maybeValidateUniqueWhere(modelName, resolved.shape, method);
3186
- const dataSchema = getDataSchema("update", resolved.shape.data, resolved.matchedKey, resolved.wasDynamic);
3187
- const data = validateAndMergeData(resolved.body.data, dataSchema, method);
3188
- 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);
3516
+ const dataSchema = getDataSchema(
3517
+ "update",
3518
+ resolved.shape.data,
3519
+ resolved.matchedKey,
3520
+ resolved.wasDynamic
3521
+ );
3522
+ const data = validateAndMergeData(
3523
+ resolved.body.data,
3524
+ dataSchema,
3525
+ method
3526
+ );
3527
+ const where = isUniqueWhere ? requireWhere(
3528
+ resolved.shape,
3529
+ resolved.body.where,
3530
+ method,
3531
+ true,
3532
+ resolved.matchedKey,
3533
+ resolved.wasDynamic
3534
+ ) : buildWhereFromShape(
3535
+ resolved.shape,
3536
+ resolved.body.where,
3537
+ false,
3538
+ resolved.matchedKey,
3539
+ resolved.wasDynamic
3540
+ );
3189
3541
  if (isBulk && Object.keys(where).length === 0) {
3190
- throw new ShapeError(`${method} requires at least one where condition`);
3542
+ throw new ShapeError(
3543
+ `${method} requires at least one where condition`
3544
+ );
3191
3545
  }
3192
3546
  if (isUniqueWhere) {
3193
3547
  validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
3194
3548
  }
3195
3549
  const args = { data, where };
3196
3550
  if (supportsProjection) {
3197
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3551
+ const projectionArgs = resolveProjection(
3552
+ resolved.shape,
3553
+ resolved.body,
3554
+ method,
3555
+ resolved.matchedKey,
3556
+ resolved.wasDynamic
3557
+ );
3198
3558
  Object.assign(args, projectionArgs);
3199
3559
  }
3200
3560
  return callDelegate(method, args);
@@ -3211,22 +3571,49 @@ function createModelGuardExtension(config) {
3211
3571
  const resolved = resolveShape(input, body, contextFn, caller);
3212
3572
  if (resolved.shape.data)
3213
3573
  throw new ShapeError(`Guard shape "data" is not valid for ${method}`);
3214
- validateMutationShapeKeys(resolved.shape, allowedShapeKeys, method);
3574
+ validateMutationShapeKeys(
3575
+ resolved.shape,
3576
+ allowedShapeKeys,
3577
+ method
3578
+ );
3215
3579
  validateMutationBodyKeys(resolved.body, allowedBodyKeys, method);
3216
3580
  if (isBulk && !resolved.shape.where) {
3217
- throw new ShapeError(`Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`);
3581
+ throw new ShapeError(
3582
+ `Guard shape requires "where" for ${method} to prevent unconstrained bulk mutations`
3583
+ );
3218
3584
  }
3219
3585
  maybeValidateUniqueWhere(modelName, resolved.shape, method);
3220
- 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);
3586
+ const where = isUniqueWhere ? requireWhere(
3587
+ resolved.shape,
3588
+ resolved.body.where,
3589
+ method,
3590
+ true,
3591
+ resolved.matchedKey,
3592
+ resolved.wasDynamic
3593
+ ) : buildWhereFromShape(
3594
+ resolved.shape,
3595
+ resolved.body.where,
3596
+ false,
3597
+ resolved.matchedKey,
3598
+ resolved.wasDynamic
3599
+ );
3221
3600
  if (isBulk && Object.keys(where).length === 0) {
3222
- throw new ShapeError(`${method} requires at least one where condition`);
3601
+ throw new ShapeError(
3602
+ `${method} requires at least one where condition`
3603
+ );
3223
3604
  }
3224
3605
  if (isUniqueWhere) {
3225
3606
  validateResolvedUniqueWhere(modelName, where, method, uniqueMap);
3226
3607
  }
3227
3608
  const args = { where };
3228
3609
  if (supportsProjection) {
3229
- const projectionArgs = resolveProjection(resolved.shape, resolved.body, method, resolved.matchedKey, resolved.wasDynamic);
3610
+ const projectionArgs = resolveProjection(
3611
+ resolved.shape,
3612
+ resolved.body,
3613
+ method,
3614
+ resolved.matchedKey,
3615
+ resolved.wasDynamic
3616
+ );
3230
3617
  Object.assign(args, projectionArgs);
3231
3618
  }
3232
3619
  return callDelegate(method, args);
@@ -3237,7 +3624,9 @@ function createModelGuardExtension(config) {
3237
3624
  const caller = resolveCaller();
3238
3625
  const resolved = resolveShape(input, body, contextFn, caller);
3239
3626
  if (resolved.shape.data) {
3240
- throw new ShapeError('Guard shape "data" is not valid for upsert. Use "create" and "update" instead.');
3627
+ throw new ShapeError(
3628
+ 'Guard shape "data" is not valid for upsert. Use "create" and "update" instead.'
3629
+ );
3241
3630
  }
3242
3631
  if (!resolved.shape.create) {
3243
3632
  throw new ShapeError('Guard shape requires "create" for upsert');
@@ -3253,24 +3642,42 @@ function createModelGuardExtension(config) {
3253
3642
  VALID_SHAPE_KEYS_UPSERT,
3254
3643
  "upsert"
3255
3644
  );
3256
- validateMutationBodyKeys(resolved.body, ALLOWED_BODY_KEYS_UPSERT, "upsert");
3645
+ validateMutationBodyKeys(
3646
+ resolved.body,
3647
+ ALLOWED_BODY_KEYS_UPSERT,
3648
+ "upsert"
3649
+ );
3257
3650
  maybeValidateUniqueWhere(modelName, resolved.shape, "upsert");
3258
3651
  const fks = modelScopeFks.get(modelName) ?? /* @__PURE__ */ new Set();
3259
- validateCreateCompleteness(modelName, resolved.shape.create, typeMap, fks, zodDefaults);
3652
+ validateCreateCompleteness(
3653
+ modelName,
3654
+ resolved.shape.create,
3655
+ typeMap,
3656
+ fks,
3657
+ zodDefaults
3658
+ );
3260
3659
  const createDataSchema = getDataSchema(
3261
3660
  "create",
3262
3661
  resolved.shape.create,
3263
3662
  `upsert:create\0${resolved.matchedKey}`,
3264
3663
  resolved.wasDynamic
3265
3664
  );
3266
- const createData = validateAndMergeData(resolved.body.create, createDataSchema, "upsert (create)");
3665
+ const createData = validateAndMergeData(
3666
+ resolved.body.create,
3667
+ createDataSchema,
3668
+ "upsert (create)"
3669
+ );
3267
3670
  const updateDataSchema = getDataSchema(
3268
3671
  "update",
3269
3672
  resolved.shape.update,
3270
3673
  `upsert:update\0${resolved.matchedKey}`,
3271
3674
  resolved.wasDynamic
3272
3675
  );
3273
- const updateData = validateAndMergeData(resolved.body.update, updateDataSchema, "upsert (update)");
3676
+ const updateData = validateAndMergeData(
3677
+ resolved.body.update,
3678
+ updateDataSchema,
3679
+ "upsert (update)"
3680
+ );
3274
3681
  const where = requireWhere(
3275
3682
  resolved.shape,
3276
3683
  resolved.body.where,
@@ -3324,10 +3731,9 @@ function createModelGuardExtension(config) {
3324
3731
  return fn(body);
3325
3732
  } catch (err) {
3326
3733
  if (err instanceof z9.ZodError) {
3327
- throw new ShapeError(
3328
- `Validation failed: ${formatZodError(err)}`,
3329
- { cause: err }
3330
- );
3734
+ throw new ShapeError(`Validation failed: ${formatZodError(err)}`, {
3735
+ cause: err
3736
+ });
3331
3737
  }
3332
3738
  throw err;
3333
3739
  }
@@ -3346,7 +3752,12 @@ function createModelGuardExtension(config) {
3346
3752
  `Could not resolve Prisma delegate for model "${modelName}" (key: "${delegateKey}")`
3347
3753
  );
3348
3754
  }
3349
- const methods = createGuardedMethods(modelName, modelDelegate, input, caller);
3755
+ const methods = createGuardedMethods(
3756
+ modelName,
3757
+ modelDelegate,
3758
+ input,
3759
+ caller
3760
+ );
3350
3761
  if (!wrapZodErrors)
3351
3762
  return methods;
3352
3763
  return wrapMethods(methods);