type-graphql 2.0.0-rc.2 → 2.0.0-rc.4

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.
Files changed (59) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +19 -13
  3. package/build/cjs/decorators/Arg.js +1 -2
  4. package/build/cjs/decorators/Args.js +1 -2
  5. package/build/cjs/decorators/ArgsType.js +1 -2
  6. package/build/cjs/decorators/Authorized.js +1 -2
  7. package/build/cjs/decorators/Ctx.js +1 -2
  8. package/build/cjs/decorators/Directive.js +1 -2
  9. package/build/cjs/decorators/Extensions.js +1 -2
  10. package/build/cjs/decorators/Field.js +1 -2
  11. package/build/cjs/decorators/FieldResolver.js +1 -2
  12. package/build/cjs/decorators/Info.js +1 -2
  13. package/build/cjs/decorators/InputType.js +1 -2
  14. package/build/cjs/decorators/InterfaceType.js +1 -2
  15. package/build/cjs/decorators/Mutation.js +1 -2
  16. package/build/cjs/decorators/ObjectType.js +1 -2
  17. package/build/cjs/decorators/Query.js +1 -2
  18. package/build/cjs/decorators/Resolver.js +1 -2
  19. package/build/cjs/decorators/Root.js +1 -2
  20. package/build/cjs/decorators/Subscription.js +1 -2
  21. package/build/cjs/decorators/UseMiddleware.js +1 -2
  22. package/build/cjs/decorators/createMethodMiddlewareDecorator.js +1 -2
  23. package/build/cjs/decorators/createParameterDecorator.js +1 -2
  24. package/build/cjs/decorators/createResolverClassMiddlewareDecorator.js +1 -2
  25. package/build/cjs/decorators/enums.js +1 -2
  26. package/build/cjs/decorators/unions.js +1 -2
  27. package/build/cjs/helpers/auth-middleware.js +1 -2
  28. package/build/cjs/helpers/decorators.js +3 -4
  29. package/build/cjs/helpers/filesystem.js +2 -3
  30. package/build/cjs/helpers/findType.js +1 -2
  31. package/build/cjs/helpers/isThrowing.js +1 -2
  32. package/build/cjs/helpers/params.js +1 -2
  33. package/build/cjs/helpers/resolver-metadata.js +1 -2
  34. package/build/cjs/helpers/types.js +11 -6
  35. package/build/cjs/metadata/getMetadataStorage.js +1 -2
  36. package/build/cjs/metadata/metadata-storage.js +192 -28
  37. package/build/cjs/metadata/utils.js +4 -5
  38. package/build/cjs/resolvers/convert-args.js +2 -3
  39. package/build/cjs/resolvers/create.js +4 -5
  40. package/build/cjs/resolvers/helpers.js +3 -4
  41. package/build/cjs/resolvers/validate-arg.js +1 -2
  42. package/build/cjs/schema/definition-node.js +6 -7
  43. package/build/cjs/schema/schema-generator.js +51 -41
  44. package/build/cjs/schema/utils.js +2 -3
  45. package/build/cjs/shim.js +3 -3
  46. package/build/cjs/utils/buildSchema.js +2 -3
  47. package/build/cjs/utils/buildTypeDefsAndResolvers.js +2 -3
  48. package/build/cjs/utils/createResolversMap.js +1 -2
  49. package/build/cjs/utils/emitSchemaDefinitionFile.js +3 -3
  50. package/build/cjs/utils/graphql-version.js +3 -3
  51. package/build/cjs/utils/isPromiseLike.js +1 -2
  52. package/build/esm/helpers/types.js +7 -1
  53. package/build/esm/metadata/metadata-storage.js +192 -28
  54. package/build/esm/schema/schema-generator.js +51 -41
  55. package/build/esm/utils/graphql-version.js +1 -1
  56. package/build/typings/metadata/metadata-storage.d.ts +14 -0
  57. package/build/typings/schema/schema-generator.d.ts +5 -5
  58. package/build/typings/utils/graphql-version.d.ts +1 -1
  59. package/package.json +65 -65
@@ -7,23 +7,34 @@ export class MetadataStorage {
7
7
  this.subscriptions = [];
8
8
  this.fieldResolvers = [];
9
9
  this.objectTypes = [];
10
+ this.objectTypesCache = new Map();
10
11
  this.inputTypes = [];
11
12
  this.argumentTypes = [];
12
13
  this.interfaceTypes = [];
14
+ this.interfaceTypesCache = new Map();
13
15
  this.authorizedFields = [];
16
+ this.authorizedFieldsByTargetAndFieldCache = new Map();
14
17
  this.authorizedResolver = [];
18
+ this.authorizedResolverByTargetCache = new Map();
15
19
  this.enums = [];
16
20
  this.unions = [];
17
21
  this.middlewares = [];
22
+ this.middlewaresByTargetAndFieldCache = new Map();
18
23
  this.resolverMiddlewares = [];
24
+ this.resolverMiddlewaresByTargetCache = new Map();
19
25
  this.classDirectives = [];
26
+ this.classDirectivesByTargetCache = new Map();
20
27
  this.fieldDirectives = [];
28
+ this.fieldDirectivesByTargetAndFieldCache = new Map();
21
29
  this.argumentDirectives = [];
22
30
  this.classExtensions = [];
23
31
  this.fieldExtensions = [];
24
32
  this.resolverClasses = [];
33
+ this.resolverClassesCache = new Map();
25
34
  this.fields = [];
35
+ this.fieldsCache = new Map();
26
36
  this.params = [];
37
+ this.paramsCache = new Map();
27
38
  }
