UNPKG

15.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.TypeMetadataStorage = exports.TypeMetadataStorageHost = void 0;
4const shared_utils_1 = require("@nestjs/common/utils/shared.utils");
5const decorators_1 = require("../../decorators");
6const plugin_constants_1 = require("../../plugin/plugin-constants");
7const collections_1 = require("../collections/");
8const cannot_determine_host_type_error_1 = require("../errors/cannot-determine-host-type.error");
9const undefined_type_error_1 = require("../errors/undefined-type.error");
10const is_throwing_util_1 = require("../utils/is-throwing.util");
11class TypeMetadataStorageHost {
12 constructor() {
13 this.queries = new Array();
14 this.mutations = new Array();
15 this.subscriptions = new Array();
16 this.fieldResolvers = new Array();
17 this.enums = new Array();
18 this.unions = new Array();
19 this.metadataByTargetCollection = new collections_1.MetadataByTargetCollection();
20 }
21 addMutationMetadata(metadata) {
22 this.mutations.push(metadata);
23 }
24 getMutationsMetadata() {
25 return this.mutations;
26 }
27 addQueryMetadata(metadata) {
28 this.queries.push(metadata);
29 }
30 getQueriesMetadata() {
31 return this.queries;
32 }
33 addSubscriptionMetadata(metadata) {
34 this.subscriptions.push(metadata);
35 }
36 getSubscriptionsMetadata() {
37 return this.subscriptions;
38 }
39 addResolverPropertyMetadata(metadata) {
40 this.fieldResolvers.push(metadata);
41 }
42 addArgsMetadata(metadata) {
43 this.metadataByTargetCollection.get(metadata.target).argumentType =
44 metadata;
45 }
46 getArgumentsMetadata() {
47 return this.metadataByTargetCollection.all.argumentType;
48 }
49 getArgumentsMetadataByTarget(target) {
50 return this.metadataByTargetCollection.get(target).argumentType;
51 }
52 addInterfaceMetadata(metadata) {
53 this.metadataByTargetCollection.get(metadata.target).interface = metadata;
54 }
55 getInterfacesMetadata() {
56 return [...this.metadataByTargetCollection.all.interface.values()];
57 }
58 getInterfaceMetadataByTarget(target) {
59 return this.metadataByTargetCollection.get(target).interface;
60 }
61 addInputTypeMetadata(metadata) {
62 this.metadataByTargetCollection.get(metadata.target).inputType = metadata;
63 }
64 getInputTypesMetadata() {
65 return this.metadataByTargetCollection.all.inputType;
66 }
67 getInputTypeMetadataByTarget(target) {
68 return this.metadataByTargetCollection.get(target).inputType;
69 }
70 addObjectTypeMetadata(metadata) {
71 this.metadataByTargetCollection.get(metadata.target).objectType = metadata;
72 }
73 getObjectTypesMetadata() {
74 return this.metadataByTargetCollection.all.objectType;
75 }
76 getObjectTypeMetadataByTarget(target) {
77 return this.metadataByTargetCollection.get(target).objectType;
78 }
79 addEnumMetadata(metadata) {
80 this.enums.push(metadata);
81 }
82 getEnumsMetadata() {
83 return this.enums;
84 }
85 addUnionMetadata(metadata) {
86 this.unions.push(metadata);
87 }
88 getUnionsMetadata() {
89 return this.unions;
90 }
91 addDirectiveMetadata(metadata) {
92 const classMetadata = this.metadataByTargetCollection.get(metadata.target);
93 if (!classMetadata.fieldDirectives.sdls.has(metadata.sdl)) {
94 classMetadata.classDirectives.push(metadata);
95 }
96 }
97 addDirectivePropertyMetadata(metadata) {
98 this.metadataByTargetCollection
99 .get(metadata.target)
100 .fieldDirectives.add(metadata);
101 }
102 addExtensionsMetadata(metadata) {
103 this.metadataByTargetCollection
104 .get(metadata.target)
105 .classExtensions.push(metadata);
106 }
107 addExtensionsPropertyMetadata(metadata) {
108 this.metadataByTargetCollection
109 .get(metadata.target)
110 .fieldExtensions.add(metadata, metadata.fieldName);
111 }
112 addResolverMetadata(metadata) {
113 this.metadataByTargetCollection.get(metadata.target).resolver = metadata;
114 }
115 addClassFieldMetadata(metadata) {
116 const existingMetadata = this.metadataByTargetCollection
117 .get(metadata.target)
118 .fields.getByName(metadata.name);
119 if (existingMetadata) {
120 const options = existingMetadata.options;
121 if ((0, shared_utils_1.isUndefined)(options.nullable) && (0, shared_utils_1.isUndefined)(options.defaultValue)) {
122 options.nullable = metadata.options.nullable;
123 }
124 existingMetadata.description ??= metadata.description;
125 existingMetadata.deprecationReason ??= metadata.deprecationReason;
126 }
127 else {
128 this.metadataByTargetCollection
129 .get(metadata.target)
130 .fields.add(metadata, metadata.name);
131 }
132 }
133 addMethodParamMetadata(metadata) {
134 this.metadataByTargetCollection
135 .get(metadata.target)
136 .params.unshift(metadata, metadata.methodName);
137 }
138 compile(orphanedTypes = []) {
139 this.metadataByTargetCollection.compile();
140 const classMetadata = [
141 ...this.metadataByTargetCollection.all.objectType,
142 ...this.metadataByTargetCollection.all.inputType,
143 ...this.metadataByTargetCollection.all.argumentType,
144 ...this.metadataByTargetCollection.all.interface.values(),
145 ];
146 this.loadClassPluginMetadata(classMetadata);
147 this.compileClassMetadata(classMetadata);
148 this.compileFieldResolverMetadata(this.fieldResolvers);
149 const resolversMetadata = [
150 ...this.queries,
151 ...this.mutations,
152 ...this.subscriptions,
153 ];
154 this.compileResolversMetadata(resolversMetadata);
155 this.compileExtendedResolversMetadata();
156 orphanedTypes.forEach((type) => 'prototype' in type && this.applyPluginMetadata(type.prototype));
157 }
158 loadClassPluginMetadata(metadata) {
159 metadata
160 .filter((item) => item?.target)
161 .forEach((item) => this.applyPluginMetadata(item.target.prototype));
162 }
163 applyPluginMetadata(prototype) {
164 do {
165 if (!prototype.constructor) {
166 return;
167 }
168 if (!prototype.constructor[plugin_constants_1.METADATA_FACTORY_NAME]) {
169 continue;
170 }
171 const metadata = prototype.constructor[plugin_constants_1.METADATA_FACTORY_NAME]();
172 const properties = Object.keys(metadata);
173 properties.forEach((key) => {
174 if (metadata[key].type) {
175 const { type, ...options } = metadata[key];
176 (0, decorators_1.addFieldMetadata)(type, options, prototype, key, undefined, true);
177 }
178 else {
179 (0, decorators_1.addFieldMetadata)(metadata[key], undefined, prototype, key, undefined, true);
180 }
181 });
182 } while ((prototype = Reflect.getPrototypeOf(prototype)) &&
183 prototype !== Object.prototype &&
184 prototype);
185 }
186 compileClassMetadata(metadata, options) {
187 metadata.forEach((item) => {
188 if (!item.properties || options?.overrideFields) {
189 item.properties = this.getClassFieldsByPredicate(item);
190 }
191 if (!item.directives) {
192 item.directives = this.metadataByTargetCollection
193 .get(item.target)
194 .classDirectives.getAll();
195 }
196 if (!item.extensions) {
197 item.extensions = this.metadataByTargetCollection
198 .get(item.target)
199 .classExtensions.reduce((curr, acc) => ({ ...curr, ...acc.value }), {});
200 }
201 });
202 }
203 clear() {
204 Object.assign(this, new TypeMetadataStorageHost());
205 }
206 getClassFieldsByPredicate(item) {
207 const fields = this.metadataByTargetCollection
208 .get(item.target)
209 .fields.getAll();
210 fields.forEach((field) => {
211 field.methodArgs = this.metadataByTargetCollection
212 .get(item.target)
213 .params.getByName(field.name);
214 field.directives = this.metadataByTargetCollection
215 .get(item.target)
216 .fieldDirectives.getByName(field.name);
217 field.extensions = this.metadataByTargetCollection
218 .get(item.target)
219 .fieldExtensions.getByName(field.name)
220 .reduce((curr, acc) => ({ ...curr, ...acc.value }), {});
221 });
222 return fields;
223 }
224 compileResolversMetadata(metadata) {
225 metadata.forEach((item) => {
226 item.classMetadata = this.metadataByTargetCollection.get(item.target).resolver;
227 item.methodArgs = this.metadataByTargetCollection
228 .get(item.target)
229 .params.getByName(item.methodName);
230 item.directives = this.metadataByTargetCollection
231 .get(item.target)
232 .fieldDirectives.getByName(item.methodName);
233 item.extensions = this.metadataByTargetCollection
234 .get(item.target)
235 .fieldExtensions.getByName(item.methodName)
236 .reduce((curr, acc) => ({ ...curr, ...acc.value }), {});
237 });
238 }
239 compileFieldResolverMetadata(metadata) {
240 this.compileResolversMetadata(metadata);
241 metadata.forEach((item) => {
242 item.directives = this.metadataByTargetCollection
243 .get(item.target)
244 .fieldDirectives.getByName(item.methodName);
245 item.extensions = this.metadataByTargetCollection
246 .get(item.target)
247 .fieldExtensions.getByName(item.methodName)
248 .reduce((curr, acc) => ({ ...curr, ...acc.value }), {});
249 item.objectTypeFn =
250 item.kind === 'external'
251 ? this.metadataByTargetCollection.get(item.target).resolver.typeFn
252 : () => item.target;
253 if (item.kind === 'external') {
254 this.compileExternalFieldResolverMetadata(item);
255 }
256 });
257 }
258 compileExternalFieldResolverMetadata(item) {
259 const [target, objectOrInterfaceTypeMetadata, objectOrInterfaceTypeField] = this.findModelFieldMetadata(item);
260 if (!objectOrInterfaceTypeField) {
261 if (!item.typeFn || !item.typeOptions) {
262 throw new undefined_type_error_1.UndefinedTypeError(item.target.name, item.methodName);
263 }
264 const fieldMetadata = {
265 name: item.methodName,
266 schemaName: item.schemaName,
267 deprecationReason: item.deprecationReason,
268 description: item.description,
269 typeFn: item.typeFn,
270 target,
271 options: item.typeOptions,
272 methodArgs: item.methodArgs,
273 directives: item.directives,
274 extensions: item.extensions,
275 complexity: item.complexity,
276 };
277 this.addClassFieldMetadata(fieldMetadata);
278 objectOrInterfaceTypeMetadata.properties.push(fieldMetadata);
279 }
280 else {
281 const isEmpty = (arr) => arr.length === 0;
282 if (isEmpty(objectOrInterfaceTypeField.methodArgs)) {
283 objectOrInterfaceTypeField.methodArgs = item.methodArgs;
284 }
285 if (isEmpty(objectOrInterfaceTypeField.directives)) {
286 objectOrInterfaceTypeField.directives = item.directives;
287 }
288 if (!objectOrInterfaceTypeField.extensions) {
289 objectOrInterfaceTypeField.extensions = item.extensions;
290 }
291 objectOrInterfaceTypeField.complexity =
292 item.complexity === undefined
293 ? objectOrInterfaceTypeField.complexity
294 : item.complexity;
295 }
296 }
297 findModelFieldMetadata(item) {
298 let objectTypeRef = this.metadataByTargetCollection
299 .get(item.target)
300 .resolver.typeFn();
301 const getTypeMetadata = (target) => {
302 const metadata = this.metadataByTargetCollection.get(target);
303 return metadata.objectType || metadata.interface;
304 };
305 let objectOrInterfaceTypeMetadata = getTypeMetadata(objectTypeRef);
306 if (!objectOrInterfaceTypeMetadata) {
307 throw new cannot_determine_host_type_error_1.CannotDetermineHostTypeError(item.schemaName, objectTypeRef?.name);
308 }
309 let objectOrInterfaceTypeField = objectOrInterfaceTypeMetadata.properties.find((fieldDef) => fieldDef.name === item.methodName);
310 for (let _objectTypeRef = objectTypeRef; !objectOrInterfaceTypeField && _objectTypeRef?.prototype; _objectTypeRef = Object.getPrototypeOf(_objectTypeRef)) {
311 const possibleTypeMetadata = getTypeMetadata(_objectTypeRef);
312 objectOrInterfaceTypeField = possibleTypeMetadata?.properties.find((fieldDef) => fieldDef.name === item.methodName);
313 if (objectOrInterfaceTypeField) {
314 objectTypeRef = _objectTypeRef;
315 objectOrInterfaceTypeMetadata = possibleTypeMetadata;
316 break;
317 }
318 }
319 return [
320 objectTypeRef,
321 objectOrInterfaceTypeMetadata,
322 objectOrInterfaceTypeField,
323 ];
324 }
325 compileExtendedResolversMetadata() {
326 this.metadataByTargetCollection.all.resolver.forEach((item) => {
327 let parentClass = Object.getPrototypeOf(item.target);
328 while (parentClass.prototype) {
329 const parentMetadata = this.metadataByTargetCollection.get(item.target).resolver;
330 if (parentMetadata) {
331 this.queries = this.mergeParentResolverHandlers(this.queries, parentClass, item);
332 this.mutations = this.mergeParentResolverHandlers(this.mutations, parentClass, item);
333 this.subscriptions = this.mergeParentResolverHandlers(this.subscriptions, parentClass, item);
334 this.fieldResolvers = this.mergeParentFieldHandlers(this.fieldResolvers, parentClass, item);
335 }
336 parentClass = Object.getPrototypeOf(parentClass);
337 }
338 });
339 }
340 mergeParentResolverHandlers(metadata, parentClass, classMetadata) {
341 return metadata.map((metadata) => {
342 return metadata.target !== parentClass
343 ? metadata
344 : {
345 ...metadata,
346 target: classMetadata.target,
347 classMetadata,
348 };
349 });
350 }
351 mergeParentFieldHandlers(metadata, parentClass, classMetadata) {
352 const parentMetadata = this.mergeParentResolverHandlers(metadata, parentClass, classMetadata);
353 return parentMetadata.map((metadata) => {
354 return metadata.target === parentClass
355 ? metadata
356 : {
357 ...metadata,
358 objectTypeFn: (0, is_throwing_util_1.isThrowing)(metadata.objectTypeFn)
359 ? classMetadata.typeFn
360 : metadata.objectTypeFn,
361 };
362 });
363 }
364}
365exports.TypeMetadataStorageHost = TypeMetadataStorageHost;
366const globalRef = global;
367exports.TypeMetadataStorage = globalRef.GqlTypeMetadataStorage ||
368 (globalRef.GqlTypeMetadataStorage = new TypeMetadataStorageHost());