prisma-guard 1.3.1 → 1.4.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.
@@ -1284,23 +1284,80 @@ function requireConfigTrue(config, context) {
1284
1284
  }
1285
1285
  }
1286
1286
  function createArgsBuilder(typeMap, enumMap, uniqueMap, scalarBase) {
1287
+ const sortEnum = import_zod5.z.enum(["asc", "desc"]);
1288
+ const nullsEnum = import_zod5.z.enum(["first", "last"]);
1289
+ const sortWithNulls = import_zod5.z.object({ sort: sortEnum, nulls: nullsEnum.optional() }).strict();
1290
+ const scalarOrderSchema = import_zod5.z.union([sortEnum, sortWithNulls]);
1291
+ function validateScalarOrderByField(fieldName, model, modelFields) {
1292
+ const fieldMeta = modelFields[fieldName];
1293
+ if (!fieldMeta)
1294
+ throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
1295
+ if (fieldMeta.isRelation)
1296
+ throw new ShapeError(`Relation field "${fieldName}" in orderBy requires a nested config object, not true`);
1297
+ if (fieldMeta.type === "Json")
1298
+ throw new ShapeError(`Json field "${fieldName}" cannot be used in orderBy`);
1299
+ if (fieldMeta.isList)
1300
+ throw new ShapeError(`List field "${fieldName}" cannot be used in orderBy`);
1301
+ }
1287
1302
  function buildOrderBySchema(model, orderByConfig) {
1288
1303
  const modelFields = typeMap[model];
1289
1304
  if (!modelFields)
1290
1305
  throw new ShapeError(`Unknown model: ${model}`);
1291
- requireConfigTrue(orderByConfig, `orderBy on model "${model}"`);
1292
1306
  const fieldSchemas = {};
1293
- for (const fieldName of Object.keys(orderByConfig)) {
1307
+ for (const [fieldName, config] of Object.entries(orderByConfig)) {
1294
1308
  const fieldMeta = modelFields[fieldName];
1295
1309
  if (!fieldMeta)
1296
1310
  throw new ShapeError(`Unknown field "${fieldName}" on model "${model}"`);
1297
- if (fieldMeta.isRelation)
1298
- throw new ShapeError(`Relation field "${fieldName}" cannot be used in orderBy`);
1299
- if (fieldMeta.type === "Json")
1300
- throw new ShapeError(`Json field "${fieldName}" cannot be used in orderBy`);
1301
- if (fieldMeta.isList)
1302
- throw new ShapeError(`List field "${fieldName}" cannot be used in orderBy`);
1303
- fieldSchemas[fieldName] = import_zod5.z.enum(["asc", "desc"]).optional();
1311
+ if (config === true) {
1312
+ validateScalarOrderByField(fieldName, model, modelFields);
1313
+ fieldSchemas[fieldName] = scalarOrderSchema.optional();
1314
+ continue;
1315
+ }
1316
+ if (typeof config !== "object" || config === null) {
1317
+ throw new ShapeError(`Invalid orderBy config for "${fieldName}" on model "${model}": expected true or a nested config object`);
1318
+ }
1319
+ if (!fieldMeta.isRelation) {
1320
+ throw new ShapeError(`Scalar field "${fieldName}" in orderBy does not accept nested config`);
1321
+ }
1322
+ if (Object.keys(config).length === 0) {
1323
+ throw new ShapeError(`Empty orderBy config for relation "${fieldName}" on model "${model}". Define at least one nested field.`);
1324
+ }
1325
+ if (fieldMeta.isList) {
1326
+ const relKeys = Object.keys(config);
1327
+ if (relKeys.length !== 1 || relKeys[0] !== "_count") {
1328
+ throw new ShapeError(`To-many relation "${fieldName}" in orderBy only supports { _count: true }`);
1329
+ }
1330
+ if (config._count !== true) {
1331
+ throw new ShapeError(`_count in orderBy for "${fieldName}" must be true`);
1332
+ }
1333
+ fieldSchemas[fieldName] = import_zod5.z.object({ _count: sortEnum }).strict().optional();
1334
+ continue;
1335
+ }
1336
+ const relatedModel = fieldMeta.type;
1337
+ const relatedFields = typeMap[relatedModel];
1338
+ if (!relatedFields)
1339
+ throw new ShapeError(`Related model "${relatedModel}" not found in type map`);
1340
+ const nestedSchemas = {};
1341
+ for (const [nestedField, nestedVal] of Object.entries(config)) {
1342
+ if (nestedVal !== true) {
1343
+ throw new ShapeError(`Nested orderBy field "${nestedField}" on relation "${fieldName}" must be true`);
1344
+ }
1345
+ const nestedMeta = relatedFields[nestedField];
1346
+ if (!nestedMeta)
1347
+ throw new ShapeError(`Unknown field "${nestedField}" on model "${relatedModel}" in orderBy`);
1348
+ if (nestedMeta.isRelation)
1349
+ throw new ShapeError(`Nested relation "${nestedField}" in orderBy on "${fieldName}" is not supported`);
1350
+ if (nestedMeta.type === "Json")
1351
+ throw new ShapeError(`Json field "${nestedField}" cannot be used in orderBy`);
1352
+ if (nestedMeta.isList)
1353
+ throw new ShapeError(`List field "${nestedField}" cannot be used in orderBy`);
1354
+ nestedSchemas[nestedField] = scalarOrderSchema.optional();
1355
+ }
1356
+ const nestedKeys = Object.keys(nestedSchemas);
1357
+ fieldSchemas[fieldName] = import_zod5.z.object(nestedSchemas).strict().refine(
1358
+ (v) => nestedKeys.some((k) => v[k] !== void 0),
1359
+ { message: `orderBy for relation "${fieldName}" must specify at least one field` }
1360
+ ).optional();
1304
1361
  }
1305
1362
  const fieldKeys = Object.keys(fieldSchemas);
1306
1363
  const singleSchema = import_zod5.z.object(fieldSchemas).strict().refine(