UNPKG

6.72 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.GraphInspector = void 0;
4const unknown_dependencies_exception_1 = require("../errors/exceptions/unknown-dependencies.exception");
5const deterministic_uuid_registry_1 = require("./deterministic-uuid-registry");
6const partial_graph_host_1 = require("./partial-graph.host");
7class GraphInspector {
8 constructor(container) {
9 this.container = container;
10 this.enhancersMetadataCache = new Array();
11 this.graph = container.serializedGraph;
12 }
13 inspectModules(modules = this.container.getModules()) {
14 for (const moduleRef of modules.values()) {
15 this.insertModuleNode(moduleRef);
16 this.insertClassNodes(moduleRef);
17 this.insertModuleToModuleEdges(moduleRef);
18 }
19 this.enhancersMetadataCache.forEach(entry => this.insertEnhancerEdge(entry));
20 deterministic_uuid_registry_1.DeterministicUuidRegistry.clear();
21 }
22 registerPartial(error) {
23 this.graph.status = 'partial';
24 if (error instanceof unknown_dependencies_exception_1.UnknownDependenciesException) {
25 this.graph.metadata = {
26 cause: {
27 type: 'unknown-dependencies',
28 context: error.context,
29 moduleId: error.moduleRef?.id,
30 nodeId: error.metadata?.id,
31 },
32 };
33 }
34 else {
35 this.graph.metadata = {
36 cause: {
37 type: 'unknown',
38 error,
39 },
40 };
41 }
42 partial_graph_host_1.PartialGraphHost.register(this.graph);
43 }
44 inspectInstanceWrapper(source, moduleRef) {
45 const ctorMetadata = source.getCtorMetadata();
46 ctorMetadata?.forEach((target, index) => this.insertClassToClassEdge(source, target, moduleRef, index, 'constructor'));
47 const propertiesMetadata = source.getPropertiesMetadata();
48 propertiesMetadata?.forEach(({ key, wrapper: target }) => this.insertClassToClassEdge(source, target, moduleRef, key, 'property'));
49 }
50 insertEnhancerMetadataCache(entry) {
51 this.enhancersMetadataCache.push(entry);
52 }
53 insertOrphanedEnhancer(entry) {
54 this.graph.insertOrphanedEnhancer({
55 ...entry,
56 ref: entry.ref?.constructor?.name ?? 'Object',
57 });
58 }
59 insertAttachedEnhancer(wrapper) {
60 const existingNode = this.graph.getNodeById(wrapper.id);
61 existingNode.metadata.global = true;
62 this.graph.insertAttachedEnhancer(existingNode.id);
63 }
64 insertEntrypointDefinition(definition, parentId) {
65 definition = {
66 ...definition,
67 id: `${definition.classNodeId}_${definition.methodName}`,
68 };
69 this.graph.insertEntrypoint(definition, parentId);
70 }
71 insertClassNode(moduleRef, wrapper, type) {
72 this.graph.insertNode({
73 id: wrapper.id,
74 label: wrapper.name,
75 parent: moduleRef.id,
76 metadata: {
77 type,
78 internal: wrapper.metatype === moduleRef.metatype,
79 sourceModuleName: moduleRef.name,
80 durable: wrapper.isDependencyTreeDurable(),
81 static: wrapper.isDependencyTreeStatic(),
82 scope: wrapper.scope,
83 transient: wrapper.isTransient,
84 exported: moduleRef.exports.has(wrapper.token),
85 token: wrapper.token,
86 subtype: wrapper.subtype,
87 initTime: wrapper.initTime,
88 },
89 });
90 }
91 insertModuleNode(moduleRef) {
92 const dynamicMetadata = this.container.getDynamicMetadataByToken(moduleRef.token);
93 const node = {
94 id: moduleRef.id,
95 label: moduleRef.name,
96 metadata: {
97 type: 'module',
98 global: moduleRef.isGlobal,
99 dynamic: !!dynamicMetadata,
100 internal: moduleRef.name === 'InternalCoreModule',
101 },
102 };
103 this.graph.insertNode(node);
104 }
105 insertModuleToModuleEdges(moduleRef) {
106 for (const targetModuleRef of moduleRef.imports) {
107 this.graph.insertEdge({
108 source: moduleRef.id,
109 target: targetModuleRef.id,
110 metadata: {
111 type: 'module-to-module',
112 sourceModuleName: moduleRef.name,
113 targetModuleName: targetModuleRef.name,
114 },
115 });
116 }
117 }
118 insertEnhancerEdge(entry) {
119 const moduleRef = this.container.getModuleByKey(entry.moduleToken);
120 const sourceInstanceWrapper = moduleRef.controllers.get(entry.classRef) ??
121 moduleRef.providers.get(entry.classRef);
122 const existingSourceNode = this.graph.getNodeById(sourceInstanceWrapper.id);
123 const enhancers = existingSourceNode.metadata.enhancers ?? [];
124 if (entry.enhancerInstanceWrapper) {
125 this.insertClassToClassEdge(sourceInstanceWrapper, entry.enhancerInstanceWrapper, moduleRef, undefined, 'decorator');
126 enhancers.push({
127 id: entry.enhancerInstanceWrapper.id,
128 methodKey: entry.methodKey,
129 subtype: entry.subtype,
130 });
131 }
132 else {
133 const name = entry.enhancerRef.constructor?.name ??
134 entry.enhancerRef.name;
135 enhancers.push({
136 name,
137 methodKey: entry.methodKey,
138 subtype: entry.subtype,
139 });
140 }
141 existingSourceNode.metadata.enhancers = enhancers;
142 }
143 insertClassToClassEdge(source, target, moduleRef, keyOrIndex, injectionType) {
144 this.graph.insertEdge({
145 source: source.id,
146 target: target.id,
147 metadata: {
148 type: 'class-to-class',
149 sourceModuleName: moduleRef.name,
150 sourceClassName: source.name,
151 targetClassName: target.name,
152 sourceClassToken: source.token,
153 targetClassToken: target.token,
154 targetModuleName: target.host?.name,
155 keyOrIndex,
156 injectionType,
157 },
158 });
159 }
160 insertClassNodes(moduleRef) {
161 moduleRef.providers.forEach(value => this.insertClassNode(moduleRef, value, 'provider'));
162 moduleRef.injectables.forEach(value => this.insertClassNode(moduleRef, value, 'injectable'));
163 moduleRef.controllers.forEach(value => this.insertClassNode(moduleRef, value, 'controller'));
164 }
165}
166exports.GraphInspector = GraphInspector;