prisma-guard 1.4.1 → 1.5.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.
@@ -705,18 +705,23 @@ function mergeUniqueWhereForced(where, forced) {
705
705
  }
706
706
  function applyBuiltShape(built, body, isUniqueMethod) {
707
707
  let parseable = body;
708
- if (built.forcedOnlyWhereKeys.size > 0 && isPlainObject(body)) {
708
+ if (isPlainObject(body)) {
709
709
  const bodyObj = body;
710
710
  if (isPlainObject(bodyObj.where)) {
711
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;
712
+ let modified = false;
713
+ if (built.forcedOnlyWhereKeys.size > 0) {
714
+ for (const key of built.forcedOnlyWhereKeys) {
715
+ if (key in where) {
716
+ delete where[key];
717
+ modified = true;
718
+ }
717
719
  }
718
720
  }
719
- if (stripped) {
721
+ if (Object.keys(where).length === 0 && hasWhereForced(built.forcedWhere)) {
722
+ const { where: _, ...rest } = bodyObj;
723
+ parseable = rest;
724
+ } else if (modified) {
720
725
  parseable = { ...bodyObj, where };
721
726
  }
722
727
  }
@@ -1247,7 +1252,14 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1247
1252
  let hasClientOps = false;
1248
1253
  let hasStringModeOp = false;
1249
1254
  const clientOpKeys = [];
1255
+ let modeConfigValue = void 0;
1256
+ let hasModeConfig = false;
1250
1257
  for (const [op, opValue] of Object.entries(operators)) {
1258
+ if (op === "mode") {
1259
+ hasModeConfig = true;
1260
+ modeConfigValue = opValue;
1261
+ continue;
1262
+ }
1251
1263
  if (opValue === true) {
1252
1264
  opSchemas[op] = createOperatorSchema(
1253
1265
  fieldMeta,
@@ -1277,14 +1289,43 @@ function createWhereBuilder(typeMap, enumMap, scalarBase) {
1277
1289
  );
1278
1290
  }
1279
1291
  fieldForced[op] = parsed;
1292
+ if (fieldMeta.type === "String" && !fieldMeta.isList && STRING_MODE_OPS.has(op)) {
1293
+ hasStringModeOp = true;
1294
+ }
1280
1295
  }
1281
1296
  }
1282
1297
  if (!hasClientOps && Object.keys(fieldForced).length === 0) {
1298
+ if (hasModeConfig) {
1299
+ throw new ShapeError(
1300
+ `Where field "${fieldName}" on model "${model}" has "mode" but no operators. Add at least one operator (contains, startsWith, endsWith, equals).`
1301
+ );
1302
+ }
1283
1303
  throw new ShapeError(
1284
1304
  `Empty operator config for where field "${fieldName}" on model "${model}". Define at least one operator.`
1285
1305
  );
1286
1306
  }
1287
- if (hasStringModeOp) {
1307
+ if (hasModeConfig) {
1308
+ if (!hasStringModeOp) {
1309
+ throw new ShapeError(
1310
+ `"mode" on where field "${fieldName}" on model "${model}" requires a compatible String operator (contains, startsWith, endsWith, equals)`
1311
+ );
1312
+ }
1313
+ if (modeConfigValue === true) {
1314
+ opSchemas["mode"] = z4.enum(["default", "insensitive"]).optional();
1315
+ } else {
1316
+ const actualModeValue = isForcedValue(modeConfigValue) ? modeConfigValue.value : modeConfigValue;
1317
+ const modeSchema = z4.enum(["default", "insensitive"]);
1318
+ let parsed;
1319
+ try {
1320
+ parsed = modeSchema.parse(actualModeValue);
1321
+ } catch (err) {
1322
+ throw new ShapeError(
1323
+ `Invalid forced value for "${model}.${fieldName}.mode": ${err.message}`
1324
+ );
1325
+ }
1326
+ fieldForced["mode"] = parsed;
1327
+ }
1328
+ } else if (hasStringModeOp) {
1288
1329
  opSchemas["mode"] = z4.enum(["default", "insensitive"]).optional();
1289
1330
  }
1290
1331
  if (hasClientOps) {
@@ -2070,9 +2111,11 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2070
2111
  }
2071
2112
  if (method === "count" && shape.include)
2072
2113
  throw new ShapeError('count does not support "include"');
2073
- if (method === "groupBy" && shape.orderBy) {
2114
+ if (method === "groupBy" && shape.orderBy && shape.orderBy !== true) {
2074
2115
  const bySet = new Set(shape.by);
2075
2116
  for (const fieldName of Object.keys(shape.orderBy)) {
2117
+ if (fieldName === "_count")
2118
+ continue;
2076
2119
  if (!bySet.has(fieldName)) {
2077
2120
  throw new ShapeError(
2078
2121
  `orderBy field "${fieldName}" must be included in "by" for groupBy`
@@ -2150,11 +2193,29 @@ function createQueryBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
2150
2193
  forcedSelectCountWhere = result.forcedCountWhere;
2151
2194
  }
2152
2195
  }
2153
- if (shape.orderBy)
2154
- schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
2155
- model,
2156
- shape.orderBy
2157
- );
2196
+ if (shape.orderBy) {
2197
+ if (method === "groupBy" && shape.orderBy === true && shape.by) {
2198
+ const sortEnum = z7.enum(["asc", "desc"]);
2199
+ const groupByOrderFields = {};
2200
+ for (const field of shape.by) {
2201
+ groupByOrderFields[field] = sortEnum.optional();
2202
+ }
2203
+ groupByOrderFields["_count"] = sortEnum.optional();
2204
+ const fieldKeys = Object.keys(groupByOrderFields);
2205
+ const singleSchema = z7.object(groupByOrderFields).strict().refine(
2206
+ (v) => fieldKeys.some(
2207
+ (k) => v[k] !== void 0
2208
+ ),
2209
+ { message: "orderBy must specify at least one field" }
2210
+ );
2211
+ schemaFields["orderBy"] = z7.union([singleSchema, z7.array(singleSchema).min(1)]).optional();
2212
+ } else {
2213
+ schemaFields["orderBy"] = argsBuilder.buildOrderBySchema(
2214
+ model,
2215
+ shape.orderBy
2216
+ );
2217
+ }
2218
+ }
2158
2219
  if (shape.cursor)
2159
2220
  schemaFields["cursor"] = argsBuilder.buildCursorSchema(
2160
2221
  model,