@@ -46,28 +46,44 @@ export class MetadataStorage {
4646
4747 objectTypes : ObjectClassMetadata [ ] = [ ] ;
4848
49+ objectTypesCache = new Map < Function , ObjectClassMetadata > ( ) ;
50+
4951 inputTypes : ClassMetadata [ ] = [ ] ;
5052
5153 argumentTypes : ClassMetadata [ ] = [ ] ;
5254
5355 interfaceTypes : InterfaceClassMetadata [ ] = [ ] ;
5456
57+ interfaceTypesCache = new Map < Function , InterfaceClassMetadata > ( ) ;
58+
5559 authorizedFields : AuthorizedMetadata [ ] = [ ] ;
5660
61+ authorizedFieldsByTargetAndFieldCache = new Map < any , AuthorizedMetadata > ( ) ;
62+
5763 authorizedResolver : AuthorizedClassMetadata [ ] = [ ] ;
5864
65+ authorizedResolverByTargetCache = new Map < Function , AuthorizedClassMetadata > ( ) ;
66+
5967 enums : EnumMetadata [ ] = [ ] ;
6068
6169 unions : UnionMetadataWithSymbol [ ] = [ ] ;
6270
6371 middlewares : MiddlewareMetadata [ ] = [ ] ;
6472
73+ middlewaresByTargetAndFieldCache = new Map < string , MiddlewareMetadata [ ] > ( ) ;
74+
6575 resolverMiddlewares : ResolverMiddlewareMetadata [ ] = [ ] ;
6676
77+ resolverMiddlewaresByTargetCache = new Map < Function , ResolverMiddlewareMetadata [ ] > ( ) ;
78+
6779 classDirectives : DirectiveClassMetadata [ ] = [ ] ;
6880
81+ classDirectivesByTargetCache = new Map < Function , DirectiveClassMetadata [ ] > ( ) ;
82+
6983 fieldDirectives : DirectiveFieldMetadata [ ] = [ ] ;
7084
85+ fieldDirectivesByTargetAndFieldCache = new Map < any , DirectiveFieldMetadata [ ] > ( ) ;
86+
7187 argumentDirectives : DirectiveArgumentMetadata [ ] = [ ] ;
7288
7389 classExtensions : ExtensionsClassMetadata [ ] = [ ] ;
@@ -76,10 +92,16 @@ export class MetadataStorage {
7692
7793 resolverClasses : ResolverClassMetadata [ ] = [ ] ;
7894
95+ resolverClassesCache = new Map < Function , ResolverClassMetadata > ( ) ;
96+
7997 fields : FieldMetadata [ ] = [ ] ;
8098
99+ fieldsCache = new Map < any , FieldMetadata [ ] > ( ) ;
100+
81101 params : ParamMetadata [ ] = [ ] ;
82102
103+ paramsCache = new Map < string , ParamMetadata [ ] > ( ) ;
104+
83105 collectQueryHandlerMetadata ( definition : ResolverMetadata ) {
84106 this . queries . push ( definition ) ;
85107 }
@@ -173,13 +195,114 @@ export class MetadataStorage {
173195 this . fieldExtensions . push ( definition ) ;
174196 }
175197
198+ initCache ( ) {
199+ if ( this . resolverClasses ?. length ) {
200+ this . resolverClasses . forEach ( resolverClass => {
201+ if ( ! this . resolverClassesCache . has ( resolverClass . target ) ) {
202+ this . resolverClassesCache . set ( resolverClass . target , resolverClass ) ;
203+ }
204+ } ) ;
205+ }
206+
207+ if ( this . params ?. length ) {
208+ this . params . forEach ( param => {
209+ const key = `${ param . target } -${ param . methodName } ` ;
210+ if ( ! this . paramsCache . has ( key ) ) {
211+ this . paramsCache . set ( key , [ ] ) ;
212+ }
213+ this . paramsCache . get ( key ) ?. push ( param ) ;
214+ } ) ;
215+ }
216+
217+ if ( this . middlewares ?. length ) {
218+ this . middlewares . forEach ( middleware => {
219+ const key = `${ middleware . target } -${ middleware . fieldName } ` ;
220+ if ( ! this . middlewaresByTargetAndFieldCache . has ( key ) ) {
221+ this . middlewaresByTargetAndFieldCache . set ( key , [ ] ) ;
222+ }
223+ this . middlewaresByTargetAndFieldCache . get ( key ) ?. push ( middleware ) ;
224+ } ) ;
225+ }
226+
227+ if ( this . resolverMiddlewares ?. length ) {
228+ this . resolverMiddlewares . forEach ( middleware => {
229+ const key = middleware . target ;
230+ if ( ! this . resolverMiddlewaresByTargetCache . has ( key ) ) {
231+ this . resolverMiddlewaresByTargetCache . set ( key , [ ] ) ;
232+ }
233+ this . resolverMiddlewaresByTargetCache . get ( key ) ?. push ( middleware ) ;
234+ } ) ;
235+ }
236+
237+ if ( this . fieldDirectives ?. length ) {
238+ this . fieldDirectives . forEach ( directive => {
239+ const key = `${ directive . target } -${ directive . fieldName } ` ;
240+ if ( ! this . fieldDirectivesByTargetAndFieldCache . has ( key ) ) {
241+ this . fieldDirectivesByTargetAndFieldCache . set ( key , [ ] ) ;
242+ }
243+ this . fieldDirectivesByTargetAndFieldCache . get ( key ) ?. push ( directive ) ;
244+ } ) ;
245+ }
246+
247+ if ( this . classDirectives ?. length ) {
248+ this . classDirectives . forEach ( directive => {
249+ const key = directive . target ;
250+ if ( ! this . classDirectivesByTargetCache . has ( key ) ) {
251+ this . classDirectivesByTargetCache . set ( key , [ ] ) ;
252+ }
253+ this . classDirectivesByTargetCache . get ( key ) ?. push ( directive ) ;
254+ } ) ;
255+ }
256+
257+ if ( this . authorizedFields ?. length ) {
258+ this . authorizedFields . forEach ( field => {
259+ const key = `${ field . target } -${ field . fieldName } ` ;
260+ if ( ! this . authorizedFieldsByTargetAndFieldCache . has ( key ) ) {
261+ this . authorizedFieldsByTargetAndFieldCache . set ( key , field ) ;
262+ }
263+ } ) ;
264+ }
265+
266+ if ( this . authorizedResolver ?. length ) {
267+ this . authorizedResolver . forEach ( resolver => {
268+ const key = resolver . target ;
269+ if ( ! this . authorizedResolverByTargetCache . has ( key ) ) {
270+ this . authorizedResolverByTargetCache . set ( key , resolver ) ;
271+ }
272+ } ) ;
273+ }
274+
275+ if ( this . fields ?. length ) {
276+ this . fields . forEach ( field => {
277+ if ( ! this . fieldsCache . has ( field . target ) ) {
278+ this . fieldsCache . set ( field . target , [ ] ) ;
279+ }
280+ this . fieldsCache . get ( field . target ) ?. push ( field ) ;
281+ } ) ;
282+ }
283+
284+ if ( this . objectTypes ?. length ) {
285+ this . objectTypes . forEach ( objType => {
286+ this . objectTypesCache . set ( objType . target , objType ) ;
287+ } ) ;
288+ }
289+
290+ if ( this . interfaceTypes ?. length ) {
291+ this . interfaceTypes . forEach ( interfaceType => {
292+ this . interfaceTypesCache . set ( interfaceType . target , interfaceType ) ;
293+ } ) ;
294+ }
295+ }
296+
176297 build ( options : SchemaGeneratorOptions ) {
177298 this . classDirectives . reverse ( ) ;
178299 this . fieldDirectives . reverse ( ) ;
179300 this . argumentDirectives . reverse ( ) ;
180301 this . classExtensions . reverse ( ) ;
181302 this . fieldExtensions . reverse ( ) ;
182303
304+ this . initCache ( ) ;
305+
183306 this . buildClassMetadata ( this . objectTypes ) ;
184307 this . buildClassMetadata ( this . inputTypes ) ;
185308 this . buildClassMetadata ( this . argumentTypes ) ;
@@ -223,34 +346,33 @@ export class MetadataStorage {
223346 private buildClassMetadata ( definitions : ClassMetadata [ ] ) {
224347 definitions . forEach ( def => {
225348 if ( ! def . fields ) {
226- const fields = this . fields . filter ( field => field . target === def . target ) ;
349+ const fields = this . fieldsCache . get ( def . target ) || [ ] ;
227350 fields . forEach ( field => {
228351 field . roles = this . findFieldRoles ( field . target , field . name ) ;
229- field . params = this . params . filter (
230- param => param . target === field . target && field . name === param . methodName ,
352+
353+ const paramKey = `${ field . target . name } -${ field . name } ` ;
354+ field . params = this . paramsCache . get ( paramKey ) || [ ] ;
355+
356+ const middlewares1 = this . resolverMiddlewaresByTargetCache . get ( field . target ) || [ ] ;
357+ const middlewaresKey = `${ field . target . name } -${ field . name } ` ;
358+ const middlewares2 = this . middlewaresByTargetAndFieldCache . get ( middlewaresKey ) || [ ] ;
359+
360+ field . middlewares = mapMiddlewareMetadataToArray ( middlewares1 ) . concat (
361+ mapMiddlewareMetadataToArray ( middlewares2 ) ,
231362 ) ;
232- field . middlewares = [
233- ...mapMiddlewareMetadataToArray (
234- this . resolverMiddlewares . filter ( middleware => middleware . target === field . target ) ,
235- ) ,
236- ...mapMiddlewareMetadataToArray (
237- this . middlewares . filter (
238- middleware =>
239- middleware . target === field . target && middleware . fieldName === field . name ,
240- ) ,
241- ) ,
242- ] ;
243- field . directives = this . fieldDirectives
244- . filter ( it => it . target === field . target && it . fieldName === field . name )
245- . map ( it => it . directive ) ;
363+
364+ const directives =
365+ this . fieldDirectivesByTargetAndFieldCache . get ( `${ field . target . name } -${ field . name } ` ) ||
366+ [ ] ;
367+ field . directives = directives . map ( it => it . directive ) ;
368+
246369 field . extensions = this . findExtensions ( field . target , field . name ) ;
247370 } ) ;
248371 def . fields = fields ;
249372 }
250373 if ( ! def . directives ) {
251- def . directives = this . classDirectives
252- . filter ( it => it . target === def . target )
253- . map ( it => it . directive ) ;
374+ const directives = this . classDirectivesByTargetCache . get ( def . target ) || [ ] ;
375+ def . directives = directives . map ( directive => directive . directive ) ;
254376 }
255377 if ( ! def . extensions ) {
256378 def . extensions = this . findExtensions ( def . target ) ;
@@ -260,28 +382,21 @@ export class MetadataStorage {
260382
261383 private buildResolversMetadata ( definitions : BaseResolverMetadata [ ] ) {
262384 definitions . forEach ( def => {
263- const resolverClassMetadata = this . resolverClasses . find (
264- resolver => resolver . target === def . target ,
265- ) ! ;
266- def . resolverClassMetadata = resolverClassMetadata ;
267- def . params = this . params . filter (
268- param => param . target === def . target && def . methodName === param . methodName ,
269- ) ;
385+ def . resolverClassMetadata = this . resolverClassesCache . get ( def . target ) ;
386+ def . params = this . paramsCache . get ( `${ def . target } -${ def . methodName } ` ) || [ ] ;
270387 def . roles = this . findFieldRoles ( def . target , def . methodName ) ;
271- def . middlewares = [
272- ...mapMiddlewareMetadataToArray (
273- this . resolverMiddlewares . filter ( middleware => middleware . target === def . target ) ,
274- ) ,
275- ...mapMiddlewareMetadataToArray (
276- this . middlewares . filter (
277- middleware =>
278- middleware . target === def . target && def . methodName === middleware . fieldName ,
279- ) ,
388+
389+ def . middlewares = mapMiddlewareMetadataToArray (
390+ this . resolverMiddlewaresByTargetCache . get ( def . target ) || [ ] ,
391+ ) . concat (
392+ mapMiddlewareMetadataToArray (
393+ this . middlewaresByTargetAndFieldCache . get ( `${ def . target } -${ def . methodName } ` ) || [ ] ,
280394 ) ,
281- ] ;
282- def . directives = this . fieldDirectives
283- . filter ( it => it . target === def . target && it . fieldName === def . methodName )
284- . map ( it => it . directive ) ;
395+ ) ;
396+
397+ def . directives = (
398+ this . fieldDirectivesByTargetAndFieldCache . get ( `${ def . target } -${ def . methodName } ` ) || [ ]
399+ ) . map ( it => it . directive ) ;
285400 def . extensions = this . findExtensions ( def . target , def . methodName ) ;
286401 } ) ;
287402 }
@@ -293,20 +408,21 @@ export class MetadataStorage {
293408 this . buildResolversMetadata ( definitions ) ;
294409 definitions . forEach ( def => {
295410 def . roles = this . findFieldRoles ( def . target , def . methodName ) ;
296- def . directives = this . fieldDirectives
297- . filter ( it => it . target === def . target && it . fieldName === def . methodName )
298- . map ( it => it . directive ) ;
411+ def . directives = (
412+ this . fieldDirectivesByTargetAndFieldCache . get ( ` ${ def . target } - ${ def . methodName } ` ) || [ ]
413+ ) . map ( it => it . directive ) ;
299414 def . extensions = this . findExtensions ( def . target , def . methodName ) ;
300415 def . getObjectType =
301416 def . kind === "external"
302- ? this . resolverClasses . find ( resolver => resolver . target === def . target ) ! . getObjectType
417+ ? this . resolverClassesCache . get ( def . target ) ! . getObjectType
303418 : ( ) => def . target as ClassType ;
304419 if ( def . kind === "external" ) {
305- const typeClass = this . resolverClasses . find ( resolver => resolver . target === def . target ) !
306- . getObjectType ! ( ) ;
420+ const typeClass = this . resolverClassesCache . get ( def . target ) ! . getObjectType ! ( ) ;
421+ if ( ! typeClass ) {
422+ throw new Error ( `Unable to find type class for external resolver ${ def . target . name } ` ) ;
423+ }
307424 const typeMetadata =
308- this . objectTypes . find ( objTypeDef => objTypeDef . target === typeClass ) ||
309- this . interfaceTypes . find ( interfaceTypeDef => interfaceTypeDef . target === typeClass ) ;
425+ this . objectTypesCache . get ( typeClass ) || this . interfaceTypesCache . get ( typeClass ) ;
310426 if ( ! typeMetadata ) {
311427 throw new Error (
312428 `Unable to find type metadata for input type or object type named '${ typeClass . name } '` ,
@@ -367,8 +483,7 @@ export class MetadataStorage {
367483
368484 // copy and modify metadata of resolver from parent resolver class
369485 while ( superResolver . prototype ) {
370- // eslint-disable-next-line @typescript-eslint/no-loop-func
371- const superResolverMetadata = this . resolverClasses . find ( it => it . target === superResolver ) ;
486+ const superResolverMetadata = this . resolverClassesCache . get ( superResolver ) ;
372487 if ( superResolverMetadata ) {
373488 this . queries = mapSuperResolverHandlers ( this . queries , superResolver , def ) ;
374489 this . mutations = mapSuperResolverHandlers ( this . mutations , superResolver , def ) ;
@@ -386,9 +501,8 @@ export class MetadataStorage {
386501
387502 private findFieldRoles ( target : Function , fieldName : string ) : any [ ] | undefined {
388503 const authorizedField =
389- this . authorizedFields . find (
390- authField => authField . target === target && authField . fieldName === fieldName ,
391- ) ?? this . authorizedResolver . find ( authScope => authScope . target === target ) ;
504+ this . authorizedFieldsByTargetAndFieldCache . get ( `${ target } -${ fieldName } ` ) ||
505+ this . authorizedResolverByTargetCache . get ( target ) ;
392506 if ( ! authorizedField ) {
393507 return undefined ;
394508 }
0 commit comments