prisma-guard 1.7.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.
- package/README.md +50 -6
- package/dist/runtime/index.cjs +79 -2
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.d.cts +1 -0
- package/dist/runtime/index.d.ts +1 -0
- package/dist/runtime/index.js +79 -2
- package/dist/runtime/index.js.map +1 -1
- package/package.json +1 -1
package/dist/runtime/index.d.cts
CHANGED
|
@@ -84,6 +84,7 @@ interface NestedIncludeArgs {
|
|
|
84
84
|
}
|
|
85
85
|
interface NestedSelectArgs {
|
|
86
86
|
select?: Record<string, true | NestedSelectArgs>;
|
|
87
|
+
include?: Record<string, true | NestedIncludeArgs>;
|
|
87
88
|
where?: Record<string, unknown>;
|
|
88
89
|
orderBy?: Record<string, OrderByFieldConfig>;
|
|
89
90
|
cursor?: Record<string, true>;
|
package/dist/runtime/index.d.ts
CHANGED
|
@@ -84,6 +84,7 @@ interface NestedIncludeArgs {
|
|
|
84
84
|
}
|
|
85
85
|
interface NestedSelectArgs {
|
|
86
86
|
select?: Record<string, true | NestedSelectArgs>;
|
|
87
|
+
include?: Record<string, true | NestedIncludeArgs>;
|
|
87
88
|
where?: Record<string, unknown>;
|
|
88
89
|
orderBy?: Record<string, OrderByFieldConfig>;
|
|
89
90
|
cursor?: Record<string, true>;
|
package/dist/runtime/index.js
CHANGED
|
@@ -1685,6 +1685,7 @@ var KNOWN_NESTED_INCLUDE_KEYS = /* @__PURE__ */ new Set([
|
|
|
1685
1685
|
]);
|
|
1686
1686
|
var KNOWN_NESTED_SELECT_KEYS = /* @__PURE__ */ new Set([
|
|
1687
1687
|
"select",
|
|
1688
|
+
"include",
|
|
1688
1689
|
"where",
|
|
1689
1690
|
"orderBy",
|
|
1690
1691
|
"cursor",
|
|
@@ -1938,10 +1939,13 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
|
|
|
1938
1939
|
KNOWN_NESTED_SELECT_KEYS,
|
|
1939
1940
|
`nested select for "${fieldName}" on model "${model}"`
|
|
1940
1941
|
);
|
|
1942
|
+
if (config.select && config.include) {
|
|
1943
|
+
throw new ShapeError(`Nested select for "${fieldName}" cannot define both "select" and "include".`);
|
|
1944
|
+
}
|
|
1941
1945
|
if (!fieldMeta.isList) {
|
|
1942
1946
|
if (config.where || config.orderBy || config.cursor || config.take || config.skip) {
|
|
1943
1947
|
throw new ShapeError(
|
|
1944
|
-
`Relation "${fieldName}" on model "${model}" is to-one. Only "select"
|
|
1948
|
+
`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.`
|
|
1945
1949
|
);
|
|
1946
1950
|
}
|
|
1947
1951
|
}
|
|
@@ -1957,6 +1961,16 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
|
|
|
1957
1961
|
relForced._countWherePlacement = "select";
|
|
1958
1962
|
}
|
|
1959
1963
|
}
|
|
1964
|
+
if (config.include) {
|
|
1965
|
+
const nested = buildIncludeSchema(fieldMeta.type, config.include, currentDepth + 1);
|
|
1966
|
+
nestedSchemas["include"] = nested.schema;
|
|
1967
|
+
if (Object.keys(nested.forcedTree).length > 0)
|
|
1968
|
+
relForced.include = nested.forcedTree;
|
|
1969
|
+
if (Object.keys(nested.forcedCountWhere).length > 0) {
|
|
1970
|
+
relForced._countWhere = nested.forcedCountWhere;
|
|
1971
|
+
relForced._countWherePlacement = "include";
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1960
1974
|
if (config.where) {
|
|
1961
1975
|
const { schema: whereSchema, forced } = deps.buildWhereSchema(
|
|
1962
1976
|
fieldMeta.type,
|
|
@@ -3066,6 +3080,8 @@ function buildDefaultSelectInput(config) {
|
|
|
3066
3080
|
const nested = {};
|
|
3067
3081
|
if (value.select)
|
|
3068
3082
|
nested.select = buildDefaultSelectInput(value.select);
|
|
3083
|
+
if (value.include)
|
|
3084
|
+
nested.include = buildDefaultIncludeInput(value.include);
|
|
3069
3085
|
result[key] = Object.keys(nested).length > 0 ? nested : true;
|
|
3070
3086
|
}
|
|
3071
3087
|
}
|
|
@@ -3114,6 +3130,41 @@ function buildDefaultProjectionBody(shape) {
|
|
|
3114
3130
|
}
|
|
3115
3131
|
return {};
|
|
3116
3132
|
}
|
|
3133
|
+
function applyClientProjectionOverrides(shapeDefault, clientProjection) {
|
|
3134
|
+
const result = { ...shapeDefault };
|
|
3135
|
+
for (const [key, clientValue] of Object.entries(clientProjection)) {
|
|
3136
|
+
const defaultValue = result[key];
|
|
3137
|
+
if (defaultValue === void 0) {
|
|
3138
|
+
result[key] = clientValue;
|
|
3139
|
+
continue;
|
|
3140
|
+
}
|
|
3141
|
+
if (clientValue === true) {
|
|
3142
|
+
result[key] = true;
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
3145
|
+
if (isPlainObject(clientValue)) {
|
|
3146
|
+
if (!isPlainObject(defaultValue)) {
|
|
3147
|
+
result[key] = clientValue;
|
|
3148
|
+
continue;
|
|
3149
|
+
}
|
|
3150
|
+
const merged = { ...defaultValue };
|
|
3151
|
+
const clientObj = clientValue;
|
|
3152
|
+
for (const [argKey, argValue] of Object.entries(clientObj)) {
|
|
3153
|
+
const defaultArgValue = merged[argKey];
|
|
3154
|
+
if ((argKey === "select" || argKey === "include") && isPlainObject(argValue) && isPlainObject(defaultArgValue)) {
|
|
3155
|
+
merged[argKey] = applyClientProjectionOverrides(
|
|
3156
|
+
defaultArgValue,
|
|
3157
|
+
argValue
|
|
3158
|
+
);
|
|
3159
|
+
} else {
|
|
3160
|
+
merged[argKey] = argValue;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
result[key] = merged;
|
|
3164
|
+
}
|
|
3165
|
+
}
|
|
3166
|
+
return result;
|
|
3167
|
+
}
|
|
3117
3168
|
function hasClientControlledValues(obj) {
|
|
3118
3169
|
for (const value of Object.values(obj)) {
|
|
3119
3170
|
if (isForcedValue(value))
|
|
@@ -3176,6 +3227,8 @@ function checkSelectForClientArgs(config) {
|
|
|
3176
3227
|
return true;
|
|
3177
3228
|
if (value.select && checkSelectForClientArgs(value.select))
|
|
3178
3229
|
return true;
|
|
3230
|
+
if (value.include && checkIncludeForClientArgs(value.include))
|
|
3231
|
+
return true;
|
|
3179
3232
|
}
|
|
3180
3233
|
return false;
|
|
3181
3234
|
}
|
|
@@ -3458,6 +3511,29 @@ function createModelGuardExtension(config) {
|
|
|
3458
3511
|
}
|
|
3459
3512
|
return where;
|
|
3460
3513
|
}
|
|
3514
|
+
function buildEffectiveReadBody(resolved) {
|
|
3515
|
+
const hasShapeProjection = !!resolved.shape.select || !!resolved.shape.include;
|
|
3516
|
+
if (!hasShapeProjection)
|
|
3517
|
+
return resolved.body;
|
|
3518
|
+
const defaultProjection = buildDefaultProjectionBody(resolved.shape);
|
|
3519
|
+
const hasBodyProjection = "select" in resolved.body || "include" in resolved.body;
|
|
3520
|
+
if (!hasBodyProjection) {
|
|
3521
|
+
return { ...resolved.body, ...defaultProjection };
|
|
3522
|
+
}
|
|
3523
|
+
const merged = { ...resolved.body };
|
|
3524
|
+
if ("select" in resolved.body && "select" in defaultProjection && isPlainObject(resolved.body.select) && isPlainObject(defaultProjection.select)) {
|
|
3525
|
+
merged.select = applyClientProjectionOverrides(
|
|
3526
|
+
defaultProjection.select,
|
|
3527
|
+
resolved.body.select
|
|
3528
|
+
);
|
|
3529
|
+
} else if ("include" in resolved.body && "include" in defaultProjection && isPlainObject(resolved.body.include) && isPlainObject(defaultProjection.include)) {
|
|
3530
|
+
merged.include = applyClientProjectionOverrides(
|
|
3531
|
+
defaultProjection.include,
|
|
3532
|
+
resolved.body.include
|
|
3533
|
+
);
|
|
3534
|
+
}
|
|
3535
|
+
return merged;
|
|
3536
|
+
}
|
|
3461
3537
|
function makeReadMethod(method) {
|
|
3462
3538
|
return (body) => {
|
|
3463
3539
|
const caller = resolveCaller();
|
|
@@ -3473,7 +3549,8 @@ function createModelGuardExtension(config) {
|
|
|
3473
3549
|
resolved.wasDynamic
|
|
3474
3550
|
);
|
|
3475
3551
|
const isUnique = UNIQUE_READ_METHODS.has(method);
|
|
3476
|
-
const
|
|
3552
|
+
const effectiveBody = buildEffectiveReadBody(resolved);
|
|
3553
|
+
const args = applyBuiltShape(built, effectiveBody, isUnique);
|
|
3477
3554
|
if (isUnique && args.where) {
|
|
3478
3555
|
validateResolvedUniqueWhere(
|
|
3479
3556
|
modelName,
|