@@ -21,13 +21,13 @@ import type {
2121 TransactionIsolationLevel ,
2222} from './contract' ;
2323import { AggregateOperationHandler } from './crud/operations/aggregate' ;
24- import type { AllCrudOperation , CoreCrudOperation } from './crud/operations/base' ;
24+ import type { AllCrudOperations , CoreCrudOperations } from './crud/operations/base' ;
2525import { BaseOperationHandler } from './crud/operations/base' ;
2626import { CountOperationHandler } from './crud/operations/count' ;
2727import { CreateOperationHandler } from './crud/operations/create' ;
2828import { DeleteOperationHandler } from './crud/operations/delete' ;
29- import { FindOperationHandler } from './crud/operations/find' ;
3029import { ExistsOperationHandler } from './crud/operations/exists' ;
30+ import { FindOperationHandler } from './crud/operations/find' ;
3131import { GroupByOperationHandler } from './crud/operations/group-by' ;
3232import { UpdateOperationHandler } from './crud/operations/update' ;
3333import { InputValidator } from './crud/validator' ;
@@ -59,6 +59,7 @@ export class ClientImpl {
5959 public readonly $schema : SchemaDef ;
6060 readonly kyselyProps : KyselyProps ;
6161 private auth : AuthType < SchemaDef > | undefined ;
62+ inputValidator : InputValidator < SchemaDef > ;
6263
6364 constructor (
6465 private readonly schema : SchemaDef ,
@@ -114,6 +115,7 @@ export class ClientImpl {
114115 }
115116
116117 this . kysely = new Kysely ( this . kyselyProps ) ;
118+ this . inputValidator = baseClient ?. inputValidator ?? new InputValidator ( this as any ) ;
117119
118120 return createClientProxy ( this ) ;
119121 }
@@ -242,8 +244,7 @@ export class ClientImpl {
242244 }
243245
244246 // Validate inputs using the same validator infrastructure as CRUD operations.
245- const inputValidator = new InputValidator ( this as any ) ;
246- const validatedInput = inputValidator . validateProcedureInput ( name , input ) ;
247+ const validatedInput = this . inputValidator . validateProcedureInput ( name , input ) ;
247248
248249 const handler = procOptions [ name ] as Function ;
249250
@@ -292,19 +293,22 @@ export class ClientImpl {
292293 await new SchemaDbPusher ( this . schema , this . kysely ) . push ( ) ;
293294 }
294295
295- $use ( plugin : RuntimePlugin < SchemaDef > ) {
296- // tsc perf
297- const newPlugins : RuntimePlugin < SchemaDef > [ ] = [ ...( this . $options . plugins ?? [ ] ) , plugin ] ;
296+ $use ( plugin : RuntimePlugin < any , any > ) {
297+ const newPlugins : RuntimePlugin < any , any > [ ] = [ ...( this . $options . plugins ?? [ ] ) , plugin ] ;
298298 const newOptions : ClientOptions < SchemaDef > = {
299299 ...this . options ,
300300 plugins : newPlugins ,
301301 } ;
302- return new ClientImpl ( this . schema , newOptions , this ) ;
302+ const newClient = new ClientImpl ( this . schema , newOptions , this ) ;
303+ // create a new validator to have a fresh schema cache, because plugins may extend the
304+ // query args schemas
305+ newClient . inputValidator = new InputValidator ( newClient as any ) ;
306+ return newClient ;
303307 }
304308
305309 $unuse ( pluginId : string ) {
306310 // tsc perf
307- const newPlugins : RuntimePlugin < SchemaDef > [ ] = [ ] ;
311+ const newPlugins : RuntimePlugin < any , any > [ ] = [ ] ;
308312 for ( const plugin of this . options . plugins ?? [ ] ) {
309313 if ( plugin . id !== pluginId ) {
310314 newPlugins . push ( plugin ) ;
@@ -314,16 +318,24 @@ export class ClientImpl {
314318 ...this . options ,
315319 plugins : newPlugins ,
316320 } ;
317- return new ClientImpl ( this . schema , newOptions , this ) ;
321+ const newClient = new ClientImpl ( this . schema , newOptions , this ) ;
322+ // create a new validator to have a fresh schema cache, because plugins may
323+ // extend the query args schemas
324+ newClient . inputValidator = new InputValidator ( newClient as any ) ;
325+ return newClient ;
318326 }
319327
320328 $unuseAll ( ) {
321329 // tsc perf
322330 const newOptions : ClientOptions < SchemaDef > = {
323331 ...this . options ,
324- plugins : [ ] as RuntimePlugin < SchemaDef > [ ] ,
332+ plugins : [ ] as RuntimePlugin < any , any > [ ] ,
325333 } ;
326- return new ClientImpl ( this . schema , newOptions , this ) ;
334+ const newClient = new ClientImpl ( this . schema , newOptions , this ) ;
335+ // create a new validator to have a fresh schema cache, because plugins may
336+ // extend the query args schemas
337+ newClient . inputValidator = new InputValidator ( newClient as any ) ;
338+ return newClient ;
327339 }
328340
329341 $setAuth ( auth : AuthType < SchemaDef > | undefined ) {
@@ -340,18 +352,18 @@ export class ClientImpl {
340352 }
341353
342354 $setOptions < Options extends ClientOptions < SchemaDef > > ( options : Options ) : ClientContract < SchemaDef , Options > {
343- return new ClientImpl ( this . schema , options as ClientOptions < SchemaDef > , this ) as unknown as ClientContract <
344- SchemaDef ,
345- Options
346- > ;
355+ const newClient = new ClientImpl ( this . schema , options as ClientOptions < SchemaDef > , this ) ;
356+ // create a new validator to have a fresh schema cache, because options may change validation settings
357+ newClient . inputValidator = new InputValidator ( newClient as any ) ;
358+ return newClient as unknown as ClientContract < SchemaDef , Options > ;
347359 }
348360
349361 $setInputValidation ( enable : boolean ) {
350362 const newOptions : ClientOptions < SchemaDef > = {
351363 ...this . options ,
352364 validateInput : enable ,
353365 } ;
354- return new ClientImpl ( this . schema , newOptions , this ) ;
366+ return this . $setOptions ( newOptions ) ;
355367 }
356368
357369 $executeRaw ( query : TemplateStringsArray , ...values : any [ ] ) {
@@ -391,7 +403,6 @@ export class ClientImpl {
391403}
392404
393405function createClientProxy ( client : ClientImpl ) : ClientImpl {
394- const inputValidator = new InputValidator ( client as any ) ;
395406 const resultProcessor = new ResultProcessor ( client . $schema , client . $options ) ;
396407
397408 return new Proxy ( client , {
@@ -403,7 +414,7 @@ function createClientProxy(client: ClientImpl): ClientImpl {
403414 if ( typeof prop === 'string' ) {
404415 const model = Object . keys ( client . $schema . models ) . find ( ( m ) => m . toLowerCase ( ) === prop . toLowerCase ( ) ) ;
405416 if ( model ) {
406- return createModelCrudHandler ( client as any , model , inputValidator , resultProcessor ) ;
417+ return createModelCrudHandler ( client as any , model , client . inputValidator , resultProcessor ) ;
407418 }
408419 }
409420
@@ -419,8 +430,8 @@ function createModelCrudHandler(
419430 resultProcessor : ResultProcessor < any > ,
420431) : ModelOperations < any , any > {
421432 const createPromise = (
422- operation : CoreCrudOperation ,
423- nominalOperation : AllCrudOperation ,
433+ operation : CoreCrudOperations ,
434+ nominalOperation : AllCrudOperations ,
424435 args : unknown ,
425436 handler : BaseOperationHandler < any > ,
426437 postProcess = false ,
@@ -448,16 +459,18 @@ function createModelCrudHandler(
448459 const onQuery = plugin . onQuery ;
449460 if ( onQuery ) {
450461 const _proceed = proceed ;
451- proceed = ( _args : unknown ) =>
452- onQuery ( {
462+ proceed = ( _args : unknown ) => {
463+ const ctx : any = {
453464 client,
454465 model,
455466 operation : nominalOperation ,
456467 // reflect the latest override if provided
457468 args : _args ,
458469 // ensure inner overrides are propagated to the previous proceed
459470 proceed : ( nextArgs : unknown ) => _proceed ( nextArgs ) ,
460- } ) as Promise < unknown > ;
471+ } ;
472+ return ( onQuery as ( ctx : any ) => Promise < unknown > ) ( ctx ) ;
473+ } ;
461474 }
462475 }
463476
@@ -516,6 +529,7 @@ function createModelCrudHandler(
516529 args ,
517530 new FindOperationHandler < any > ( client , model , inputValidator ) ,
518531 true ,
532+ false ,
519533 ) ;
520534 } ,
521535
0 commit comments