UNPKG

@nestjs/core

Version:

Nest - modern, fast, powerful node.js web framework (@core)

163 lines (162 loc) 7.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GraphInspector = void 0; const unknown_dependencies_exception_1 = require("../errors/exceptions/unknown-dependencies.exception"); const deterministic_uuid_registry_1 = require("./deterministic-uuid-registry"); const partial_graph_host_1 = require("./partial-graph.host"); class GraphInspector { constructor(container) { this.container = container; this.enhancersMetadataCache = new Array(); this.graph = container.serializedGraph; } inspectModules(modules = this.container.getModules()) { for (const moduleRef of modules.values()) { this.insertModuleNode(moduleRef); this.insertClassNodes(moduleRef); this.insertModuleToModuleEdges(moduleRef); } this.enhancersMetadataCache.forEach(entry => this.insertEnhancerEdge(entry)); deterministic_uuid_registry_1.DeterministicUuidRegistry.clear(); } registerPartial(error) { var _a, _b; this.graph.status = 'partial'; if (error instanceof unknown_dependencies_exception_1.UnknownDependenciesException) { this.graph.metadata = { cause: { type: 'unknown-dependencies', context: error.context, moduleId: (_a = error.moduleRef) === null || _a === void 0 ? void 0 : _a.id, nodeId: (_b = error.metadata) === null || _b === void 0 ? void 0 : _b.id, }, }; } else { this.graph.metadata = { cause: { type: 'unknown', error, }, }; } partial_graph_host_1.PartialGraphHost.register(this.graph); } inspectInstanceWrapper(source, moduleRef) { const ctorMetadata = source.getCtorMetadata(); ctorMetadata === null || ctorMetadata === void 0 ? void 0 : ctorMetadata.forEach((target, index) => this.insertClassToClassEdge(source, target, moduleRef, index, 'constructor')); const propertiesMetadata = source.getPropertiesMetadata(); propertiesMetadata === null || propertiesMetadata === void 0 ? void 0 : propertiesMetadata.forEach(({ key, wrapper: target }) => this.insertClassToClassEdge(source, target, moduleRef, key, 'property')); } insertEnhancerMetadataCache(entry) { this.enhancersMetadataCache.push(entry); } insertOrphanedEnhancer(entry) { var _a, _b, _c; this.graph.insertOrphanedEnhancer(Object.assign(Object.assign({}, entry), { ref: (_c = (_b = (_a = entry.ref) === null || _a === void 0 ? void 0 : _a.constructor) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : 'Object' })); } insertAttachedEnhancer(wrapper) { const existingNode = this.graph.getNodeById(wrapper.id); existingNode.metadata.global = true; this.graph.insertAttachedEnhancer(existingNode.id); } insertEntrypointDefinition(definition, parentId) { definition = Object.assign(Object.assign({}, definition), { id: `${definition.classNodeId}_${definition.methodName}` }); this.graph.insertEntrypoint(definition, parentId); } insertClassNode(moduleRef, wrapper, type) { this.graph.insertNode({ id: wrapper.id, label: wrapper.name, parent: moduleRef.id, metadata: { type, internal: wrapper.metatype === moduleRef.metatype, sourceModuleName: moduleRef.name, durable: wrapper.isDependencyTreeDurable(), static: wrapper.isDependencyTreeStatic(), scope: wrapper.scope, transient: wrapper.isTransient, exported: moduleRef.exports.has(wrapper.token), token: wrapper.token, subtype: wrapper.subtype, initTime: wrapper.initTime, }, }); } insertModuleNode(moduleRef) { const dynamicMetadata = this.container.getDynamicMetadataByToken(moduleRef.token); const node = { id: moduleRef.id, label: moduleRef.name, metadata: { type: 'module', global: moduleRef.isGlobal, dynamic: !!dynamicMetadata, internal: moduleRef.name === 'InternalCoreModule', }, }; this.graph.insertNode(node); } insertModuleToModuleEdges(moduleRef) { for (const targetModuleRef of moduleRef.imports) { this.graph.insertEdge({ source: moduleRef.id, target: targetModuleRef.id, metadata: { type: 'module-to-module', sourceModuleName: moduleRef.name, targetModuleName: targetModuleRef.name, }, }); } } insertEnhancerEdge(entry) { var _a, _b, _c, _d; const moduleRef = this.container.getModuleByKey(entry.moduleToken); const sourceInstanceWrapper = (_a = moduleRef.controllers.get(entry.classRef)) !== null && _a !== void 0 ? _a : moduleRef.providers.get(entry.classRef); const existingSourceNode = this.graph.getNodeById(sourceInstanceWrapper.id); const enhancers = (_b = existingSourceNode.metadata.enhancers) !== null && _b !== void 0 ? _b : []; if (entry.enhancerInstanceWrapper) { this.insertClassToClassEdge(sourceInstanceWrapper, entry.enhancerInstanceWrapper, moduleRef, undefined, 'decorator'); enhancers.push({ id: entry.enhancerInstanceWrapper.id, methodKey: entry.methodKey, subtype: entry.subtype, }); } else { const name = (_d = (_c = entry.enhancerRef.constructor) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : entry.enhancerRef.name; enhancers.push({ name, methodKey: entry.methodKey, subtype: entry.subtype, }); } existingSourceNode.metadata.enhancers = enhancers; } insertClassToClassEdge(source, target, moduleRef, keyOrIndex, injectionType) { var _a; this.graph.insertEdge({ source: source.id, target: target.id, metadata: { type: 'class-to-class', sourceModuleName: moduleRef.name, sourceClassName: source.name, targetClassName: target.name, sourceClassToken: source.token, targetClassToken: target.token, targetModuleName: (_a = target.host) === null || _a === void 0 ? void 0 : _a.name, keyOrIndex, injectionType, }, }); } insertClassNodes(moduleRef) { moduleRef.providers.forEach(value => this.insertClassNode(moduleRef, value, 'provider')); moduleRef.injectables.forEach(value => this.insertClassNode(moduleRef, value, 'injectable')); moduleRef.controllers.forEach(value => this.insertClassNode(moduleRef, value, 'controller')); } } exports.GraphInspector = GraphInspector;