prisma-guard 1.21.0 → 1.22.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.
@@ -95,7 +95,7 @@ interface NestedSelectArgs {
95
95
  };
96
96
  skip?: true;
97
97
  }
98
- type ShapeOrFn<TCtx = unknown> = ShapeConfig | ((ctx: TCtx) => ShapeConfig);
98
+ type ShapeOrFn$1<TCtx = unknown> = ShapeConfig | ((ctx: TCtx) => ShapeConfig);
99
99
  interface ScopeEntry {
100
100
  readonly fk: string;
101
101
  readonly root: string;
@@ -150,7 +150,7 @@ type GuardInput = GuardShapeOrFn | Record<string, GuardShapeOrFn>;
150
150
  type GuardableMethodName = QueryMethod | MutationMethod;
151
151
  type ExtractReturn<T, K extends string> = K extends keyof T ? T[K] extends (...args: any[]) => infer R ? R : never : never;
152
152
  type GuardedModel<TDelegate> = {
153
- [K in GuardableMethodName as K extends keyof TDelegate ? K : never]: ExtractReturn<TDelegate, K> extends never ? never : (body: unknown) => ExtractReturn<TDelegate, K>;
153
+ [K in GuardableMethodName as K extends keyof TDelegate ? K : never]: ExtractReturn<TDelegate, K> extends never ? never : (body?: unknown) => ExtractReturn<TDelegate, K>;
154
154
  };
155
155
 
156
156
  declare function createGuard<TModels extends TypeMap = TypeMap, TRoots extends string = string, TModelExt = unknown>(config: GuardConfig & {
@@ -158,7 +158,7 @@ declare function createGuard<TModels extends TypeMap = TypeMap, TRoots extends s
158
158
  }): {
159
159
  input: (model: Extract<keyof TModels, string>, opts: InputOpts) => InputSchema;
160
160
  model: (model: Extract<keyof TModels, string>, opts: ModelOpts) => zod.ZodObject<any, zod_v4_core.$strip>;
161
- query: <TCtx = unknown>(model: Extract<keyof TModels, string>, method: QueryMethod, config_: ShapeOrFn<TCtx> | Record<string, ShapeOrFn<TCtx>>) => QuerySchema<TCtx>;
161
+ query: <TCtx = unknown>(model: Extract<keyof TModels, string>, method: QueryMethod, config_: ShapeOrFn$1<TCtx> | Record<string, ShapeOrFn$1<TCtx>>) => QuerySchema<TCtx>;
162
162
  extension: <TCtx extends Record<string, unknown> = Record<string, unknown>>(contextFn?: () => TCtx) => {
163
163
  name: string;
164
164
  model: TModelExt;
@@ -191,4 +191,138 @@ declare function unsupported(): {
191
191
  __brand: 'unsupported';
192
192
  };
193
193
 
194
- export { CallerError, type EnumMap, type FieldMeta, type GuardConfig, type GuardGeneratedConfig, type GuardInput, type GuardLogger, type GuardShape, type GuardShapeOrFn, type GuardedModel, type InputOpts, type InputSchema, type MissingScopeContextMode, type ModelOpts, type MutationMethod, type NestedIncludeArgs, type NestedSelectArgs, PolicyError, type QueryMethod, type QuerySchema, type ScopeEntry, type ScopeMap, type ShapeConfig, ShapeError, type ShapeOrFn, type TypeMap, type UniqueConstraint, type UniqueMap, type ZodChains, type ZodDefaults, createGuard, force, unsupported };
194
+ declare const OPERATION_SHAPE_KEYS: {
195
+ readonly findMany: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
196
+ readonly findFirst: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
197
+ readonly findFirstOrThrow: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
198
+ readonly findUnique: readonly ["where", "include", "select"];
199
+ readonly findUniqueOrThrow: readonly ["where", "include", "select"];
200
+ readonly findManyPaginated: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
201
+ readonly count: readonly ["where", "select", "cursor", "orderBy", "skip", "take"];
202
+ readonly aggregate: readonly ["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"];
203
+ readonly groupBy: readonly ["where", "by", "having", "_count", "_avg", "_sum", "_min", "_max", "orderBy", "take", "skip"];
204
+ readonly create: readonly ["data", "select", "include"];
205
+ readonly createMany: readonly ["data"];
206
+ readonly createManyAndReturn: readonly ["data", "select", "include"];
207
+ readonly update: readonly ["data", "where", "select", "include"];
208
+ readonly updateMany: readonly ["data", "where"];
209
+ readonly updateManyAndReturn: readonly ["data", "where", "select", "include"];
210
+ readonly upsert: readonly ["where", "create", "update", "select", "include"];
211
+ readonly delete: readonly ["where", "select", "include"];
212
+ readonly deleteMany: readonly ["where"];
213
+ };
214
+ type OperationName = keyof typeof OPERATION_SHAPE_KEYS;
215
+ type OperationShapeKey<O extends OperationName> = (typeof OPERATION_SHAPE_KEYS)[O][number];
216
+
217
+ interface FieldMetaConst {
218
+ readonly type: string;
219
+ readonly isList: boolean;
220
+ readonly isRequired: boolean;
221
+ readonly isId: boolean;
222
+ readonly isRelation: boolean;
223
+ readonly hasDefault: boolean;
224
+ readonly isUpdatedAt: boolean;
225
+ readonly isEnum?: boolean;
226
+ readonly isUnique?: boolean;
227
+ readonly isUnsupported?: boolean;
228
+ }
229
+ type TypeMapConst = Record<string, Record<string, FieldMetaConst>>;
230
+ type ShapeDepth = 0 | 1 | 2 | 3;
231
+ type DecDepth<D extends ShapeDepth> = D extends 3 ? 2 : D extends 2 ? 1 : D extends 1 ? 0 : 0;
232
+ type AllFields<TM extends TypeMapConst, M extends keyof TM> = keyof TM[M] & string;
233
+ type ScalarFields<TM extends TypeMapConst, M extends keyof TM> = {
234
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : K;
235
+ }[keyof TM[M]] & string;
236
+ type RelationFields<TM extends TypeMapConst, M extends keyof TM> = {
237
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? K : never;
238
+ }[keyof TM[M]] & string;
239
+ type WritableFields<TM extends TypeMapConst, M extends keyof TM> = {
240
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['isUpdatedAt'] extends true ? never : K;
241
+ }[keyof TM[M]] & string;
242
+ type UniqueFields<TM extends TypeMapConst, M extends keyof TM> = {
243
+ [K in keyof TM[M]]: TM[M][K]['isUnique'] extends true ? K : TM[M][K]['isId'] extends true ? K : never;
244
+ }[keyof TM[M]] & string;
245
+ type NumericScalarType = 'Int' | 'BigInt' | 'Float' | 'Decimal';
246
+ type ComparableScalarType = NumericScalarType | 'String' | 'DateTime';
247
+ type NumericFields<TM extends TypeMapConst, M extends keyof TM> = {
248
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['type'] extends NumericScalarType ? K : never;
249
+ }[keyof TM[M]] & string;
250
+ type ComparableFields<TM extends TypeMapConst, M extends keyof TM> = {
251
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['type'] extends ComparableScalarType ? K : never;
252
+ }[keyof TM[M]] & string;
253
+ type RelTarget<TM extends TypeMapConst, M extends keyof TM, K extends keyof TM[M]> = TM[M][K]['type'] extends string ? Extract<keyof TM, TM[M][K]['type']> : never;
254
+ type LooseNestedArgs = {
255
+ select?: Record<string, unknown>;
256
+ include?: Record<string, unknown>;
257
+ where?: Record<string, unknown>;
258
+ orderBy?: Record<string, unknown>;
259
+ cursor?: Record<string, unknown>;
260
+ take?: number | {
261
+ max: number;
262
+ default?: number;
263
+ };
264
+ skip?: true;
265
+ };
266
+ type TypedWhere<TM extends TypeMapConst, M extends keyof TM> = Partial<Record<AllFields<TM, M> | 'AND' | 'OR' | 'NOT', unknown>>;
267
+ type TypedNestedRelArgs<TM extends TypeMapConst, T, D extends ShapeDepth> = T extends keyof TM ? D extends 0 ? LooseNestedArgs : {
268
+ select?: TypedProjection<TM, T, DecDepth<D>>;
269
+ include?: TypedInclude<TM, T, DecDepth<D>>;
270
+ where?: TypedWhere<TM, T>;
271
+ orderBy?: true | Partial<Record<AllFields<TM, T>, unknown>>;
272
+ cursor?: Partial<Record<UniqueFields<TM, T>, true>>;
273
+ take?: number | {
274
+ max: number;
275
+ default?: number;
276
+ };
277
+ skip?: true;
278
+ } : LooseNestedArgs;
279
+ type TypedProjection<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
280
+ [K in AllFields<TM, M>]?: K extends RelationFields<TM, M> ? true | TypedNestedRelArgs<TM, RelTarget<TM, M, K>, D> : true;
281
+ };
282
+ type TypedInclude<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
283
+ [K in RelationFields<TM, M>]?: true | TypedNestedRelArgs<TM, RelTarget<TM, M, K>, D>;
284
+ };
285
+ type TypedCountSelect<TM extends TypeMapConst, M extends keyof TM> = Partial<Record<ScalarFields<TM, M> | '_all', true>>;
286
+ type TypedCountField<TM extends TypeMapConst, M extends keyof TM> = true | Partial<Record<ScalarFields<TM, M> | '_all', true>>;
287
+ type TypedShapeProps<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
288
+ where: TypedWhere<TM, M>;
289
+ select: TypedProjection<TM, M, D>;
290
+ include: TypedInclude<TM, M, D>;
291
+ orderBy: true | Partial<Record<AllFields<TM, M>, unknown>>;
292
+ cursor: Partial<Record<UniqueFields<TM, M>, true>>;
293
+ take: number | {
294
+ max: number;
295
+ default?: number;
296
+ };
297
+ skip: true;
298
+ distinct: ScalarFields<TM, M>[];
299
+ by: ScalarFields<TM, M>[];
300
+ having: Partial<Record<ScalarFields<TM, M>, unknown>>;
301
+ _count: TypedCountField<TM, M>;
302
+ _avg: Partial<Record<NumericFields<TM, M>, true>>;
303
+ _sum: Partial<Record<NumericFields<TM, M>, true>>;
304
+ _min: Partial<Record<ComparableFields<TM, M>, true>>;
305
+ _max: Partial<Record<ComparableFields<TM, M>, true>>;
306
+ data: Partial<Record<WritableFields<TM, M>, unknown>>;
307
+ create: Partial<Record<WritableFields<TM, M>, unknown>>;
308
+ update: Partial<Record<WritableFields<TM, M>, unknown>>;
309
+ };
310
+ type BaseOperationShape<TM extends TypeMapConst, M extends keyof TM, O extends OperationName, D extends ShapeDepth> = Partial<Pick<TypedShapeProps<TM, M, D>, Extract<OperationShapeKey<O>, keyof TypedShapeProps<TM, M, D>>>>;
311
+ type RequireKeys<T, K extends keyof T> = Omit<T, K> & {
312
+ [P in K]-?: NonNullable<T[P]>;
313
+ };
314
+ type CountShape<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = Omit<BaseOperationShape<TM, M, 'count', D>, 'select'> & {
315
+ select?: TypedCountSelect<TM, M>;
316
+ };
317
+ type OperationShape<TM extends TypeMapConst, M extends keyof TM, O extends OperationName, D extends ShapeDepth = 1> = O extends 'findUnique' ? RequireKeys<BaseOperationShape<TM, M, 'findUnique', D>, 'where'> : O extends 'findUniqueOrThrow' ? RequireKeys<BaseOperationShape<TM, M, 'findUniqueOrThrow', D>, 'where'> : O extends 'groupBy' ? RequireKeys<BaseOperationShape<TM, M, 'groupBy', D>, 'by'> : O extends 'count' ? CountShape<TM, M, D> : BaseOperationShape<TM, M, O, D>;
318
+ type TypedGuardShape<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth = 1> = Partial<TypedShapeProps<TM, M, D>>;
319
+ type ShapeFn<S, TCtx> = (ctx: TCtx) => S;
320
+ type ShapeOrFn<S, TCtx> = S | ShapeFn<S, TCtx>;
321
+ declare const namedShapeBrand: unique symbol;
322
+ type NamedShapeMap<S, TCtx> = Record<string, ShapeOrFn<S, TCtx>> & {
323
+ readonly [namedShapeBrand]: true;
324
+ };
325
+ declare function namedShapes<S, TCtx = unknown>(shapes: Record<string, ShapeOrFn<S, TCtx>>): NamedShapeMap<S, TCtx>;
326
+ type ShapeInput<S, TCtx = unknown> = ShapeOrFn<S, TCtx> | NamedShapeMap<S, TCtx>;
327
+
328
+ export { CallerError, type ComparableFields, type EnumMap, type FieldMeta, type FieldMetaConst, type GuardConfig, type GuardGeneratedConfig, type GuardInput, type GuardLogger, type GuardShape, type GuardShapeOrFn, type GuardedModel, type InputOpts, type InputSchema, type MissingScopeContextMode, type ModelOpts, type MutationMethod, type NamedShapeMap, type NestedIncludeArgs, type NestedSelectArgs, type NumericFields, type OperationName, type OperationShape, PolicyError, type QueryMethod, type QuerySchema, type ScopeEntry, type ScopeMap, type ShapeConfig, type ShapeDepth, ShapeError, type ShapeInput, type ShapeOrFn$1 as ShapeOrFn, type TypeMap, type TypeMapConst, type TypedCountSelect, type TypedGuardShape, type TypedInclude, type TypedProjection, type TypedShapeProps, type TypedWhere, type UniqueConstraint, type UniqueMap, type ZodChains, type ZodDefaults, createGuard, force, namedShapes, unsupported };
@@ -95,7 +95,7 @@ interface NestedSelectArgs {
95
95
  };
