prisma-guard 1.8.0 → 1.9.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.
@@ -1715,6 +1715,7 @@ var KNOWN_NESTED_INCLUDE_KEYS = /* @__PURE__ */ new Set([
1715
1715
  ]);
1716
1716
  var KNOWN_NESTED_SELECT_KEYS = /* @__PURE__ */ new Set([
1717
1717
  "select",
1718
+ "include",
1718
1719
  "where",
1719
1720
  "orderBy",
1720
1721
  "cursor",
@@ -1968,10 +1969,13 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
1968
1969
  KNOWN_NESTED_SELECT_KEYS,
1969
1970
  `nested select for "${fieldName}" on model "${model}"`
1970
1971
  );
1972
+ if (config.select && config.include) {
1973
+ throw new ShapeError(`Nested select for "${fieldName}" cannot define both "select" and "include".`);
1974
+ }
1971
1975
  if (!fieldMeta.isList) {
1972
1976
  if (config.where || config.orderBy || config.cursor || config.take || config.skip) {
1973
1977
  throw new ShapeError(
1974
- `Relation "${fieldName}" on model "${model}" is to-one. Only "select" is supported for to-one nested reads, not where/orderBy/cursor/take/skip.`
1978
+ `Relation "${fieldName}" on model "${model}" is to-one. Only "select" and "include" are supported for to-one nested reads, not where/orderBy/cursor/take/skip.`
1975
1979
  );
1976
1980
  }
1977
1981
  }
@@ -1987,6 +1991,16 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
1987
1991
  relForced._countWherePlacement = "select";
1988
1992
  }
1989
1993
  }
1994
+ if (config.include) {
1995
+ const nested = buildIncludeSchema(fieldMeta.type, config.include, currentDepth + 1);
1996
+ nestedSchemas["include"] = nested.schema;
1997
+ if (Object.keys(nested.forcedTree).length > 0)
1998
+ relForced.include = nested.forcedTree;
1999
+ if (Object.keys(nested.forcedCountWhere).length > 0) {
2000
+ relForced._countWhere = nested.forcedCountWhere;
2001
+ relForced._countWherePlacement = "include";
2002
+ }
2003
+ }
1990
2004
  if (config.where) {
1991
2005
  const { schema: whereSchema, forced } = deps.buildWhereSchema(
1992
2006
  fieldMeta.type,
@@ -3096,6 +3110,8 @@ function buildDefaultSelectInput(config) {
3096
3110
  const nested = {};
3097
3111
  if (value.select)
3098
3112
  nested.select = buildDefaultSelectInput(value.select);
3113
+ if (value.include)
3114
+ nested.include = buildDefaultIncludeInput(value.include);
3099
3115
  result[key] = Object.keys(nested).length > 0 ? nested : true;
3100
3116
  }
3101
3117
  }
@@ -3144,6 +3160,41 @@ function buildDefaultProjectionBody(shape) {
3144
3160
  }
3145
3161
  return {};
3146
3162
  }
3163
+ function applyClientProjectionOverrides(shapeDefault, clientProjection) {
3164
+ const result = { ...shapeDefault };
3165
+ for (const [key, clientValue] of Object.entries(clientProjection)) {
3166
+ const defaultValue = result[key];
3167
+ if (defaultValue === void 0) {
3168
+ result[key] = clientValue;
3169
+ continue;
3170
+ }
3171
+ if (clientValue === true) {
3172
+ result[key] = true;
3173
+ continue;
3174
+ }
3175
+ if (isPlainObject(clientValue)) {
3176
+ if (!isPlainObject(defaultValue)) {
3177
+ result[key] = clientValue;
3178
+ continue;
3179
+ }
3180
+ const merged = { ...defaultValue };
3181
+ const clientObj = clientValue;
3182
+ for (const [argKey, argValue] of Object.entries(clientObj)) {
3183
+ const defaultArgValue = merged[argKey];
3184
+ if ((argKey === "select" || argKey === "include") && isPlainObject(argValue) && isPlainObject(defaultArgValue)) {
3185
+ merged[argKey] = applyClientProjectionOverrides(
3186
+ defaultArgValue,
3187
+ argValue
3188
+ );
3189
+ } else {
3190
+ merged[argKey] = argValue;
3191
+ }
3192
+ }
3193
+ result[key] = merged;
3194
+ }
3195
+ }
3196
+ return result;
3197
+ }
3147
3198
  function hasClientControlledValues(obj) {
3148
3199
  for (const value of Object.values(obj)) {
3149
3200
  if (isForcedValue(value))
@@ -3206,6 +3257,8 @@ function checkSelectForClientArgs(config) {
3206
3257
  return true;
3207
3258
  if (value.select && checkSelectForClientArgs(value.select))
3208
3259
  return true;
3260
+ if (value.include && checkIncludeForClientArgs(value.include))
3261
+ return true;
3209
3262
  }
3210
3263
  return false;
3211
3264
  }
@@ -3488,6 +3541,29 @@ function createModelGuardExtension(config) {
3488
3541
  }
3489
3542
  return where;
3490
3543
  }
3544
+ function buildEffectiveReadBody(resolved) {
3545
+ const hasShapeProjection = !!resolved.shape.select || !!resolved.shape.include;
3546
+ if (!hasShapeProjection)
3547
+ return resolved.body;
3548
+ const defaultProjection = buildDefaultProjectionBody(resolved.shape);
3549
+ const hasBodyProjection = "select" in resolved.body || "include" in resolved.body;
3550
+ if (!hasBodyProjection) {
3551
+ return { ...resolved.body, ...defaultProjection };
3552
+ }
3553
+ const merged = { ...resolved.body };
3554
+ if ("select" in resolved.body && "select" in defaultProjection && isPlainObject(resolved.body.select) && isPlainObject(defaultProjection.select)) {
3555
+ merged.select = applyClientProjectionOverrides(
3556
+ defaultProjection.select,
3557
+ resolved.body.select
3558
+ );
3559
+ } else if ("include" in resolved.body && "include" in defaultProjection && isPlainObject(resolved.body.include) && isPlainObject(defaultProjection.include)) {
3560
+ merged.include = applyClientProjectionOverrides(
3561
+ defaultProjection.include,
3562
+ resolved.body.include
3563
+ );
3564
+ }
3565
+ return merged;
3566
+ }
3491
3567
  function makeReadMethod(method) {
3492
3568
  return (body) => {
3493
3569
  const caller = resolveCaller();
@@ -3503,17 +3579,7 @@ function createModelGuardExtension(config) {
3503
3579
  resolved.wasDynamic
3504
3580
  );
3505
3581
  const isUnique = UNIQUE_READ_METHODS.has(method);
3506
- let effectiveBody = resolved.body;
3507
- const hasShapeProjection = !!resolved.shape.select || !!resolved.shape.include;
3508
- if (hasShapeProjection) {
3509
- const hasBodyProjection = "select" in resolved.body || "include" in resolved.body;
3510
- if (!hasBodyProjection) {
3511
- effectiveBody = {
3512
- ...resolved.body,
3513
- ...buildDefaultProjectionBody(resolved.shape)
3514
- };
3515
- }
3516
- }
3582
+ const effectiveBody = buildEffectiveReadBody(resolved);
3517
3583
  const args = applyBuiltShape(built, effectiveBody, isUnique);
3518
3584
  if (isUnique && args.where) {
3519
3585
  validateResolvedUniqueWhere(