11import Decimal from 'decimal.js' ;
2+ import stableStringify from 'json-stable-stringify' ;
23import { match , P } from 'ts-pattern' ;
34import { z , ZodSchema } from 'zod' ;
45import type {
@@ -33,104 +34,169 @@ import {
3334 requireModel ,
3435} from '../query-utils' ;
3536
37+ type GetSchemaFunc < Schema extends SchemaDef , Options > = (
38+ model : GetModels < Schema > ,
39+ options : Options
40+ ) => ZodSchema ;
41+
3642export class InputValidator < Schema extends SchemaDef > {
43+ private schemaCache = new Map < string , ZodSchema > ( ) ;
44+
3745 constructor ( private readonly schema : Schema ) { }
3846
3947 validateFindArgs ( model : GetModels < Schema > , unique : boolean , args : unknown ) {
40- return this . validate < FindArgs < Schema , GetModels < Schema > , true > > (
41- this . makeFindSchema ( model , unique , true ) ,
48+ return this . validate <
49+ FindArgs < Schema , GetModels < Schema > , true > ,
50+ Parameters < typeof this . makeFindSchema > [ 1 ]
51+ > (
52+ model ,
4253 'find' ,
54+ { unique, collection : true } ,
55+ ( model , options ) => this . makeFindSchema ( model , options ) ,
4356 args
4457 ) ;
4558 }
4659
4760 validateCreateArgs ( model : GetModels < Schema > , args : unknown ) {
4861 return this . validate < CreateArgs < Schema , GetModels < Schema > > > (
49- this . makeCreateSchema ( model ) ,
62+ model ,
5063 'create' ,
64+ undefined ,
65+ ( model ) => this . makeCreateSchema ( model ) ,
5166 args
5267 ) ;
5368 }
5469
5570 validateCreateManyArgs ( model : GetModels < Schema > , args : unknown ) {
5671 return this . validate <
57- CreateManyArgs < Schema , GetModels < Schema > > | undefined
58- > ( this . makeCreateManySchema ( model ) , 'createMany' , args ) ;
72+ CreateManyArgs < Schema , GetModels < Schema > > ,
73+ undefined
74+ > (
75+ model ,
76+ 'createMany' ,
77+ undefined ,
78+ ( model ) => this . makeCreateManySchema ( model ) ,
79+ args
80+ ) ;
5981 }
6082
6183 validateCreateManyAndReturnArgs ( model : GetModels < Schema > , args : unknown ) {
6284 return this . validate <
6385 CreateManyAndReturnArgs < Schema , GetModels < Schema > > | undefined
6486 > (
65- this . makeCreateManyAndReturnSchema ( model ) ,
87+ model ,
6688 'createManyAndReturn' ,
89+ undefined ,
90+ ( model ) => this . makeCreateManyAndReturnSchema ( model ) ,
6791 args
6892 ) ;
6993 }
7094
7195 validateUpdateArgs ( model : GetModels < Schema > , args : unknown ) {
7296 return this . validate < UpdateArgs < Schema , GetModels < Schema > > > (
73- this . makeUpdateSchema ( model ) ,
97+ model ,
7498 'update' ,
99+ undefined ,
100+ ( model ) => this . makeUpdateSchema ( model ) ,
75101 args
76102 ) ;
77103 }
78104
79105 validateUpdateManyArgs ( model : GetModels < Schema > , args : unknown ) {
80106 return this . validate < UpdateManyArgs < Schema , GetModels < Schema > > > (
81- this . makeUpdateManySchema ( model ) ,
107+ model ,
82108 'updateMany' ,
109+ undefined ,
110+ ( model ) => this . makeUpdateManySchema ( model ) ,
83111 args
84112 ) ;
85113 }
86114
87115 validateUpsertArgs ( model : GetModels < Schema > , args : unknown ) {
88116 return this . validate < UpsertArgs < Schema , GetModels < Schema > > > (
89- this . makeUpsertSchema ( model ) ,
117+ model ,
90118 'upsert' ,
119+ undefined ,
120+ ( model ) => this . makeUpsertSchema ( model ) ,
91121 args
92122 ) ;
93123 }
94124
95125 validateDeleteArgs ( model : GetModels < Schema > , args : unknown ) {
96126 return this . validate < DeleteArgs < Schema , GetModels < Schema > > > (
97- this . makeDeleteSchema ( model ) ,
127+ model ,
98128 'delete' ,
129+ undefined ,
130+ ( model ) => this . makeDeleteSchema ( model ) ,
99131 args
100132 ) ;
101133 }
102134
103135 validateDeleteManyArgs ( model : GetModels < Schema > , args : unknown ) {
104136 return this . validate <
105137 DeleteManyArgs < Schema , GetModels < Schema > > | undefined
106- > ( this . makeDeleteManySchema ( model ) , 'deleteMany' , args ) ;
138+ > (
139+ model ,
140+ 'deleteMany' ,
141+ undefined ,
142+ ( model ) => this . makeDeleteManySchema ( model ) ,
143+ args
144+ ) ;
107145 }
108146
109147 validateCountArgs ( model : GetModels < Schema > , args : unknown ) {
110- return this . validate < CountArgs < Schema , GetModels < Schema > > | undefined > (
111- this . makeCountSchema ( model ) ,
148+ return this . validate <
149+ CountArgs < Schema , GetModels < Schema > > | undefined ,
150+ undefined
151+ > (
152+ model ,
112153 'count' ,
154+ undefined ,
155+ ( model ) => this . makeCountSchema ( model ) ,
113156 args
114157 ) ;
115158 }
116159
117160 validateAggregateArgs ( model : GetModels < Schema > , args : unknown ) {
118- return this . validate < AggregateArgs < Schema , GetModels < Schema > > > (
119- this . makeAggregateSchema ( model ) ,
161+ return this . validate <
162+ AggregateArgs < Schema , GetModels < Schema > > ,
163+ undefined
164+ > (
165+ model ,
120166 'aggregate' ,
167+ undefined ,
168+ ( model ) => this . makeAggregateSchema ( model ) ,
121169 args
122170 ) ;
123171 }
124172
125173 validateGroupByArgs ( model : GetModels < Schema > , args : unknown ) {
126- return this . validate < GroupByArgs < Schema , GetModels < Schema > > > (
127- this . makeGroupBySchema ( model ) ,
174+ return this . validate < GroupByArgs < Schema , GetModels < Schema > > , undefined > (
175+ model ,
128176 'groupBy' ,
177+ undefined ,
178+ ( model ) => this . makeGroupBySchema ( model ) ,
129179 args
130180 ) ;
131181 }
132182
133- private validate < T > ( schema : ZodSchema , operation : string , args : unknown ) {
183+ private validate < T , Options = undefined > (
184+ model : GetModels < Schema > ,
185+ operation : string ,
186+ options : Options ,
187+ getSchema : GetSchemaFunc < Schema , Options > ,
188+ args : unknown
189+ ) {
190+ const cacheKey = stableStringify ( {
191+ model,
192+ operation,
193+ options,
194+ } ) ;
195+ let schema = this . schemaCache . get ( cacheKey ! ) ;
196+ if ( ! schema ) {
197+ schema = getSchema ( model , options ) ;
198+ this . schemaCache . set ( cacheKey ! , schema ) ;
199+ }
134200 const { error } = schema . safeParse ( args ) ;
135201 if ( error ) {
136202 throw new QueryError ( `Invalid ${ operation } args: ${ error . message } ` ) ;
@@ -142,12 +208,11 @@ export class InputValidator<Schema extends SchemaDef> {
142208
143209 private makeFindSchema (
144210 model : string ,
145- unique : boolean ,
146- collection : boolean
211+ options : { unique : boolean ; collection : boolean }
147212 ) {
148213 const fields : Record < string , z . ZodSchema > = { } ;
149- const where = this . makeWhereSchema ( model , unique ) ;
150- if ( unique ) {
214+ const where = this . makeWhereSchema ( model , options . unique ) ;
215+ if ( options . unique ) {
151216 fields [ 'where' ] = where ;
152217 } else {
153218 fields [ 'where' ] = where . optional ( ) ;
@@ -159,7 +224,7 @@ export class InputValidator<Schema extends SchemaDef> {
159224 fields [ 'distinct' ] = this . makeDistinctSchema ( model ) . optional ( ) ;
160225 fields [ 'cursor' ] = this . makeCursorSchema ( model ) . optional ( ) ;
161226
162- if ( collection ) {
227+ if ( options . collection ) {
163228 fields [ 'skip' ] = z . number ( ) . int ( ) . nonnegative ( ) . optional ( ) ;
164229 fields [ 'take' ] = z . number ( ) . int ( ) . optional ( ) ;
165230 fields [ 'orderBy' ] = this . orArray (
@@ -172,7 +237,7 @@ export class InputValidator<Schema extends SchemaDef> {
172237 result = this . refineForSelectIncludeMutuallyExclusive ( result ) ;
173238 result = this . refineForSelectOmitMutuallyExclusive ( result ) ;
174239
175- if ( ! unique ) {
240+ if ( ! options . unique ) {
176241 result = result . optional ( ) ;
177242 }
178243 return result ;
0 commit comments