nest-graph-inspector 0.2.9 → 0.4.0
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.
- package/README.md +20 -11
- package/package.json +1 -1
- package/src/{drivers/file-output.driver.d.ts → adapters/file-output.adapter.d.ts} +17 -2
- package/src/adapters/file-output.adapter.js +284 -0
- package/src/adapters/file-output.adapter.js.map +1 -0
- package/src/adapters/http-output.adapter.d.ts +25 -0
- package/src/adapters/http-output.adapter.js +94 -0
- package/src/adapters/http-output.adapter.js.map +1 -0
- package/src/adapters/http-serve.adapter.d.ts +58 -0
- package/src/adapters/http-serve.adapter.js +298 -0
- package/src/adapters/http-serve.adapter.js.map +1 -0
- package/src/{drivers/json-output.driver.d.ts → adapters/json-output.adapter.d.ts} +1 -1
- package/src/{drivers/json-output.driver.js → adapters/json-output.adapter.js} +6 -6
- package/src/adapters/json-output.adapter.js.map +1 -0
- package/src/adapters/proxy.adapter.d.ts +21 -0
- package/src/adapters/proxy.adapter.js +153 -0
- package/src/adapters/proxy.adapter.js.map +1 -0
- package/src/adapters/viewer-output.adapter.d.ts +22 -0
- package/src/adapters/viewer-output.adapter.js +82 -0
- package/src/adapters/viewer-output.adapter.js.map +1 -0
- package/src/nest-graph-inspector.module.js +22 -9
- package/src/nest-graph-inspector.module.js.map +1 -1
- package/src/nest-graph-inspector.setup.d.ts +19 -5
- package/src/nest-graph-inspector.setup.js +217 -9
- package/src/nest-graph-inspector.setup.js.map +1 -1
- package/src/nest-graph-inspector.type.d.ts +10 -0
- package/src/ports/proxy.gateway.d.ts +15 -0
- package/src/ports/proxy.gateway.js +3 -0
- package/src/ports/proxy.gateway.js.map +1 -0
- package/src/types/graph-output.type.d.ts +27 -0
- package/src/drivers/file-output.driver.js +0 -187
- package/src/drivers/file-output.driver.js.map +0 -1
- package/src/drivers/http-output.driver.d.ts +0 -19
- package/src/drivers/http-output.driver.js +0 -62
- package/src/drivers/http-output.driver.js.map +0 -1
- package/src/drivers/json-output.driver.js.map +0 -1
- package/src/drivers/viewer-output.driver.d.ts +0 -16
- package/src/drivers/viewer-output.driver.js +0 -42
- package/src/drivers/viewer-output.driver.js.map +0 -1
package/README.md
CHANGED
|
@@ -12,21 +12,30 @@
|
|
|
12
12
|
|
|
13
13
|
Nest Graph Inspector reads your NestJS runtime container and generates a dependency graph of modules, providers, controllers, and their relationships.
|
|
14
14
|
|
|
15
|
-
###
|
|
15
|
+
### Preview
|
|
16
16
|
|
|
17
|
-
[**Try the interactive viewer with AI Chat →**](https://albasyir.github.io/nest-graph-inspector/view/)
|
|
17
|
+
This is a static preview. [**Try the interactive viewer with AI Chat →**](https://albasyir.github.io/nest-graph-inspector/view/)
|
|
18
18
|
|
|
19
19
|
> "Load Example" to see result without installing it
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Why It Matters
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
- **Minimal setup** — import the module and you're done
|
|
25
|
-
- **Interactive web viewer** — zoom, pan, and inspect nodes in the browser
|
|
26
|
-
- **Chat with AI** — there's AI that help you to understand complex graph
|
|
27
|
-
- **JSON output** — structured data for programmatic use or CI integration
|
|
28
|
-
- **Markdown output** — AI-friendly graph representation
|
|
23
|
+
Shipping speed depends on confidence. Teams need runtime visibility to trace impact, find architecture issues early, and ship safer changes.
|
|
29
24
|
|
|
25
|
+
- **Ship Changes Faster** — trace impact in minutes, not meetings, before touching critical providers or modules
|
|
26
|
+
- **Cut Regression Risk** — catch circular and high-coupling patterns before they become release blockers
|
|
27
|
+
- **Make PR Reviews Concrete** — replace assumptions with runtime-backed module and provider-level evidence
|
|
28
|
+
- **Onboard With Real Context** — give new engineers a live map of how the system actually connects and behaves
|
|
29
|
+
- **Find Architecture Issues Early** — use Issue Finder to surface structural problems before they grow into production incidents
|
|
30
|
+
|
|
31
|
+
## Feature List
|
|
32
|
+
|
|
33
|
+
- **Dependency Graph** — visualize modules, providers, controllers, imports, and dependency edges from the running app
|
|
34
|
+
- **Circular Detection** — surface circular relationships early so teams can resolve risky loops before release
|
|
35
|
+
- **Relation Focus** — coming soon: focus provider/module pairs to see how they relate and where dependencies connect
|
|
36
|
+
- **Context-Aware AI Assistant** — ask graph and trace questions in plain language with context-aware answers, always free in the viewer
|
|
37
|
+
- **Process Sequence** — coming soon: generate sequence diagrams from an entry point to completion flow
|
|
38
|
+
- **Direct Run** — coming soon: execute runtime-resolved services and functions directly from graph context
|
|
30
39
|
|
|
31
40
|
## Quick Start
|
|
32
41
|
|
|
@@ -38,10 +47,10 @@ npm install nest-graph-inspector
|
|
|
38
47
|
|
|
39
48
|
```ts
|
|
40
49
|
import { Module } from '@nestjs/common';
|
|
41
|
-
import {
|
|
50
|
+
import { NestGraphInspectorModule } from 'nest-graph-inspector';
|
|
42
51
|
|
|
43
52
|
@Module({
|
|
44
|
-
imports: [
|
|
53
|
+
imports: [NestGraphInspectorModule],
|
|
45
54
|
})
|
|
46
55
|
export class RootModule {}
|
|
47
56
|
```
|
package/package.json
CHANGED
|
@@ -4,7 +4,9 @@ import type { GraphOutput } from '../types/graph-output.type';
|
|
|
4
4
|
type FileOutputConfig = Extract<NestGraphInspectorOutput, {
|
|
5
5
|
type: 'markdown';
|
|
6
6
|
}>;
|
|
7
|
-
export declare class
|
|
7
|
+
export declare class FileOutputAdapter implements OutputAdapter<FileOutputConfig> {
|
|
8
|
+
private readonly markdownTitle;
|
|
9
|
+
private readonly arrowDirectionDescription;
|
|
8
10
|
private readonly nestCoreModuleName;
|
|
9
11
|
execute(graphOutput: GraphOutput, config: FileOutputConfig): Promise<{
|
|
10
12
|
message: string;
|
|
@@ -16,12 +18,25 @@ export declare class FileOutputDriver implements OutputAdapter<FileOutputConfig>
|
|
|
16
18
|
private appendMermaidProviderRelations;
|
|
17
19
|
private appendMermaidControllerRelations;
|
|
18
20
|
private appendDependencyRelations;
|
|
19
|
-
private appendLegend;
|
|
20
21
|
private appendModuleSections;
|
|
22
|
+
private findProviderCircularWarnings;
|
|
23
|
+
private findControllerCircularWarnings;
|
|
24
|
+
private findModuleCircularWarnings;
|
|
25
|
+
private findUnusedImportWarnings;
|
|
26
|
+
private isModuleImportUsed;
|
|
21
27
|
private appendStringSection;
|
|
22
28
|
private appendProviderSection;
|
|
23
29
|
private appendControllerSection;
|
|
24
30
|
private appendNamedDependencyItem;
|
|
31
|
+
private appendWarningItems;
|
|
32
|
+
private appendModuleWarningBlock;
|
|
33
|
+
private addImportWarning;
|
|
34
|
+
private providerKey;
|
|
35
|
+
private providerDisplayName;
|
|
36
|
+
private providerDisplayNameFromKey;
|
|
37
|
+
private getOrCreateMap;
|
|
38
|
+
private getOrCreateArray;
|
|
39
|
+
private findCircularWarningsFromCycles;
|
|
25
40
|
private toMermaidNodeId;
|
|
26
41
|
private escapeMermaidLabel;
|
|
27
42
|
private moduleGroupId;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.FileOutputAdapter = void 0;
|
|
10
|
+
const promises_1 = require("node:fs/promises");
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const node_path_1 = require("node:path");
|
|
13
|
+
let FileOutputAdapter = class FileOutputAdapter {
|
|
14
|
+
markdownTitle = 'NestJS Dependency Graph';
|
|
15
|
+
arrowDirectionDescription = 'Arrow direction: `A --> B` means `A` depends on `B`.';
|
|
16
|
+
nestCoreModuleName = 'NestJSCoreModule';
|
|
17
|
+
async execute(graphOutput, config) {
|
|
18
|
+
const filePath = (0, node_path_1.join)(process.cwd(), config.path);
|
|
19
|
+
const markdownText = this.buildMarkdownText(graphOutput);
|
|
20
|
+
await (0, promises_1.mkdir)((0, node_path_1.dirname)(filePath), { recursive: true });
|
|
21
|
+
await (0, promises_1.writeFile)(filePath, markdownText, 'utf8');
|
|
22
|
+
return {
|
|
23
|
+
message: `Graph inspector markdown output was written to ${filePath}`,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
buildMarkdownText(graphOutput) {
|
|
27
|
+
const lines = [];
|
|
28
|
+
const moduleEntries = Object.entries(graphOutput.modules);
|
|
29
|
+
lines.push(`# ${this.markdownTitle}`);
|
|
30
|
+
lines.push('');
|
|
31
|
+
lines.push('```mermaid');
|
|
32
|
+
lines.push('graph TD');
|
|
33
|
+
lines.push('');
|
|
34
|
+
this.appendMermaidModuleGroups(lines, moduleEntries);
|
|
35
|
+
this.appendMermaidModuleRelations(lines, moduleEntries, graphOutput);
|
|
36
|
+
lines.push('```');
|
|
37
|
+
lines.push('');
|
|
38
|
+
lines.push(`> ${this.arrowDirectionDescription}`);
|
|
39
|
+
lines.push('');
|
|
40
|
+
this.appendModuleSections(lines, moduleEntries, graphOutput);
|
|
41
|
+
return lines.join('\n');
|
|
42
|
+
}
|
|
43
|
+
appendMermaidModuleGroups(lines, moduleEntries) {
|
|
44
|
+
for (const [moduleName, moduleData] of moduleEntries) {
|
|
45
|
+
lines.push(` subgraph ${this.moduleGroupId(moduleName)}["${this.escapeMermaidLabel(moduleName)}"]`);
|
|
46
|
+
for (const provider of moduleData.providers) {
|
|
47
|
+
lines.push(` ${this.providerNodeId(moduleName, provider.name)}["${this.escapeMermaidLabel(provider.name)}"]`);
|
|
48
|
+
}
|
|
49
|
+
for (const controller of moduleData.controllers) {
|
|
50
|
+
lines.push(` ${this.controllerNodeId(moduleName, controller.name)}["${this.escapeMermaidLabel(controller.name)}"]`);
|
|
51
|
+
}
|
|
52
|
+
lines.push(' end');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
appendMermaidModuleRelations(lines, moduleEntries, graphOutput) {
|
|
56
|
+
for (const [moduleName, moduleData] of moduleEntries) {
|
|
57
|
+
this.appendMermaidImportRelations(lines, moduleName, moduleData, graphOutput);
|
|
58
|
+
this.appendMermaidProviderRelations(lines, moduleName, moduleData, graphOutput);
|
|
59
|
+
this.appendMermaidControllerRelations(lines, moduleName, moduleData, graphOutput);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
appendMermaidImportRelations(lines, moduleName, moduleData, graphOutput) {
|
|
63
|
+
const importingModuleGroupId = this.moduleGroupId(moduleName);
|
|
64
|
+
if (moduleName === this.nestCoreModuleName) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (const importedModuleName of moduleData.imports) {
|
|
68
|
+
if (!graphOutput.modules[importedModuleName]) {
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
const importedModuleGroupId = this.moduleGroupId(importedModuleName);
|
|
72
|
+
lines.push(` ${importingModuleGroupId} --> ${importedModuleGroupId}`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
appendMermaidProviderRelations(lines, moduleName, moduleData, graphOutput) {
|
|
76
|
+
for (const provider of moduleData.providers) {
|
|
77
|
+
const providerNodeId = this.providerNodeId(moduleName, provider.name);
|
|
78
|
+
this.appendDependencyRelations(lines, providerNodeId, moduleName, provider.name, provider.dependencies, graphOutput);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
appendMermaidControllerRelations(lines, moduleName, moduleData, graphOutput) {
|
|
82
|
+
for (const controller of moduleData.controllers) {
|
|
83
|
+
const controllerNodeId = this.controllerNodeId(moduleName, controller.name);
|
|
84
|
+
this.appendDependencyRelations(lines, controllerNodeId, moduleName, controller.name, controller.dependencies, graphOutput);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
appendDependencyRelations(lines, ownerNodeId, moduleName, ownerName, dependencies, graphOutput) {
|
|
88
|
+
for (const dependency of dependencies) {
|
|
89
|
+
const dependencyModule = graphOutput.modules[dependency.providedBy.name];
|
|
90
|
+
const hasDependencyProvider = dependencyModule?.providers.some((provider) => provider.name === dependency.token);
|
|
91
|
+
if (hasDependencyProvider) {
|
|
92
|
+
const dependencyProviderNodeId = this.providerNodeId(dependency.providedBy.name, dependency.token);
|
|
93
|
+
lines.push(` ${ownerNodeId} --> ${dependencyProviderNodeId}`);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const dependencyLabel = `${dependency.providedBy.name}:${dependency.token}`;
|
|
97
|
+
const dependencyNodeId = this.dependencyNodeId(moduleName, ownerName, dependencyLabel);
|
|
98
|
+
lines.push(` ${dependencyNodeId}["${this.escapeMermaidLabel(dependencyLabel)}"]`);
|
|
99
|
+
lines.push(` ${ownerNodeId} --> ${dependencyNodeId}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
appendModuleSections(lines, moduleEntries, graphOutput) {
|
|
103
|
+
const providerCircularWarnings = this.findProviderCircularWarnings(graphOutput);
|
|
104
|
+
const controllerCircularWarnings = this.findControllerCircularWarnings(graphOutput);
|
|
105
|
+
const moduleCircularWarnings = this.findModuleCircularWarnings(graphOutput);
|
|
106
|
+
const unusedImportWarnings = this.findUnusedImportWarnings(moduleEntries, graphOutput);
|
|
107
|
+
for (const [moduleName, moduleData] of moduleEntries) {
|
|
108
|
+
lines.push(`## ${moduleName}`);
|
|
109
|
+
lines.push('');
|
|
110
|
+
const moduleWarnings = moduleCircularWarnings.get(moduleName);
|
|
111
|
+
this.appendModuleWarningBlock(lines, moduleWarnings);
|
|
112
|
+
if (moduleWarnings && moduleWarnings.length > 0) {
|
|
113
|
+
lines.push('');
|
|
114
|
+
}
|
|
115
|
+
this.appendStringSection(lines, 'Imports', moduleData.imports, unusedImportWarnings.get(moduleName));
|
|
116
|
+
this.appendStringSection(lines, 'Exports', moduleData.exports);
|
|
117
|
+
this.appendProviderSection(lines, 'Providers', moduleName, moduleData.providers, providerCircularWarnings);
|
|
118
|
+
this.appendControllerSection(lines, 'Controllers', moduleName, moduleData.controllers, controllerCircularWarnings);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
findProviderCircularWarnings(graphOutput) {
|
|
122
|
+
return this.findCircularWarningsFromCycles(graphOutput.cycles?.providers, (providerKey) => this.providerDisplayNameFromKey(providerKey));
|
|
123
|
+
}
|
|
124
|
+
findControllerCircularWarnings(graphOutput) {
|
|
125
|
+
return this.findCircularWarningsFromCycles(graphOutput.cycles?.controllers, (controllerKey) => this.providerDisplayNameFromKey(controllerKey));
|
|
126
|
+
}
|
|
127
|
+
findModuleCircularWarnings(graphOutput) {
|
|
128
|
+
return this.findCircularWarningsFromCycles(graphOutput.cycles?.modules, (moduleName) => moduleName);
|
|
129
|
+
}
|
|
130
|
+
findUnusedImportWarnings(moduleEntries, graphOutput) {
|
|
131
|
+
const unusedImportWarnings = new Map();
|
|
132
|
+
for (const [moduleName, moduleData] of moduleEntries) {
|
|
133
|
+
if (moduleName === graphOutput.root ||
|
|
134
|
+
moduleName === this.nestCoreModuleName) {
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
const dependencies = [
|
|
138
|
+
...moduleData.providers.flatMap((provider) => provider.dependencies),
|
|
139
|
+
...moduleData.controllers.flatMap((controller) => controller.dependencies),
|
|
140
|
+
];
|
|
141
|
+
for (const importedModuleName of moduleData.imports) {
|
|
142
|
+
const importedModule = graphOutput.modules[importedModuleName];
|
|
143
|
+
if (!importedModule) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
if (this.isModuleImportUsed(moduleData, importedModuleName, importedModule, dependencies)) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
this.addImportWarning(unusedImportWarnings, moduleName, importedModuleName, 'unused import module');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return unusedImportWarnings;
|
|
153
|
+
}
|
|
154
|
+
isModuleImportUsed(moduleData, importedModuleName, importedModule, dependencies) {
|
|
155
|
+
if (moduleData.exports.includes(importedModuleName)) {
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
return dependencies.some((dependency) => {
|
|
159
|
+
if (dependency.providedBy.name === importedModuleName) {
|
|
160
|
+
return true;
|
|
161
|
+
}
|
|
162
|
+
if (importedModule.exports.includes(dependency.providedBy.name)) {
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
return importedModule.exports.includes(dependency.token);
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
appendStringSection(lines, title, values, warnings = new Map()) {
|
|
169
|
+
if (values.length === 0) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
lines.push(`### ${title}`);
|
|
173
|
+
for (const value of values) {
|
|
174
|
+
lines.push(`- ${value}`);
|
|
175
|
+
this.appendWarningItems(lines, warnings.get(value), ' ');
|
|
176
|
+
}
|
|
177
|
+
lines.push('');
|
|
178
|
+
}
|
|
179
|
+
appendProviderSection(lines, title, moduleName, providers, circularWarnings) {
|
|
180
|
+
if (providers.length === 0) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
lines.push(`### ${title}`);
|
|
184
|
+
for (const provider of providers) {
|
|
185
|
+
this.appendNamedDependencyItem(lines, provider.name, provider.dependencies, circularWarnings.get(this.providerKey(moduleName, provider.name)));
|
|
186
|
+
}
|
|
187
|
+
lines.push('');
|
|
188
|
+
}
|
|
189
|
+
appendControllerSection(lines, title, moduleName, controllers, circularWarnings) {
|
|
190
|
+
if (controllers.length === 0) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
lines.push(`### ${title}`);
|
|
194
|
+
for (const controller of controllers) {
|
|
195
|
+
this.appendNamedDependencyItem(lines, controller.name, controller.dependencies, circularWarnings.get(this.providerKey(moduleName, controller.name)));
|
|
196
|
+
}
|
|
197
|
+
lines.push('');
|
|
198
|
+
}
|
|
199
|
+
appendNamedDependencyItem(lines, name, dependencies, warnings = []) {
|
|
200
|
+
lines.push(`- ${name}`);
|
|
201
|
+
this.appendWarningItems(lines, warnings, ' ');
|
|
202
|
+
for (const dependency of dependencies) {
|
|
203
|
+
lines.push(` - depends on ${dependency.token} from ${dependency.providedBy.name}`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
appendWarningItems(lines, warnings = [], indent = '') {
|
|
207
|
+
for (const warning of warnings) {
|
|
208
|
+
lines.push(`${indent}- Warning: ${warning}`);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
appendModuleWarningBlock(lines, warnings = []) {
|
|
212
|
+
if (warnings.length === 0) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
lines.push('> warnings');
|
|
216
|
+
for (const warning of warnings) {
|
|
217
|
+
lines.push(`> - ${warning}`);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
addImportWarning(warnings, moduleName, importedModuleName, warning) {
|
|
221
|
+
const moduleWarnings = this.getOrCreateMap(warnings, moduleName);
|
|
222
|
+
const importWarnings = this.getOrCreateArray(moduleWarnings, importedModuleName);
|
|
223
|
+
importWarnings.push(warning);
|
|
224
|
+
}
|
|
225
|
+
providerKey(moduleName, providerName) {
|
|
226
|
+
return `${moduleName}:${providerName}`;
|
|
227
|
+
}
|
|
228
|
+
providerDisplayName(moduleName, providerName) {
|
|
229
|
+
return `${providerName} from ${moduleName}`;
|
|
230
|
+
}
|
|
231
|
+
providerDisplayNameFromKey(providerKey) {
|
|
232
|
+
const separatorIndex = providerKey.indexOf(':');
|
|
233
|
+
return this.providerDisplayName(providerKey.slice(0, separatorIndex), providerKey.slice(separatorIndex + 1));
|
|
234
|
+
}
|
|
235
|
+
getOrCreateMap(map, key) {
|
|
236
|
+
const existingValue = map.get(key);
|
|
237
|
+
if (existingValue) {
|
|
238
|
+
return existingValue;
|
|
239
|
+
}
|
|
240
|
+
const value = new Map();
|
|
241
|
+
map.set(key, value);
|
|
242
|
+
return value;
|
|
243
|
+
}
|
|
244
|
+
getOrCreateArray(map, key) {
|
|
245
|
+
const existingValue = map.get(key);
|
|
246
|
+
if (existingValue) {
|
|
247
|
+
return existingValue;
|
|
248
|
+
}
|
|
249
|
+
const value = [];
|
|
250
|
+
map.set(key, value);
|
|
251
|
+
return value;
|
|
252
|
+
}
|
|
253
|
+
findCircularWarningsFromCycles(cycles = [], displayName) {
|
|
254
|
+
const circularWarnings = new Map();
|
|
255
|
+
for (const cycle of cycles) {
|
|
256
|
+
const warnings = this.getOrCreateArray(circularWarnings, cycle.from);
|
|
257
|
+
warnings.push(`${cycle.type} circular dependency with ${displayName(cycle.to)}`);
|
|
258
|
+
}
|
|
259
|
+
return circularWarnings;
|
|
260
|
+
}
|
|
261
|
+
toMermaidNodeId(value) {
|
|
262
|
+
return value.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
263
|
+
}
|
|
264
|
+
escapeMermaidLabel(value) {
|
|
265
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
266
|
+
}
|
|
267
|
+
moduleGroupId(moduleName) {
|
|
268
|
+
return this.toMermaidNodeId(`module-group:${moduleName}`);
|
|
269
|
+
}
|
|
270
|
+
providerNodeId(moduleName, providerName) {
|
|
271
|
+
return this.toMermaidNodeId(`provider:${moduleName}:${providerName}`);
|
|
272
|
+
}
|
|
273
|
+
controllerNodeId(moduleName, controllerName) {
|
|
274
|
+
return this.toMermaidNodeId(`controller:${moduleName}:${controllerName}`);
|
|
275
|
+
}
|
|
276
|
+
dependencyNodeId(moduleName, ownerName, dependencyName) {
|
|
277
|
+
return this.toMermaidNodeId(`dependency:${moduleName}:${ownerName}:${dependencyName}`);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
280
|
+
exports.FileOutputAdapter = FileOutputAdapter;
|
|
281
|
+
exports.FileOutputAdapter = FileOutputAdapter = __decorate([
|
|
282
|
+
(0, common_1.Injectable)()
|
|
283
|
+
], FileOutputAdapter);
|
|
284
|
+
//# sourceMappingURL=file-output.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-output.adapter.js","sourceRoot":"","sources":["../../../../../libs/nest-graph-inspector/src/adapters/file-output.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { OutputAdapter } from '../ports/output.adapter';
|
|
2
|
+
import { NestGraphInspectorOutput } from '../nest-graph-inspector.type';
|
|
3
|
+
import type { GraphOutput } from '../types/graph-output.type';
|
|
4
|
+
import { FileOutputAdapter } from './file-output.adapter';
|
|
5
|
+
import { HttpServeAdapter } from './http-serve.adapter';
|
|
6
|
+
type HttpOutputConfig = Extract<NestGraphInspectorOutput, {
|
|
7
|
+
type: 'http';
|
|
8
|
+
}>;
|
|
9
|
+
interface HttpOutputInternalOptions {
|
|
10
|
+
httpAdapter?: HttpServeAdapter;
|
|
11
|
+
}
|
|
12
|
+
export declare class HttpOutputAdapter implements OutputAdapter<HttpOutputConfig> {
|
|
13
|
+
private readonly fileOutputAdapter;
|
|
14
|
+
private readonly httpServeAdapter;
|
|
15
|
+
private static readonly inspectorEndpointInfo;
|
|
16
|
+
static readonly defaultConfig: Readonly<Required<Pick<HttpOutputConfig, 'host' | 'port'>>>;
|
|
17
|
+
constructor(fileOutputAdapter: FileOutputAdapter, httpServeAdapter: HttpServeAdapter);
|
|
18
|
+
execute(graphOutput: GraphOutput, config: HttpOutputConfig & HttpOutputInternalOptions): Promise<{
|
|
19
|
+
message: string;
|
|
20
|
+
}>;
|
|
21
|
+
normalizePath(path?: string): string;
|
|
22
|
+
private get httpOrigin();
|
|
23
|
+
private joinPath;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var HttpOutputAdapter_1;
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.HttpOutputAdapter = void 0;
|
|
14
|
+
const common_1 = require("@nestjs/common");
|
|
15
|
+
const file_output_adapter_1 = require("./file-output.adapter");
|
|
16
|
+
const http_serve_adapter_1 = require("./http-serve.adapter");
|
|
17
|
+
let HttpOutputAdapter = class HttpOutputAdapter {
|
|
18
|
+
static { HttpOutputAdapter_1 = this; }
|
|
19
|
+
fileOutputAdapter;
|
|
20
|
+
httpServeAdapter;
|
|
21
|
+
static inspectorEndpointInfo = {
|
|
22
|
+
for: 'nest-graph-inspector',
|
|
23
|
+
};
|
|
24
|
+
static defaultConfig = {
|
|
25
|
+
host: 'localhost',
|
|
26
|
+
port: 53371,
|
|
27
|
+
};
|
|
28
|
+
constructor(fileOutputAdapter, httpServeAdapter) {
|
|
29
|
+
this.fileOutputAdapter = fileOutputAdapter;
|
|
30
|
+
this.httpServeAdapter = httpServeAdapter;
|
|
31
|
+
}
|
|
32
|
+
async execute(graphOutput, config) {
|
|
33
|
+
const origin = config.origin ?? this.httpOrigin;
|
|
34
|
+
const path = this.normalizePath(config.path);
|
|
35
|
+
const informationOutputPath = this.joinPath(path, 'information.json');
|
|
36
|
+
const jsonOutputPath = this.joinPath(path, 'output.json');
|
|
37
|
+
const markdownOutputPath = this.joinPath(path, 'output.md');
|
|
38
|
+
const isReuseHttpAdapter = !!config.httpAdapter;
|
|
39
|
+
const httpAdapter = config.httpAdapter ?? this.httpServeAdapter;
|
|
40
|
+
const registration = httpAdapter.register({
|
|
41
|
+
origin,
|
|
42
|
+
host: config.host,
|
|
43
|
+
port: config.port,
|
|
44
|
+
}, [
|
|
45
|
+
httpAdapter.get(informationOutputPath, () => HttpOutputAdapter_1.inspectorEndpointInfo, {
|
|
46
|
+
responseHeaders: {
|
|
47
|
+
'content-type': 'application/json; charset=utf-8',
|
|
48
|
+
},
|
|
49
|
+
}),
|
|
50
|
+
httpAdapter.get(jsonOutputPath, () => graphOutput, {
|
|
51
|
+
responseHeaders: {
|
|
52
|
+
'content-type': 'application/json; charset=utf-8',
|
|
53
|
+
},
|
|
54
|
+
}),
|
|
55
|
+
httpAdapter.get(markdownOutputPath, () => this.fileOutputAdapter.buildMarkdownText(graphOutput), {
|
|
56
|
+
responseHeaders: {
|
|
57
|
+
'content-type': 'text/markdown; charset=utf-8',
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
]);
|
|
61
|
+
if (!isReuseHttpAdapter) {
|
|
62
|
+
try {
|
|
63
|
+
await httpAdapter.serve();
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
httpAdapter.close(registration.origin);
|
|
67
|
+
throw err;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const informationOutputUrl = new URL(informationOutputPath, registration.origin);
|
|
71
|
+
const jsonOutputUrl = new URL(jsonOutputPath, registration.origin);
|
|
72
|
+
const markdownOutputUrl = new URL(markdownOutputPath, registration.origin);
|
|
73
|
+
return {
|
|
74
|
+
message: `Graph inspector HTTP endpoints are installed at ${informationOutputUrl}, ${jsonOutputUrl}, and ${markdownOutputUrl}`,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
normalizePath(path = '/__nest-graph-inspector') {
|
|
78
|
+
return path.startsWith('/') ? path : `/${path}`;
|
|
79
|
+
}
|
|
80
|
+
get httpOrigin() {
|
|
81
|
+
const { host, port } = HttpOutputAdapter_1.defaultConfig;
|
|
82
|
+
return `http://${host}:${port}`;
|
|
83
|
+
}
|
|
84
|
+
joinPath(basePath, childPath) {
|
|
85
|
+
return `${basePath.replace(/\/$/, '')}/${childPath.replace(/^\//, '')}`;
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
exports.HttpOutputAdapter = HttpOutputAdapter;
|
|
89
|
+
exports.HttpOutputAdapter = HttpOutputAdapter = HttpOutputAdapter_1 = __decorate([
|
|
90
|
+
(0, common_1.Injectable)(),
|
|
91
|
+
__metadata("design:paramtypes", [file_output_adapter_1.FileOutputAdapter,
|
|
92
|
+
http_serve_adapter_1.HttpServeAdapter])
|
|
93
|
+
], HttpOutputAdapter);
|
|
94
|
+
//# sourceMappingURL=http-output.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-output.adapter.js","sourceRoot":"","sources":["../../../../../libs/nest-graph-inspector/src/adapters/http-output.adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import { OnModuleDestroy } from '@nestjs/common';
|
|
3
|
+
export type HttpServeOptions = {
|
|
4
|
+
origin?: string;
|
|
5
|
+
host?: string;
|
|
6
|
+
port?: number;
|
|
7
|
+
};
|
|
8
|
+
export type HttpServeRoute = {
|
|
9
|
+
type: string;
|
|
10
|
+
path: string;
|
|
11
|
+
callback?: (context: HttpServeRequest) => unknown | Promise<unknown>;
|
|
12
|
+
rawCallback?: (req: http.IncomingMessage, res: http.ServerResponse) => void | Promise<void>;
|
|
13
|
+
requestHeaders?: http.OutgoingHttpHeaders;
|
|
14
|
+
responseHeaders?: http.OutgoingHttpHeaders;
|
|
15
|
+
contentType?: string;
|
|
16
|
+
statusCode?: number;
|
|
17
|
+
};
|
|
18
|
+
export type HttpServeRequest = {
|
|
19
|
+
request: http.IncomingMessage;
|
|
20
|
+
headers: http.IncomingHttpHeaders;
|
|
21
|
+
};
|
|
22
|
+
export type HttpServeResponse = {
|
|
23
|
+
statusCode?: number;
|
|
24
|
+
contentType?: string;
|
|
25
|
+
headers?: http.OutgoingHttpHeaders;
|
|
26
|
+
body?: unknown;
|
|
27
|
+
};
|
|
28
|
+
export declare class HttpServeAdapter implements OnModuleDestroy {
|
|
29
|
+
private readonly servers;
|
|
30
|
+
register(options: HttpServeOptions, routes: HttpServeRoute[]): {
|
|
31
|
+
origin: string;
|
|
32
|
+
};
|
|
33
|
+
get(path: string, callback: HttpServeRoute['callback'], options?: Omit<HttpServeRoute, 'type' | 'path' | 'callback'>): HttpServeRoute;
|
|
34
|
+
post(path: string, callback: HttpServeRoute['callback'], options?: Omit<HttpServeRoute, 'type' | 'path' | 'callback'>): HttpServeRoute;
|
|
35
|
+
all(path: string, rawCallback: NonNullable<HttpServeRoute['rawCallback']>, options?: Omit<HttpServeRoute, 'type' | 'path' | 'rawCallback'>): HttpServeRoute;
|
|
36
|
+
serve(): Promise<void>;
|
|
37
|
+
close(origin?: string): void;
|
|
38
|
+
onModuleDestroy(): void;
|
|
39
|
+
private serverState;
|
|
40
|
+
private serveState;
|
|
41
|
+
private listen;
|
|
42
|
+
private handleRequest;
|
|
43
|
+
private route;
|
|
44
|
+
private wildcardPathCandidates;
|
|
45
|
+
private routeKey;
|
|
46
|
+
private sendResult;
|
|
47
|
+
private normalizeResponse;
|
|
48
|
+
private isHttpServeResponse;
|
|
49
|
+
private serializeBody;
|
|
50
|
+
private sendText;
|
|
51
|
+
private requestHeadersMatch;
|
|
52
|
+
private headerValue;
|
|
53
|
+
private contentTypeHeader;
|
|
54
|
+
private setCorsHeaders;
|
|
55
|
+
private resolveDynamicPort;
|
|
56
|
+
private normalizeOrigin;
|
|
57
|
+
private normalizePath;
|
|
58
|
+
}
|