96
96
  skip?: true;
97
97
  }
98
- type ShapeOrFn<TCtx = unknown> = ShapeConfig | ((ctx: TCtx) => ShapeConfig);
98
+ type ShapeOrFn$1<TCtx = unknown> = ShapeConfig | ((ctx: TCtx) => ShapeConfig);
99
99
  interface ScopeEntry {
100
100
  readonly fk: string;
101
101
  readonly root: string;
@@ -150,7 +150,7 @@ type GuardInput = GuardShapeOrFn | Record<string, GuardShapeOrFn>;
150
150
  type GuardableMethodName = QueryMethod | MutationMethod;
151
151
  type ExtractReturn<T, K extends string> = K extends keyof T ? T[K] extends (...args: any[]) => infer R ? R : never : never;
152
152
  type GuardedModel<TDelegate> = {
153
- [K in GuardableMethodName as K extends keyof TDelegate ? K : never]: ExtractReturn<TDelegate, K> extends never ? never : (body: unknown) => ExtractReturn<TDelegate, K>;
153
+ [K in GuardableMethodName as K extends keyof TDelegate ? K : never]: ExtractReturn<TDelegate, K> extends never ? never : (body?: unknown) => ExtractReturn<TDelegate, K>;
154
154
  };
155
155
 
156
156
  declare function createGuard<TModels extends TypeMap = TypeMap, TRoots extends string = string, TModelExt = unknown>(config: GuardConfig & {
@@ -158,7 +158,7 @@ declare function createGuard<TModels extends TypeMap = TypeMap, TRoots extends s
158
158
  }): {
159
159
  input: (model: Extract<keyof TModels, string>, opts: InputOpts) => InputSchema;
160
160
  model: (model: Extract<keyof TModels, string>, opts: ModelOpts) => zod.ZodObject<any, zod_v4_core.$strip>;
161
- query: <TCtx = unknown>(model: Extract<keyof TModels, string>, method: QueryMethod, config_: ShapeOrFn<TCtx> | Record<string, ShapeOrFn<TCtx>>) => QuerySchema<TCtx>;
161
+ query: <TCtx = unknown>(model: Extract<keyof TModels, string>, method: QueryMethod, config_: ShapeOrFn$1<TCtx> | Record<string, ShapeOrFn$1<TCtx>>) => QuerySchema<TCtx>;
162
162
  extension: <TCtx extends Record<string, unknown> = Record<string, unknown>>(contextFn?: () => TCtx) => {
163
163
  name: string;
164
164
  model: TModelExt;
@@ -191,4 +191,138 @@ declare function unsupported(): {
191
191
  __brand: 'unsupported';
192
192
  };
193
193
 
194
- export { CallerError, type EnumMap, type FieldMeta, type GuardConfig, type GuardGeneratedConfig, type GuardInput, type GuardLogger, type GuardShape, type GuardShapeOrFn, type GuardedModel, type InputOpts, type InputSchema, type MissingScopeContextMode, type ModelOpts, type MutationMethod, type NestedIncludeArgs, type NestedSelectArgs, PolicyError, type QueryMethod, type QuerySchema, type ScopeEntry, type ScopeMap, type ShapeConfig, ShapeError, type ShapeOrFn, type TypeMap, type UniqueConstraint, type UniqueMap, type ZodChains, type ZodDefaults, createGuard, force, unsupported };
194
+ declare const OPERATION_SHAPE_KEYS: {
195
+ readonly findMany: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
196
+ readonly findFirst: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
197
+ readonly findFirstOrThrow: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
198
+ readonly findUnique: readonly ["where", "include", "select"];
199
+ readonly findUniqueOrThrow: readonly ["where", "include", "select"];
200
+ readonly findManyPaginated: readonly ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"];
201
+ readonly count: readonly ["where", "select", "cursor", "orderBy", "skip", "take"];
202
+ readonly aggregate: readonly ["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"];
203
+ readonly groupBy: readonly ["where", "by", "having", "_count", "_avg", "_sum", "_min", "_max", "orderBy", "take", "skip"];
204
+ readonly create: readonly ["data", "select", "include"];
205
+ readonly createMany: readonly ["data"];
206
+ readonly createManyAndReturn: readonly ["data", "select", "include"];
207
+ readonly update: readonly ["data", "where", "select", "include"];
208
+ readonly updateMany: readonly ["data", "where"];
209
+ readonly updateManyAndReturn: readonly ["data", "where", "select", "include"];
210
+ readonly upsert: readonly ["where", "create", "update", "select", "include"];
211
+ readonly delete: readonly ["where", "select", "include"];
212
+ readonly deleteMany: readonly ["where"];
213
+ };
214
+ type OperationName = keyof typeof OPERATION_SHAPE_KEYS;
215
+ type OperationShapeKey<O extends OperationName> = (typeof OPERATION_SHAPE_KEYS)[O][number];
216
+
217
+ interface FieldMetaConst {
218
+ readonly type: string;
219
+ readonly isList: boolean;
220
+ readonly isRequired: boolean;
221
+ readonly isId: boolean;
222
+ readonly isRelation: boolean;
223
+ readonly hasDefault: boolean;
224
+ readonly isUpdatedAt: boolean;
225
+ readonly isEnum?: boolean;
226
+ readonly isUnique?: boolean;
227
+ readonly isUnsupported?: boolean;
228
+ }
229
+ type TypeMapConst = Record<string, Record<string, FieldMetaConst>>;
230
+ type ShapeDepth = 0 | 1 | 2 | 3;
231
+ type DecDepth<D extends ShapeDepth> = D extends 3 ? 2 : D extends 2 ? 1 : D extends 1 ? 0 : 0;
232
+ type AllFields<TM extends TypeMapConst, M extends keyof TM> = keyof TM[M] & string;
233
+ type ScalarFields<TM extends TypeMapConst, M extends keyof TM> = {
234
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : K;
235
+ }[keyof TM[M]] & string;
236
+ type RelationFields<TM extends TypeMapConst, M extends keyof TM> = {
237
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? K : never;
238
+ }[keyof TM[M]] & string;
239
+ type WritableFields<TM extends TypeMapConst, M extends keyof TM> = {
240
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['isUpdatedAt'] extends true ? never : K;
241
+ }[keyof TM[M]] & string;
242
+ type UniqueFields<TM extends TypeMapConst, M extends keyof TM> = {
243
+ [K in keyof TM[M]]: TM[M][K]['isUnique'] extends true ? K : TM[M][K]['isId'] extends true ? K : never;
244
+ }[keyof TM[M]] & string;
245
+ type NumericScalarType = 'Int' | 'BigInt' | 'Float' | 'Decimal';
246
+ type ComparableScalarType = NumericScalarType | 'String' | 'DateTime';
247
+ type NumericFields<TM extends TypeMapConst, M extends keyof TM> = {
248
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['type'] extends NumericScalarType ? K : never;
249
+ }[keyof TM[M]] & string;
250
+ type ComparableFields<TM extends TypeMapConst, M extends keyof TM> = {
251
+ [K in keyof TM[M]]: TM[M][K]['isRelation'] extends true ? never : TM[M][K]['type'] extends ComparableScalarType ? K : never;
252
+ }[keyof TM[M]] & string;
253
+ type RelTarget<TM extends TypeMapConst, M extends keyof TM, K extends keyof TM[M]> = TM[M][K]['type'] extends string ? Extract<keyof TM, TM[M][K]['type']> : never;
254
+ type LooseNestedArgs = {
255
+ select?: Record<string, unknown>;
256
+ include?: Record<string, unknown>;
257
+ where?: Record<string, unknown>;
258
+ orderBy?: Record<string, unknown>;
259
+ cursor?: Record<string, unknown>;
260
+ take?: number | {
261
+ max: number;
262
+ default?: number;
263
+ };
264
+ skip?: true;
265
+ };
266
+ type TypedWhere<TM extends TypeMapConst, M extends keyof TM> = Partial<Record<AllFields<TM, M> | 'AND' | 'OR' | 'NOT', unknown>>;
267
+ type TypedNestedRelArgs<TM extends TypeMapConst, T, D extends ShapeDepth> = T extends keyof TM ? D extends 0 ? LooseNestedArgs : {
268
+ select?: TypedProjection<TM, T, DecDepth<D>>;
269
+ include?: TypedInclude<TM, T, DecDepth<D>>;
270
+ where?: TypedWhere<TM, T>;
271
+ orderBy?: true | Partial<Record<AllFields<TM, T>, unknown>>;
272
+ cursor?: Partial<Record<UniqueFields<TM, T>, true>>;
273
+ take?: number | {
274
+ max: number;
275
+ default?: number;
276
+ };
277
+ skip?: true;
278
+ } : LooseNestedArgs;
279
+ type TypedProjection<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
280
+ [K in AllFields<TM, M>]?: K extends RelationFields<TM, M> ? true | TypedNestedRelArgs<TM, RelTarget<TM, M, K>, D> : true;
281
+ };
282
+ type TypedInclude<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
283
+ [K in RelationFields<TM, M>]?: true | TypedNestedRelArgs<TM, RelTarget<TM, M, K>, D>;
284
+ };
285
+ type TypedCountSelect<TM extends TypeMapConst, M extends keyof TM> = Partial<Record<ScalarFields<TM, M> | '_all', true>>;
286
+ type TypedCountField<TM extends TypeMapConst, M extends keyof TM> = true | Partial<Record<ScalarFields<TM, M> | '_all', true>>;
287
+ type TypedShapeProps<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = {
288
+ where: TypedWhere<TM, M>;
289
+ select: TypedProjection<TM, M, D>;
290
+ include: TypedInclude<TM, M, D>;
291
+ orderBy: true | Partial<Record<AllFields<TM, M>, unknown>>;
292
+ cursor: Partial<Record<UniqueFields<TM, M>, true>>;
293
+ take: number | {
294
+ max: number;
295
+ default?: number;
296
+ };
297
+ skip: true;
298
+ distinct: ScalarFields<TM, M>[];
299
+ by: ScalarFields<TM, M>[];
300
+ having: Partial<Record<ScalarFields<TM, M>, unknown>>;
301
+ _count: TypedCountField<TM, M>;
302
+ _avg: Partial<Record<NumericFields<TM, M>, true>>;
303
+ _sum: Partial<Record<NumericFields<TM, M>, true>>;
304
+ _min: Partial<Record<ComparableFields<TM, M>, true>>;
305
+ _max: Partial<Record<ComparableFields<TM, M>, true>>;
306
+ data: Partial<Record<WritableFields<TM, M>, unknown>>;
307
+ create: Partial<Record<WritableFields<TM, M>, unknown>>;
308
+ update: Partial<Record<WritableFields<TM, M>, unknown>>;
309
+ };
310
+ type BaseOperationShape<TM extends TypeMapConst, M extends keyof TM, O extends OperationName, D extends ShapeDepth> = Partial<Pick<TypedShapeProps<TM, M, D>, Extract<OperationShapeKey<O>, keyof TypedShapeProps<TM, M, D>>>>;
311
+ type RequireKeys<T, K extends keyof T> = Omit<T, K> & {
312
+ [P in K]-?: NonNullable<T[P]>;
313
+ };
314
+ type CountShape<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth> = Omit<BaseOperationShape<TM, M, 'count', D>, 'select'> & {
315
+ select?: TypedCountSelect<TM, M>;
316
+ };
317
+ type OperationShape<TM extends TypeMapConst, M extends keyof TM, O extends OperationName, D extends ShapeDepth = 1> = O extends 'findUnique' ? RequireKeys<BaseOperationShape<TM, M, 'findUnique', D>, 'where'> : O extends 'findUniqueOrThrow' ? RequireKeys<BaseOperationShape<TM, M, 'findUniqueOrThrow', D>, 'where'> : O extends 'groupBy' ? RequireKeys<BaseOperationShape<TM, M, 'groupBy', D>, 'by'> : O extends 'count' ? CountShape<TM, M, D> : BaseOperationShape<TM, M, O, D>;
318
+ type TypedGuardShape<TM extends TypeMapConst, M extends keyof TM, D extends ShapeDepth = 1> = Partial<TypedShapeProps<TM, M, D>>;
319
+ type ShapeFn<S, TCtx> = (ctx: TCtx) => S;
320
+ type ShapeOrFn<S, TCtx> = S | ShapeFn<S, TCtx>;
321
+ declare const namedShapeBrand: unique symbol;
322
+ type NamedShapeMap<S, TCtx> = Record<string, ShapeOrFn<S, TCtx>> & {
323
+ readonly [namedShapeBrand]: true;
324
+ };
325
+ declare function namedShapes<S, TCtx = unknown>(shapes: Record<string, ShapeOrFn<S, TCtx>>): NamedShapeMap<S, TCtx>;
326
+ type ShapeInput<S, TCtx = unknown> = ShapeOrFn<S, TCtx> | NamedShapeMap<S, TCtx>;
327
+
328
+ export { CallerError, type ComparableFields, type EnumMap, type FieldMeta, type FieldMetaConst, type GuardConfig, type GuardGeneratedConfig, type GuardInput, type GuardLogger, type GuardShape, type GuardShapeOrFn, type GuardedModel, type InputOpts, type InputSchema, type MissingScopeContextMode, type ModelOpts, type MutationMethod, type NamedShapeMap, type NestedIncludeArgs, type NestedSelectArgs, type NumericFields, type OperationName, type OperationShape, PolicyError, type QueryMethod, type QuerySchema, type ScopeEntry, type ScopeMap, type ShapeConfig, type ShapeDepth, ShapeError, type ShapeInput, type ShapeOrFn$1 as ShapeOrFn, type TypeMap, type TypeMapConst, type TypedCountSelect, type TypedGuardShape, type TypedInclude, type TypedProjection, type TypedShapeProps, type TypedWhere, type UniqueConstraint, type UniqueMap, type ZodChains, type ZodDefaults, createGuard, force, namedShapes, unsupported };
@@ -191,7 +191,13 @@ function createScalarBase(strictDecimal) {
191
191
  z.string().regex(/^-?\d+$/).transform((v) => BigInt(v))
192
192
  ]),
