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.
Files changed (39) hide show
  1. package/README.md +20 -11
  2. package/package.json +1 -1
  3. package/src/{drivers/file-output.driver.d.ts → adapters/file-output.adapter.d.ts} +17 -2
  4. package/src/adapters/file-output.adapter.js +284 -0
  5. package/src/adapters/file-output.adapter.js.map +1 -0
  6. package/src/adapters/http-output.adapter.d.ts +25 -0
  7. package/src/adapters/http-output.adapter.js +94 -0
  8. package/src/adapters/http-output.adapter.js.map +1 -0
  9. package/src/adapters/http-serve.adapter.d.ts +58 -0
  10. package/src/adapters/http-serve.adapter.js +298 -0
  11. package/src/adapters/http-serve.adapter.js.map +1 -0
  12. package/src/{drivers/json-output.driver.d.ts → adapters/json-output.adapter.d.ts} +1 -1
  13. package/src/{drivers/json-output.driver.js → adapters/json-output.adapter.js} +6 -6
  14. package/src/adapters/json-output.adapter.js.map +1 -0
  15. package/src/adapters/proxy.adapter.d.ts +21 -0
  16. package/src/adapters/proxy.adapter.js +153 -0
  17. package/src/adapters/proxy.adapter.js.map +1 -0
  18. package/src/adapters/viewer-output.adapter.d.ts +22 -0
  19. package/src/adapters/viewer-output.adapter.js +82 -0
  20. package/src/adapters/viewer-output.adapter.js.map +1 -0
  21. package/src/nest-graph-inspector.module.js +22 -9
  22. package/src/nest-graph-inspector.module.js.map +1 -1
  23. package/src/nest-graph-inspector.setup.d.ts +19 -5
  24. package/src/nest-graph-inspector.setup.js +217 -9
  25. package/src/nest-graph-inspector.setup.js.map +1 -1
  26. package/src/nest-graph-inspector.type.d.ts +10 -0
  27. package/src/ports/proxy.gateway.d.ts +15 -0
  28. package/src/ports/proxy.gateway.js +3 -0
  29. package/src/ports/proxy.gateway.js.map +1 -0
  30. package/src/types/graph-output.type.d.ts +27 -0
  31. package/src/drivers/file-output.driver.js +0 -187
  32. package/src/drivers/file-output.driver.js.map +0 -1
  33. package/src/drivers/http-output.driver.d.ts +0 -19
  34. package/src/drivers/http-output.driver.js +0 -62
  35. package/src/drivers/http-output.driver.js.map +0 -1
  36. package/src/drivers/json-output.driver.js.map +0 -1
  37. package/src/drivers/viewer-output.driver.d.ts +0 -16
  38. package/src/drivers/viewer-output.driver.js +0 -42
  39. 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
- ### Result Preview
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
- ## Features
21
+ ## Why It Matters
22
22
 
23
- - **Runtime introspection** graphs are built from the actual Nest container, not static source parsing
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 { NestGraphInspector } from 'nest-graph-inspector';
50
+ import { NestGraphInspectorModule } from 'nest-graph-inspector';
42
51
 
43
52
  @Module({
44
- imports: [NestGraphInspector],
53
+ imports: [NestGraphInspectorModule],
45
54
  })
46
55
  export class RootModule {}
47
56
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nest-graph-inspector",
3
- "version": "0.2.9",
3
+ "version": "0.4.0",
4
4
  "description": "NestJS module graph inspector for discovery and dependency analysis",
5
5
  "license": "MIT",
6
6
  "main": "./src/index.js",
@@ -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 FileOutputDriver implements OutputAdapter<FileOutputConfig> {
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
+ }