28
39
  collectQueryHandlerMetadata(definition) {
29
40
  this.queries.push(definition);
@@ -96,12 +107,127 @@ export class MetadataStorage {
96
107
  collectExtensionsFieldMetadata(definition) {
97
108
  this.fieldExtensions.push(definition);
98
109
  }
110
+ initCache() {
111
+ this.clearMapCaches();
112
+ if (this.resolverClasses?.length) {
113
+ this.resolverClasses.forEach(resolverClass => {
114
+ if (!this.resolverClassesCache.has(resolverClass.target)) {
115
+ this.resolverClassesCache.set(resolverClass.target, resolverClass);
116
+ }
117
+ });
118
+ }
119
+ if (this.params?.length) {
120
+ this.params.forEach(param => {
121
+ if (!this.paramsCache.has(param.target)) {
122
+ this.paramsCache.set(param.target, new Map());
123
+ }
124
+ if (!this.paramsCache.get(param.target).has(param.methodName)) {
125
+ this.paramsCache.get(param.target).set(param.methodName, []);
126
+ }
127
+ this.paramsCache.get(param.target).get(param.methodName).push(param);
128
+ });
129
+ }
130
+ if (this.middlewares?.length) {
131
+ this.middlewares.forEach(middleware => {
132
+ if (!this.middlewaresByTargetAndFieldCache.has(middleware.target)) {
133
+ this.middlewaresByTargetAndFieldCache.set(middleware.target, new Map());
134
+ }
135
+ if (!this.middlewaresByTargetAndFieldCache.get(middleware.target).has(middleware.fieldName)) {
136
+ this.middlewaresByTargetAndFieldCache
137
+ .get(middleware.target)
138
+ .set(middleware.fieldName, new Set());
139
+ }
140
+ if (!this.middlewaresByTargetAndFieldCache
141
+ .get(middleware.target)
142
+ .get(middleware.fieldName)
143
+ .has(middleware)) {
144
+ this.middlewaresByTargetAndFieldCache
145
+ .get(middleware.target)
146
+ .get(middleware.fieldName)
147
+ .add(middleware);
148
+ }
149
+ });
150
+ }
151
+ if (this.resolverMiddlewares?.length) {
152
+ this.resolverMiddlewares.forEach(middleware => {
153
+ const key = middleware.target;
154
+ if (!this.resolverMiddlewaresByTargetCache.has(key)) {
155
+ this.resolverMiddlewaresByTargetCache.set(key, new Set());
156
+ }
157
+ if (!this.resolverMiddlewaresByTargetCache.get(key).has(middleware)) {
158
+ this.resolverMiddlewaresByTargetCache.get(key).add(middleware);
159
+ }
160
+ });
161
+ }
162
+ if (this.fieldDirectives?.length) {
163
+ this.fieldDirectives.forEach(directive => {
164
+ if (!this.fieldDirectivesByTargetAndFieldCache.has(directive.target)) {
165
+ this.fieldDirectivesByTargetAndFieldCache.set(directive.target, new Map());
166
+ }
167
+ if (!this.fieldDirectivesByTargetAndFieldCache.get(directive.target).has(directive.fieldName)) {
168
+ this.fieldDirectivesByTargetAndFieldCache
169
+ .get(directive.target)
170
+ .set(directive.fieldName, []);
171
+ }
172
+ this.fieldDirectivesByTargetAndFieldCache
173
+ .get(directive.target)
174
+ .get(directive.fieldName)
175
+ .push(directive);
176
+ });
177
+ }
178
+ if (this.classDirectives?.length) {
179
+ this.classDirectives.forEach(directive => {
180
+ const key = directive.target;
181
+ if (!this.classDirectivesByTargetCache.has(key)) {
182
+ this.classDirectivesByTargetCache.set(key, []);
183
+ }
184
+ this.classDirectivesByTargetCache.get(key).push(directive);
185
+ });
186
+ }
187
+ if (this.authorizedFields?.length) {
188
+ this.authorizedFields.forEach(field => {
189
+ if (!this.authorizedFieldsByTargetAndFieldCache.has(field.target)) {
190
+ this.authorizedFieldsByTargetAndFieldCache.set(field.target, new Map());
191
+ }
192
+ if (!this.authorizedFieldsByTargetAndFieldCache.get(field.target).has(field.fieldName)) {
193
+ this.authorizedFieldsByTargetAndFieldCache.get(field.target).set(field.fieldName, field);
194
+ }
195
+ });
196
+ }
197
+ if (this.authorizedResolver?.length) {
198
+ this.authorizedResolver.forEach(resolver => {
199
+ const key = resolver.target;
200
+ if (!this.authorizedResolverByTargetCache.has(key)) {
201
+ this.authorizedResolverByTargetCache.set(key, resolver);
202
+ }
203
+ });
204
+ }
205
+ if (this.fields?.length) {
206
+ this.fields.forEach(field => {
207
+ if (!this.fieldsCache.has(field.target)) {
208
+ this.fieldsCache.set(field.target, []);
209
+ }
210
+ this.fieldsCache.get(field.target).push(field);
211
+ });
212
+ }
213
+ if (this.objectTypes?.length) {
214
+ this.objectTypes.forEach(objType => {
215
+ this.objectTypesCache.set(objType.target, objType);
216
+ });
217
+ }
218
+ if (this.interfaceTypes?.length) {
219
+ this.interfaceTypes.forEach(interfaceType => {
220
+ this.interfaceTypesCache.set(interfaceType.target, interfaceType);
221
+ });
222
+ }
223
+ }
99
224
  build(options) {
100
225
  this.classDirectives.reverse();
101
226
  this.fieldDirectives.reverse();
102
227
  this.argumentDirectives.reverse();
103
228
  this.classExtensions.reverse();
104
229
  this.fieldExtensions.reverse();
230
+ this.initCache();
105
231
  this.buildClassMetadata(this.objectTypes);
106
232
  this.buildClassMetadata(this.inputTypes);
107
233
  this.buildClassMetadata(this.argumentTypes);
@@ -135,29 +261,69 @@ export class MetadataStorage {
135
261
  this.resolverClasses = [];
136
262
  this.fields = [];
137
263
  this.params = [];
264
+ this.clearMapCaches();
265
+ }
266
+ clone() {
267
+ const cloned = new MetadataStorage();
268
+ cloned.queries = [...this.queries];
269
+ cloned.mutations = [...this.mutations];
270
+ cloned.subscriptions = [...this.subscriptions];
271
+ cloned.fieldResolvers = [...this.fieldResolvers];
272
+ cloned.objectTypes = [...this.objectTypes];
273
+ cloned.inputTypes = [...this.inputTypes];
274
+ cloned.argumentTypes = [...this.argumentTypes];
275
+ cloned.interfaceTypes = [...this.interfaceTypes];
276
+ cloned.authorizedFields = [...this.authorizedFields];
277
+ cloned.authorizedResolver = [...this.authorizedResolver];
278
+ cloned.enums = [...this.enums];
279
+ cloned.unions = [...this.unions];
280
+ cloned.middlewares = [...this.middlewares];
281
+ cloned.resolverMiddlewares = [...this.resolverMiddlewares];
282
+ cloned.classDirectives = [...this.classDirectives];
283
+ cloned.fieldDirectives = [...this.fieldDirectives];
284
+ cloned.argumentDirectives = [...this.argumentDirectives];
285
+ cloned.classExtensions = [...this.classExtensions];
286
+ cloned.fieldExtensions = [...this.fieldExtensions];
287
+ cloned.resolverClasses = [...this.resolverClasses];
288
+ cloned.fields = [...this.fields];
289
+ cloned.params = [...this.params];
290
+ return cloned;
291
+ }
292
+ clearMapCaches() {
293
+ this.fieldsCache = new Map();
294
+ this.objectTypesCache = new Map();
295
+ this.interfaceTypesCache = new Map();
296
+ this.middlewaresByTargetAndFieldCache = new Map();
297
+ this.resolverMiddlewaresByTargetCache = new Map();
298
+ this.paramsCache = new Map();
299
+ this.fieldDirectivesByTargetAndFieldCache = new Map();
300
+ this.classDirectivesByTargetCache = new Map();
301
+ this.authorizedFieldsByTargetAndFieldCache = new Map();
302
+ this.authorizedResolverByTargetCache = new Map();
303
+ this.resolverClassesCache = new Map();
138
304
  }
139
305
  buildClassMetadata(definitions) {
140
306
  definitions.forEach(def => {
141
307
  if (!def.fields) {
142
- const fields = this.fields.filter(field => field.target === def.target);
308
+ const fields = this.fieldsCache.get(def.target) || [];
143
309
  fields.forEach(field => {
144
310
  field.roles = this.findFieldRoles(field.target, field.name);
145
- field.params = this.params.filter(param => param.target === field.target && field.name === param.methodName);
311
+ field.params = this.paramsCache.get(field.target)?.get(field.name) || [];
146
312
  field.middlewares = [
147
- ...mapMiddlewareMetadataToArray(this.resolverMiddlewares.filter(middleware => middleware.target === field.target)),
148
- ...mapMiddlewareMetadataToArray(this.middlewares.filter(middleware => middleware.target === field.target && middleware.fieldName === field.name)),
313
+ ...mapMiddlewareMetadataToArray([
314
+ ...(this.resolverMiddlewaresByTargetCache.get(field.target) || []),
315
+ ]),
316
+ ...mapMiddlewareMetadataToArray([
317
+ ...(this.middlewaresByTargetAndFieldCache.get(field.target)?.get(field.name) || []),
318
+ ]),
149
319
  ];
150
- field.directives = this.fieldDirectives
151
- .filter(it => it.target === field.target && it.fieldName === field.name)
152
- .map(it => it.directive);
320
+ field.directives = (this.fieldDirectivesByTargetAndFieldCache.get(field.target)?.get(field.name) || []).map(it => it.directive);
153
321
  field.extensions = this.findExtensions(field.target, field.name);
154
322
  });
155
323
  def.fields = fields;
156
324
  }
157
325
  if (!def.directives) {
158
- def.directives = this.classDirectives
159
- .filter(it => it.target === def.target)
160
- .map(it => it.directive);
326
+ def.directives = (this.classDirectivesByTargetCache.get(def.target) || []).map(it => it.directive);
161
327
  }
162
328
  if (!def.extensions) {
163
329
  def.extensions = this.findExtensions(def.target);
@@ -166,17 +332,18 @@ export class MetadataStorage {
166
332
  }
167
333
  buildResolversMetadata(definitions) {
168
334
  definitions.forEach(def => {
169
- const resolverClassMetadata = this.resolverClasses.find(resolver => resolver.target === def.target);
170
- def.resolverClassMetadata = resolverClassMetadata;
171
- def.params = this.params.filter(param => param.target === def.target && def.methodName === param.methodName);
335
+ def.resolverClassMetadata = this.resolverClassesCache.get(def.target);
336
+ def.params = this.paramsCache.get(def.target)?.get(def.methodName) || [];
172
337
  def.roles = this.findFieldRoles(def.target, def.methodName);
173
338
  def.middlewares = [
174
- ...mapMiddlewareMetadataToArray(this.resolverMiddlewares.filter(middleware => middleware.target === def.target)),
175
- ...mapMiddlewareMetadataToArray(this.middlewares.filter(middleware => middleware.target === def.target && def.methodName === middleware.fieldName)),
339
+ ...mapMiddlewareMetadataToArray([
340
+ ...(this.resolverMiddlewaresByTargetCache.get(def.target) || []),
341
+ ]),
342
+ ...mapMiddlewareMetadataToArray([
343
+ ...(this.middlewaresByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []),
344
+ ]),
176
345
  ];
177
- def.directives = this.fieldDirectives
178
- .filter(it => it.target === def.target && it.fieldName === def.methodName)
179
- .map(it => it.directive);
346
+ def.directives = (this.fieldDirectivesByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []).map(it => it.directive);
180
347
  def.extensions = this.findExtensions(def.target, def.methodName);
181
348
  });
182
349
  }
@@ -184,19 +351,15 @@ export class MetadataStorage {
184
351
  this.buildResolversMetadata(definitions);
185
352
  definitions.forEach(def => {
186
353
  def.roles = this.findFieldRoles(def.target, def.methodName);
187
- def.directives = this.fieldDirectives
188
- .filter(it => it.target === def.target && it.fieldName === def.methodName)
189
- .map(it => it.directive);
354
+ def.directives = (this.fieldDirectivesByTargetAndFieldCache.get(def.target)?.get(def.methodName) || []).map(it => it.directive);
190
355
  def.extensions = this.findExtensions(def.target, def.methodName);
191
356
  def.getObjectType =
192
357
  def.kind === "external"
193
- ? this.resolverClasses.find(resolver => resolver.target === def.target).getObjectType
358
+ ? this.resolverClassesCache.get(def.target).getObjectType
194
359
  : () => def.target;
195
360
  if (def.kind === "external") {
196
- const typeClass = this.resolverClasses.find(resolver => resolver.target === def.target)
197
- .getObjectType();
198
- const typeMetadata = this.objectTypes.find(objTypeDef => objTypeDef.target === typeClass) ||
199
- this.interfaceTypes.find(interfaceTypeDef => interfaceTypeDef.target === typeClass);
361
+ const typeClass = this.resolverClassesCache.get(def.target).getObjectType();
362
+ const typeMetadata = this.objectTypesCache.get(typeClass) || this.interfaceTypesCache.get(typeClass);
200
363
  if (!typeMetadata) {
201
364
  throw new Error(`Unable to find type metadata for input type or object type named '${typeClass.name}'`);
202
365
  }
@@ -247,7 +410,7 @@ export class MetadataStorage {
247
410
  this.resolverClasses.forEach(def => {
248
411
  let superResolver = Object.getPrototypeOf(def.target);
249
412
  while (superResolver.prototype) {
250
- const superResolverMetadata = this.resolverClasses.find(it => it.target === superResolver);
413
+ const superResolverMetadata = this.resolverClassesCache.get(superResolver);
251
414
  if (superResolverMetadata) {
252
415
  this.queries = mapSuperResolverHandlers(this.queries, superResolver, def);
253
416
  this.mutations = mapSuperResolverHandlers(this.mutations, superResolver, def);
@@ -259,7 +422,8 @@ export class MetadataStorage {
259
422
  });
260
423
  }
261
424
  findFieldRoles(target, fieldName) {
262
- const authorizedField = this.authorizedFields.find(authField => authField.target === target && authField.fieldName === fieldName) ?? this.authorizedResolver.find(authScope => authScope.target === target);
425
+ const authorizedField = this.authorizedFieldsByTargetAndFieldCache.get(target)?.get(fieldName) ||
426
+ this.authorizedResolverByTargetCache.get(target);
263
427
  if (!authorizedField) {
264
428
  return undefined;
265
429
  }
@@ -3,7 +3,6 @@ import { GraphQLEnumType, GraphQLInputObjectType, GraphQLInterfaceType, GraphQLO
3
3
  import { CannotDetermineGraphQLTypeError, ConflictingDefaultValuesError, GeneratingSchemaError, InterfaceResolveTypeError, MissingPubSubError, MissingSubscriptionTopicsError, UnionResolveTypeError, } from "../errors/index.js";
4
4
  import { convertTypeIfScalar, getEnumValuesMap, wrapWithTypeOptions } from "../helpers/types.js";
5
5
  import { getMetadataStorage } from "../metadata/getMetadataStorage.js";
6
- import { MetadataStorage } from "../metadata/metadata-storage.js";
7
6
  import { createAdvancedFieldResolver, createBasicFieldResolver, createHandlerResolver, wrapResolverWithAuthChecker, } from "../resolvers/create.js";
8
7
  import { ensureInstalledCorrectGraphQLPackage } from "../utils/graphql-version.js";
9
8
  import { BuildContext } from "./build-context.js";
@@ -11,7 +10,7 @@ import { getFieldDefinitionNode, getInputObjectTypeDefinitionNode, getInputValue
11
10
  import { getFieldMetadataFromInputType, getFieldMetadataFromObjectType } from "./utils.js";
12
11
  export class SchemaGenerator {
13
12
  static generateFromMetadata(options) {
14
- this.metadataStorage = Object.assign(new MetadataStorage(), getMetadataStorage());
13
+ this.metadataStorage = getMetadataStorage().clone();
15
14
  this.metadataStorage.build(options);
16
15
  this.checkForErrors(options);
17
16
  BuildContext.create(options);
@@ -29,6 +28,11 @@ export class SchemaGenerator {
29
28
  });
30
29
  BuildContext.reset();
31
30
  this.usedInterfaceTypes = new Set();
31
+ this.objectTypesInfoMap = new Map();
32
+ this.inputTypesInfoMap = new Map();
33
+ this.interfaceTypesInfoMap = new Map();
34
+ this.enumTypesInfoMap = new Map();
35
+ this.unionTypesInfoMap = new Map();
32
36
  if (!options.skipCheck) {
33
37
  const { errors } = graphqlSync({ schema: finalSchema, source: getIntrospectionQuery() });
34
38
  if (errors) {
@@ -59,15 +63,15 @@ export class SchemaGenerator {
59
63
  : defaultValueFromInitializer;
60
64
  }
61
65
  static buildTypesInfo(resolvers) {
62
- this.unionTypesInfo = this.metadataStorage.unions.map(unionMetadata => {
66
+ this.unionTypesInfoMap = new Map(this.metadataStorage.unions.map(unionMetadata => {
63
67
  const unionObjectTypesInfo = [];
64
68
  const typesThunk = () => {
65
69
  unionObjectTypesInfo.push(...unionMetadata
66
70
  .getClassTypes()
67
- .map(objectTypeCls => this.objectTypesInfo.find(type => type.target === objectTypeCls)));
71
+ .map(objectTypeCls => this.objectTypesInfoMap.get(objectTypeCls)));
68
72
  return unionObjectTypesInfo.map(it => it.type);
69
73
  };
70
- return {
74
+ const unionTypeInfo = {
71
75
  unionSymbol: unionMetadata.symbol,
72
76
  type: new GraphQLUnionType({
73
77
  name: unionMetadata.name,
@@ -87,10 +91,11 @@ export class SchemaGenerator {
87
91
  },
88
92
  }),
89
93
  };
90
- });
91
- this.enumTypesInfo = this.metadataStorage.enums.map(enumMetadata => {
94
+ return [unionMetadata.symbol, unionTypeInfo];
95
+ }));
96
+ this.enumTypesInfoMap = new Map(this.metadataStorage.enums.map(enumMetadata => {
92
97
  const enumMap = getEnumValuesMap(enumMetadata.enumObj);
93
- return {
98
+ const enumTypeInfo = {
94
99
  enumObj: enumMetadata.enumObj,
95
100
  type: new GraphQLEnumType({
96
101
  name: enumMetadata.name,
@@ -106,17 +111,18 @@ export class SchemaGenerator {
106
111
  }, {}),
107
112
  }),
108
113
  };
109
- });
110
- this.objectTypesInfo = this.metadataStorage.objectTypes.map(objectType => {
114
+ return [enumMetadata.enumObj, enumTypeInfo];
115
+ }));
116
+ this.objectTypesInfoMap = new Map(this.metadataStorage.objectTypes.map(objectType => {
111
117
  const objectSuperClass = Object.getPrototypeOf(objectType.target);
112
118
  const hasExtended = objectSuperClass.prototype !== undefined;
113
119
  const getSuperClassType = () => {
114
- const superClassTypeInfo = this.objectTypesInfo.find(type => type.target === objectSuperClass) ??
115
- this.interfaceTypesInfo.find(type => type.target === objectSuperClass);
120
+ const superClassTypeInfo = this.objectTypesInfoMap.get(objectSuperClass) ??
121
+ this.interfaceTypesInfoMap.get(objectSuperClass);
116
122
  return superClassTypeInfo ? superClassTypeInfo.type : undefined;
117
123
  };
118
124
  const interfaceClasses = objectType.interfaceClasses || [];
119
- return {
125
+ const objectTypeInfo = {
120
126
  metadata: objectType,
121
127
  target: objectType.target,
122
128
  type: new GraphQLObjectType({
@@ -126,7 +132,7 @@ export class SchemaGenerator {
126
132
  extensions: objectType.extensions,
127
133
  interfaces: () => {
128
134
  let interfaces = interfaceClasses.map(interfaceClass => {
129
- const interfaceTypeInfo = this.interfaceTypesInfo.find(info => info.target === interfaceClass);
135
+ const interfaceTypeInfo = this.interfaceTypesInfoMap.get(interfaceClass);
130
136
  if (!interfaceTypeInfo) {
131
137
  throw new Error(`Cannot find interface type metadata for class '${interfaceClass.name}' ` +
132
138
  `provided in 'implements' option for '${objectType.target.name}' object type class. ` +
@@ -192,28 +198,30 @@ export class SchemaGenerator {
192
198
  },
193
199
  }),
194
200
  };
195
- });
196
- this.interfaceTypesInfo = this.metadataStorage.interfaceTypes.map(interfaceType => {
201
+ return [objectType.target, objectTypeInfo];
202
+ }));
203
+ this.interfaceTypesInfoMap = new Map(this.metadataStorage.interfaceTypes.map(interfaceType => {
197
204
  const interfaceSuperClass = Object.getPrototypeOf(interfaceType.target);
198
205
  const hasExtended = interfaceSuperClass.prototype !== undefined;
199
206
  const getSuperClassType = () => {
200
- const superClassTypeInfo = this.interfaceTypesInfo.find(type => type.target === interfaceSuperClass);
207
+ const superClassTypeInfo = this.interfaceTypesInfoMap.get(interfaceSuperClass);
201
208
  return superClassTypeInfo ? superClassTypeInfo.type : undefined;
202
209
  };
203
210
  const implementingObjectTypesTargets = this.metadataStorage.objectTypes
204
211
  .filter(objectType => objectType.interfaceClasses &&
205
212
  objectType.interfaceClasses.includes(interfaceType.target))
206
213
  .map(objectType => objectType.target);
207
- const implementingObjectTypesInfo = this.objectTypesInfo.filter(objectTypesInfo => implementingObjectTypesTargets.includes(objectTypesInfo.target));
208
- return {
214
+ const implementingObjectTypesInfo = [...this.objectTypesInfoMap.values()].filter(objectTypesInfo => implementingObjectTypesTargets.includes(objectTypesInfo.target));
215
+ const interfaceTypeInfo = {
209
216
  metadata: interfaceType,
210
217
  target: interfaceType.target,
211
218
  type: new GraphQLInterfaceType({
212
219
  name: interfaceType.name,
213
220
  description: interfaceType.description,
214
221
  astNode: getInterfaceTypeDefinitionNode(interfaceType.name, interfaceType.directives),
222
+ extensions: interfaceType.extensions,
215
223
  interfaces: () => {
216
- let interfaces = (interfaceType.interfaceClasses || []).map(interfaceClass => this.interfaceTypesInfo.find(info => info.target === interfaceClass).type);
224
+ let interfaces = (interfaceType.interfaceClasses || []).map(interfaceClass => this.interfaceTypesInfoMap.get(interfaceClass).type);
217
225
  if (hasExtended) {
218
226
  const superClass = getSuperClassType();
219
227
  if (superClass) {
@@ -273,15 +281,16 @@ export class SchemaGenerator {
273
281
  },
274
282
  }),
275
283
  };
276
- });
277
- this.inputTypesInfo = this.metadataStorage.inputTypes.map(inputType => {
284
+ return [interfaceType.target, interfaceTypeInfo];
285
+ }));
286
+ this.inputTypesInfoMap = new Map(this.metadataStorage.inputTypes.map(inputType => {
278
287
  const objectSuperClass = Object.getPrototypeOf(inputType.target);
279
288
  const getSuperClassType = () => {
280
- const superClassTypeInfo = this.inputTypesInfo.find(type => type.target === objectSuperClass);
289
+ const superClassTypeInfo = this.inputTypesInfoMap.get(objectSuperClass);
281
290
  return superClassTypeInfo ? superClassTypeInfo.type : undefined;
282
291
  };
283
292
  const inputInstance = new inputType.target();
284
- return {
293
+ const inputTypeInfo = {
285
294
  target: inputType.target,
286
295
  type: new GraphQLInputObjectType({
287
296
  name: inputType.name,
@@ -316,7 +325,8 @@ export class SchemaGenerator {
316
325
  astNode: getInputObjectTypeDefinitionNode(inputType.name, inputType.directives),
317
326
  }),
318
327
  };
319
- });
328
+ return [inputType.target, inputTypeInfo];
329
+ }));
320
330
  }
321
331
  static buildRootQueryType(resolvers) {
322
332
  const queriesHandlers = this.filterHandlersByResolvers(this.metadataStorage.queries, resolvers);
@@ -346,8 +356,8 @@ export class SchemaGenerator {
346
356
  });
347
357
  }
348
358
  static buildOtherTypes(orphanedTypes) {
349
- const autoRegisteredObjectTypesInfo = this.objectTypesInfo.filter(typeInfo => typeInfo.metadata.interfaceClasses?.some(interfaceClass => {
350
- const implementedInterfaceInfo = this.interfaceTypesInfo.find(it => it.target === interfaceClass);
359
+ const autoRegisteredObjectTypesInfo = [...this.objectTypesInfoMap.values()].filter(typeInfo => typeInfo.metadata.interfaceClasses?.some(interfaceClass => {
360
+ const implementedInterfaceInfo = this.interfaceTypesInfoMap.get(interfaceClass);
351
361
  if (!implementedInterfaceInfo) {
352
362
  return false;
353
363
  }
@@ -360,9 +370,9 @@ export class SchemaGenerator {
360
370
  return true;
361
371
  }));
362
372
  return [
363
- ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.objectTypesInfo, orphanedTypes),
364
- ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.interfaceTypesInfo, orphanedTypes),
365
- ...this.filterTypesInfoByOrphanedTypesAndExtractType(this.inputTypesInfo, orphanedTypes),
373
+ ...this.filterTypesInfoByOrphanedTypesAndExtractType([...this.objectTypesInfoMap.values()], orphanedTypes),
374
+ ...this.filterTypesInfoByOrphanedTypesAndExtractType([...this.interfaceTypesInfoMap.values()], orphanedTypes),
375
+ ...this.filterTypesInfoByOrphanedTypesAndExtractType([...this.inputTypesInfoMap.values()], orphanedTypes),
366
376
  ...autoRegisteredObjectTypesInfo.map(typeInfo => typeInfo.type),
367
377
  ];
368
378
  }
@@ -498,26 +508,26 @@ export class SchemaGenerator {
498
508
  let gqlType;
499
509
  gqlType = convertTypeIfScalar(type);
500
510
  if (!gqlType) {
501
- const objectType = this.objectTypesInfo.find(it => it.target === type);
511
+ const objectType = this.objectTypesInfoMap.get(type);
502
512
  if (objectType) {
503
513
  gqlType = objectType.type;
504
514
  }
505
515
  }
506
516
  if (!gqlType) {
507
- const interfaceType = this.interfaceTypesInfo.find(it => it.target === type);
517
+ const interfaceType = this.interfaceTypesInfoMap.get(type);
508
518
  if (interfaceType) {
509
519
  this.usedInterfaceTypes.add(interfaceType.target);
510
520
  gqlType = interfaceType.type;
511
521
  }
512
522
  }
513
523
  if (!gqlType) {
514
- const enumType = this.enumTypesInfo.find(it => it.enumObj === type);
524
+ const enumType = this.enumTypesInfoMap.get(type);
515
525
  if (enumType) {
516
526
  gqlType = enumType.type;
517
527
  }
518
528
  }
519
529
  if (!gqlType) {
520
- const unionType = this.unionTypesInfo.find(it => it.unionSymbol === type);
530
+ const unionType = this.unionTypesInfoMap.get(type);
521
531
  if (unionType) {
522
532
  gqlType = unionType.type;
523
533
  }
@@ -532,13 +542,13 @@ export class SchemaGenerator {
532
542
  let gqlType;
533
543
  gqlType = convertTypeIfScalar(type);
534
544
  if (!gqlType) {
535
- const inputType = this.inputTypesInfo.find(it => it.target === type);
545
+ const inputType = this.inputTypesInfoMap.get(type);
536
546
  if (inputType) {
537
547
  gqlType = inputType.type;
538
548
  }
539
549
  }
540
550
  if (!gqlType) {
541
- const enumType = this.enumTypesInfo.find(it => it.enumObj === type);
551
+ const enumType = this.enumTypesInfoMap.get(type);
542
552
  if (enumType) {
543
553
  gqlType = enumType.type;
544
554
  }
@@ -566,9 +576,9 @@ export class SchemaGenerator {
566
576
  return typesInfo.filter(it => orphanedTypes.includes(it.target)).map(it => it.type);
567
577
  }
568
578
  }
569
- SchemaGenerator.objectTypesInfo = [];
570
- SchemaGenerator.inputTypesInfo = [];
571
- SchemaGenerator.interfaceTypesInfo = [];
572
- SchemaGenerator.enumTypesInfo = [];
573
- SchemaGenerator.unionTypesInfo = [];
579
+ SchemaGenerator.objectTypesInfoMap = new Map();
580
+ SchemaGenerator.inputTypesInfoMap = new Map();
581
+ SchemaGenerator.interfaceTypesInfoMap = new Map();
582
+ SchemaGenerator.enumTypesInfoMap = new Map();
583
+ SchemaGenerator.unionTypesInfoMap = new Map();
574
584
  SchemaGenerator.usedInterfaceTypes = new Set();
@@ -1,7 +1,7 @@
1
1
  import * as graphql from "graphql";
2
2
  import semVer from "semver";
3
3
  import { UnmetGraphQLPeerDependencyError } from "../errors/index.js";
4
- export const graphQLPeerDependencyVersion = "^16.8.1";
4
+ export const graphQLPeerDependencyVersion = "^16.12.0";
5
5
  export function ensureInstalledCorrectGraphQLPackage() {
6
6
  if (!semVer.satisfies(graphql.version, graphQLPeerDependencyVersion)) {
7
7
  throw new UnmetGraphQLPeerDependencyError(graphql.version, graphQLPeerDependencyVersion);
@@ -9,23 +9,34 @@ export declare class MetadataStorage {
9
9
  subscriptions: SubscriptionResolverMetadata[];
10
10
  fieldResolvers: FieldResolverMetadata[];
11
11
  objectTypes: ObjectClassMetadata[];
12
+ objectTypesCache: Map<Function, ObjectClassMetadata>;
12
13
  inputTypes: ClassMetadata[];
13
14
  argumentTypes: ClassMetadata[];
14
15
  interfaceTypes: InterfaceClassMetadata[];
16
+ interfaceTypesCache: Map<Function, InterfaceClassMetadata>;
15
17
  authorizedFields: AuthorizedMetadata[];
18
+ authorizedFieldsByTargetAndFieldCache: Map<Function, Map<string, AuthorizedMetadata>>;
16
19
  authorizedResolver: AuthorizedClassMetadata[];
20
+ authorizedResolverByTargetCache: Map<Function, AuthorizedClassMetadata>;
17
21
  enums: EnumMetadata[];
18
22
  unions: UnionMetadataWithSymbol[];
19
23
  middlewares: MiddlewareMetadata[];
24
+ middlewaresByTargetAndFieldCache: Map<Function, Map<string, Set<MiddlewareMetadata>>>;
20
25
  resolverMiddlewares: ResolverMiddlewareMetadata[];
26
+ resolverMiddlewaresByTargetCache: Map<Function, Set<ResolverMiddlewareMetadata>>;
21
27
  classDirectives: DirectiveClassMetadata[];
28
+ classDirectivesByTargetCache: Map<Function, DirectiveClassMetadata[]>;
22
29
  fieldDirectives: DirectiveFieldMetadata[];
30
+ fieldDirectivesByTargetAndFieldCache: Map<Function, Map<string, DirectiveFieldMetadata[]>>;
23
31
  argumentDirectives: DirectiveArgumentMetadata[];
24
32
  classExtensions: ExtensionsClassMetadata[];
25
33
  fieldExtensions: ExtensionsFieldMetadata[];
26
34
  resolverClasses: ResolverClassMetadata[];
35
+ resolverClassesCache: Map<Function, ResolverClassMetadata>;
27
36
  fields: FieldMetadata[];
37
+ fieldsCache: Map<Function, FieldMetadata[]>;
28
38
  params: ParamMetadata[];
39
+ paramsCache: Map<Function, Map<string, ParamMetadata[]>>;
29
40
  collectQueryHandlerMetadata(definition: ResolverMetadata): void;
30
41
  collectMutationHandlerMetadata(definition: ResolverMetadata): void;
31
42
  collectSubscriptionHandlerMetadata(definition: SubscriptionResolverMetadata): void;
@@ -48,8 +59,11 @@ export declare class MetadataStorage {
48
59
  collectDirectiveArgumentMetadata(definition: DirectiveArgumentMetadata): void;
49
60
  collectExtensionsClassMetadata(definition: ExtensionsClassMetadata): void;
50
61
  collectExtensionsFieldMetadata(definition: ExtensionsFieldMetadata): void;
62
+ initCache(): void;
51
63
  build(options: SchemaGeneratorOptions): void;
52
64
  clear(): void;
65
+ clone(): MetadataStorage;
66
+ private clearMapCaches;
53
67
  private buildClassMetadata;
54
68
  private buildResolversMetadata;
55
69
  private buildFieldResolverMetadata;
@@ -19,11 +19,11 @@ export type SchemaGeneratorOptions = {
19
19
  directives?: GraphQLDirective[];
20
20
  } & BuildContextOptions;
21
21
  export declare abstract class SchemaGenerator {
22
- private static objectTypesInfo;
23
- private static inputTypesInfo;
24
- private static interfaceTypesInfo;
25
- private static enumTypesInfo;
26
- private static unionTypesInfo;
22
+ private static objectTypesInfoMap;
23
+ private static inputTypesInfoMap;
24
+ private static interfaceTypesInfoMap;
25
+ private static enumTypesInfoMap;
26
+ private static unionTypesInfoMap;
27
27
  private static usedInterfaceTypes;
28
28
  private static metadataStorage;
29
29
  static generateFromMetadata(options: SchemaGeneratorOptions): GraphQLSchema;
@@ -1,2 +1,2 @@
1
- export declare const graphQLPeerDependencyVersion = "^16.8.1";
1
+ export declare const graphQLPeerDependencyVersion = "^16.12.0";
2
2
  export declare function ensureInstalledCorrectGraphQLPackage(): void;