193
193
  Boolean: () => z.boolean(),
194
- DateTime: () => z.union([z.date(), z.string().datetime({ offset: true })]).pipe(z.coerce.date()),
194
+ DateTime: () => z.union([
195
+ z.date(),
196
+ z.string().refine(
197
+ (s) => !isNaN(Date.parse(s)),
198
+ "Invalid date string"
199
+ )
200
+ ]).pipe(z.coerce.date()),
195
201
  Json: () => z.unknown().refine(
196
202
  isJsonSafe,
197
203
  "Value must be JSON-serializable (no undefined, functions, symbols, class instances, NaN, Infinity, or circular references)"
@@ -208,8 +214,8 @@ function wrapWithInputCoercion(fieldType, isList, schema) {
208
214
  break;
209
215
  case "Int":
210
216
  itemCoercion = z.union([
211
- z.number().int(),
212
- z.string().regex(/^-?\d+$/).transform(Number)
217
+ z.number().transform((v) => Math.trunc(v)).pipe(z.number().int()),
218
+ z.string().regex(/^-?\d+(\.\d+)?$/).transform((v) => Math.trunc(Number(v)))
213
219
  ]);
214
220
  break;
215
221
  case "Float":
@@ -787,7 +793,7 @@ function createSchemaBuilder(typeMap, zodChains, enumMap, scalarBase, zodDefault
787
793
  import { z as z7 } from "zod";
788
794
 
789
795
  // src/shared/constants.ts
790
- var SHAPE_CONFIG_KEYS = /* @__PURE__ */ new Set([
796
+ var SHAPE_CONFIG_KEY_LIST = [
791
797
  "where",
792
798
  "include",
793
799
  "select",
@@ -803,13 +809,15 @@ var SHAPE_CONFIG_KEYS = /* @__PURE__ */ new Set([
803
809
  "_min",
804
810
  "_max",
805
811
  "by"
806
- ]);
807
- var GUARD_SHAPE_KEYS = /* @__PURE__ */ new Set([
812
+ ];
813
+ var SHAPE_CONFIG_KEYS = new Set(SHAPE_CONFIG_KEY_LIST);
814
+ var GUARD_SHAPE_KEY_LIST = [
808
815
  "data",
809
816
  "create",
810
817
  "update",
811
- ...SHAPE_CONFIG_KEYS
812
- ]);
818
+ ...SHAPE_CONFIG_KEY_LIST
819
+ ];
820
+ var GUARD_SHAPE_KEYS = new Set(GUARD_SHAPE_KEY_LIST);
813
821
  var COMBINATOR_KEYS = /* @__PURE__ */ new Set(["AND", "OR", "NOT"]);
814
822
  var TO_MANY_RELATION_OPS = /* @__PURE__ */ new Set(["some", "every", "none"]);
815
823
  var TO_ONE_RELATION_OPS = /* @__PURE__ */ new Set(["is", "isNot"]);
@@ -2447,67 +2455,51 @@ function createProjectionBuilder(typeMap, enumMap, deps) {
2447
2455
  return { buildIncludeSchema, buildSelectSchema, buildIncludeCountSchema };
2448
2456
  }
2449
2457
 
2450
- // src/runtime/query-builder.ts
2451
- var METHOD_ALLOWED_ARGS = {
2452
- findMany: /* @__PURE__ */ new Set([
2453
- "where",
2454
- "include",
2455
- "select",
2456
- "orderBy",
2457
- "cursor",
2458
- "take",
2459
- "skip",
2460
- "distinct"
2461
- ]),
2462
- findFirst: /* @__PURE__ */ new Set([
2463
- "where",
2464
- "include",
2465
- "select",
2466
- "orderBy",
2467
- "cursor",
2468
- "take",
2469
- "skip",
2470
- "distinct"
2471
- ]),
2472
- findFirstOrThrow: /* @__PURE__ */ new Set([
2473
- "where",
2474
- "include",
2475
- "select",
2476
- "orderBy",
2477
- "cursor",
2478
- "take",
2479
- "skip",
2480
- "distinct"
2481
- ]),
2482
- findUnique: /* @__PURE__ */ new Set(["where", "include", "select"]),
2483
- findUniqueOrThrow: /* @__PURE__ */ new Set(["where", "include", "select"]),
2484
- count: /* @__PURE__ */ new Set(["where", "select", "cursor", "orderBy", "skip", "take"]),
2485
- aggregate: /* @__PURE__ */ new Set([
2486
- "where",
2487
- "orderBy",
2488
- "cursor",
2489
- "take",
2490
- "skip",
2491
- "_count",
2492
- "_avg",
2493
- "_sum",
2494
- "_min",
2495
- "_max"
2496
- ]),
2497
- groupBy: /* @__PURE__ */ new Set([
2498
- "where",
2499
- "by",
2500
- "having",
2501
- "_count",
2502
- "_avg",
2503
- "_sum",
2504
- "_min",
2505
- "_max",
2506
- "orderBy",
2507
- "take",
2508
- "skip"
2509
- ])
2458
+ // src/shared/operation-shape-keys.ts
2459
+ var OPERATION_SHAPE_KEYS = {
2460
+ findMany: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
2461
+ findFirst: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
2462
+ findFirstOrThrow: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
2463
+ findUnique: ["where", "include", "select"],
2464
+ findUniqueOrThrow: ["where", "include", "select"],
2465
+ findManyPaginated: ["where", "include", "select", "orderBy", "cursor", "take", "skip", "distinct"],
2466
+ count: ["where", "select", "cursor", "orderBy", "skip", "take"],
2467
+ aggregate: ["where", "orderBy", "cursor", "take", "skip", "_count", "_avg", "_sum", "_min", "_max"],
2468
+ groupBy: ["where", "by", "having", "_count", "_avg", "_sum", "_min", "_max", "orderBy", "take", "skip"],
2469
+ create: ["data", "select", "include"],
2470
+ createMany: ["data"],
2471
+ createManyAndReturn: ["data", "select", "include"],
2472
+ update: ["data", "where", "select", "include"],
2473
+ updateMany: ["data", "where"],
2474
+ updateManyAndReturn: ["data", "where", "select", "include"],
2475
+ upsert: ["where", "create", "update", "select", "include"],
2476
+ delete: ["where", "select", "include"],
2477
+ deleteMany: ["where"]
2510
2478
  };
2479
+ var READ_METHOD_ALLOWED_ARGS = {
2480
+ findMany: new Set(OPERATION_SHAPE_KEYS.findMany),
2481
+ findFirst: new Set(OPERATION_SHAPE_KEYS.findFirst),
2482
+ findFirstOrThrow: new Set(OPERATION_SHAPE_KEYS.findFirstOrThrow),
2483
+ findUnique: new Set(OPERATION_SHAPE_KEYS.findUnique),
2484
+ findUniqueOrThrow: new Set(OPERATION_SHAPE_KEYS.findUniqueOrThrow),
2485
+ count: new Set(OPERATION_SHAPE_KEYS.count),
2486
+ aggregate: new Set(OPERATION_SHAPE_KEYS.aggregate),
2487
+ groupBy: new Set(OPERATION_SHAPE_KEYS.groupBy)
2488
+ };
2489
+ var MUTATION_SHAPE_KEYS = {
2490
+ create: new Set(OPERATION_SHAPE_KEYS.create),
2491
+ createMany: new Set(OPERATION_SHAPE_KEYS.createMany),
2492
+ createManyAndReturn: new Set(OPERATION_SHAPE_KEYS.createManyAndReturn),
2493
+ update: new Set(OPERATION_SHAPE_KEYS.update),
2494
+ updateMany: new Set(OPERATION_SHAPE_KEYS.updateMany),
2495
+ updateManyAndReturn: new Set(OPERATION_SHAPE_KEYS.updateManyAndReturn),
2496
+ upsert: new Set(OPERATION_SHAPE_KEYS.upsert),
2497
+ delete: new Set(OPERATION_SHAPE_KEYS.delete),
2498
+ deleteMany: new Set(OPERATION_SHAPE_KEYS.deleteMany)
2499
+ };
2500
+
2501
+ // src/runtime/query-builder.ts
2502
+ var METHOD_ALLOWED_ARGS = READ_METHOD_ALLOWED_ARGS;
2511
2503
  var UNIQUE_WHERE_METHODS = /* @__PURE__ */ new Set([
2512
2504
  "findUnique",
2513
2505
  "findUniqueOrThrow"
@@ -2918,11 +2910,29 @@ function buildAndConditions(existingWhere, conditions) {
2918
2910
  return conditions[0];
2919
2911
  return { AND: conditions };
2920
2912
  }
2921
- function buildScopedUniqueWhere(existingWhere, conditions) {
2922
- if (!existingWhere) {
2913
+ function stripScopeFksFromWhere(where, scopeFks, log, model) {
2914
+ let result = where;
2915
+ for (const fk of scopeFks) {
2916
+ if (fk in result) {
2917
+ if (result === where)
2918
+ result = { ...where };
2919
+ log.warn(
2920
+ `prisma-guard: Scope FK "${fk}" found in where for model "${model}". Stripped in favor of scope context.`
2921
+ );
2922
+ delete result[fk];
2923
+ }
2924
+ }
2925
+ return result;
2926
+ }
2927
+ function buildScopedUniqueWhere(existingWhere, conditions, scopeFks, log, model) {
2928
+ let cleaned = existingWhere;
2929
+ if (cleaned) {
2930
+ cleaned = stripScopeFksFromWhere(cleaned, scopeFks, log, model);
2931
+ }
2932
+ if (!cleaned || Object.keys(cleaned).length === 0) {
2923
2933
  return conditions.length === 1 ? conditions[0] : { AND: conditions };
2924
2934
  }
2925
- const { AND: existingAnd, ...topLevel } = existingWhere;
2935
+ const { AND: existingAnd, ...topLevel } = cleaned;
2926
2936
  const allConditions = [];
2927
2937
  if (existingAnd !== void 0) {
2928
2938
  if (Array.isArray(existingAnd)) {
@@ -3022,6 +3032,13 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3022
3032
  `prisma-guard: Invalid onScopeRelationWrite "${onScopeRelationWrite}". Allowed: ${[...VALID_ON_SCOPE_RELATION_WRITES].join(", ")}`
3023
3033
  );
3024
3034
  }
3035
+ const scopeFkSets = /* @__PURE__ */ new Map();
3036
+ for (const [model, entries] of Object.entries(scopeMap)) {
3037
+ const fks = /* @__PURE__ */ new Set();
3038
+ for (const entry of entries)
3039
+ fks.add(entry.fk);
3040
+ scopeFkSets.set(model, fks);
3041
+ }
3025
3042
  return {
3026
3043
  name: "prisma-guard-scope",
3027
3044
  query: {
@@ -3042,7 +3059,7 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3042
3059
  if (missingRoots.length > 0) {
3043
3060
  if (isMutation || guardConfig.onMissingScopeContext === "error") {
3044
3061
  throw new PolicyError(
3045
- `Missing scope context for model "${model}": roots ${missingRoots.map((r) => `"${r}"`).join(", ")} not provided. All scope roots must be present.`
3062
+ `prisma-guard: Missing scope context for model "${model}": roots ${missingRoots.map((r) => `"${r}"`).join(", ")} not provided. All scope roots must be present.`
3046
3063
  );
3047
3064
  }
3048
3065
  if (guardConfig.onMissingScopeContext === "warn") {
@@ -3058,9 +3075,10 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3058
3075
  const overrides = Object.fromEntries(
3059
3076
  presentScopes.map((s) => [s.fk, ctx[s.root]])
3060
3077
  );
3078
+ const modelFks = scopeFkSets.get(model) ?? /* @__PURE__ */ new Set();
3061
3079
  const nextArgs = { ...args };
3062
3080
  if (operation === "upsert") {
3063
- nextArgs.where = buildScopedUniqueWhere(args.where, conditions);
3081
+ nextArgs.where = buildScopedUniqueWhere(args.where, conditions, modelFks, log, model);
3064
3082
  if (args.create !== void 0 && args.create !== null) {
3065
3083
  if (typeof args.create !== "object" || Array.isArray(args.create)) {
3066
3084
  throw new ShapeError(`upsert expects create to be an object`);
@@ -3098,7 +3116,7 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3098
3116
  if (FIND_UNIQUE_OPS.has(operation)) {
3099
3117
  if (findUniqueMode === "reject") {
3100
3118
  throw new PolicyError(
3101
- `Scoped model "${model}" does not allow ${operation} via scope extension (findUniqueMode is "reject"). Use findFirst with explicit where conditions instead.`
3119
+ `prisma-guard: Scoped model "${model}" does not allow ${operation} via scope extension (findUniqueMode is "reject"). Use findFirst with explicit where conditions instead.`
3102
3120
  );
3103
3121
  }
3104
3122
  return handleFindUnique(
@@ -3168,7 +3186,7 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3168
3186
  return query(nextArgs);
3169
3187
  }
3170
3188
  if (UNIQUE_MUTATION_OPS.has(operation)) {
3171
- nextArgs.where = buildScopedUniqueWhere(args.where, conditions);
3189
+ nextArgs.where = buildScopedUniqueWhere(args.where, conditions, modelFks, log, model);
3172
3190
  if (args.data !== void 0 && args.data !== null) {
3173
3191
  if (typeof args.data !== "object" || Array.isArray(args.data)) {
3174
3192
  throw new ShapeError(`${operation} expects data to be an object`);
@@ -3208,7 +3226,7 @@ function createScopeExtension(scopeMap, contextFn, guardConfig, logger) {
3208
3226
  return query(nextArgs);
3209
3227
  }
3210
3228
  throw new ShapeError(
3211
- `Unknown operation "${operation}" on scoped model "${model}". Update prisma-guard to handle this operation.`
3229
+ `prisma-guard: Unknown operation "${operation}" on scoped model "${model}". Update prisma-guard to handle this operation.`
3212
3230
  );
3213
3231
  }
3214
3232
  }
@@ -3279,7 +3297,7 @@ async function handleFindUnique(args, query, conditions, scopes, operation, log,
3279
3297
  if (!looseEqual(verifyObj[fk], value, log, fk)) {
3280
3298
  if (operation === "findUniqueOrThrow") {
3281
3299
  throw new PolicyError(
3282
- `Record on model "${model}" not accessible in current scope`
3300
+ `prisma-guard: Record on model "${model}" not accessible in current scope`
3283
3301
  );
3284
3302
  }
3285
3303
  return null;
@@ -4351,8 +4369,10 @@ function createModelGuardExtension(config) {
4351
4369
  equalityFields.add(key);
4352
4370
  continue;
4353
4371
  }
4354
- if (isPlainObject(value) && "equals" in value) {
4355
- equalityFields.add(key);
4372
+ if (isPlainObject(value)) {
4373
+ if ("equals" in value) {
4374
+ equalityFields.add(key);
4375
+ }
4356
4376
  continue;
4357
4377
  }
4358
4378
  if (value !== null && value !== void 0) {
@@ -5227,12 +5247,18 @@ function createGuard(config) {
5227
5247
  }
5228
5248
  };
5229
5249
  }
5250
+
5251
+ // src/shared/typed-shape.ts
5252
+ function namedShapes(shapes) {
5253
+ return shapes;
5254
+ }
5230
5255
  export {
5231
5256
  CallerError,
5232
5257
  PolicyError,
5233
5258
  ShapeError,
5234
5259
  createGuard,
5235
5260
  force,
5261
+ namedShapes,
5236
5262
  unsupported
5237
5263
  };
5238
5264
  //# sourceMappingURL=index.js.map