nestjs-devtools 1.0.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 (47) hide show
  1. package/README.md +84 -0
  2. package/dist/collectors/abstract.collector.d.ts +7 -0
  3. package/dist/collectors/abstract.collector.js +7 -0
  4. package/dist/collectors/abstract.collector.js.map +1 -0
  5. package/dist/collectors/database.collector.d.ts +9 -0
  6. package/dist/collectors/database.collector.js +47 -0
  7. package/dist/collectors/database.collector.js.map +1 -0
  8. package/dist/collectors/index.d.ts +6 -0
  9. package/dist/collectors/index.js +16 -0
  10. package/dist/collectors/index.js.map +1 -0
  11. package/dist/collectors/log.collector.d.ts +9 -0
  12. package/dist/collectors/log.collector.js +56 -0
  13. package/dist/collectors/log.collector.js.map +1 -0
  14. package/dist/collectors/performance.collector.d.ts +9 -0
  15. package/dist/collectors/performance.collector.js +45 -0
  16. package/dist/collectors/performance.collector.js.map +1 -0
  17. package/dist/collectors/request.collector.d.ts +9 -0
  18. package/dist/collectors/request.collector.js +48 -0
  19. package/dist/collectors/request.collector.js.map +1 -0
  20. package/dist/collectors/route.collector.d.ts +13 -0
  21. package/dist/collectors/route.collector.js +92 -0
  22. package/dist/collectors/route.collector.js.map +1 -0
  23. package/dist/devtools.controller.d.ts +17 -0
  24. package/dist/devtools.controller.js +69 -0
  25. package/dist/devtools.controller.js.map +1 -0
  26. package/dist/devtools.filter.d.ts +8 -0
  27. package/dist/devtools.filter.js +71 -0
  28. package/dist/devtools.filter.js.map +1 -0
  29. package/dist/devtools.interceptor.d.ts +8 -0
  30. package/dist/devtools.interceptor.js +72 -0
  31. package/dist/devtools.interceptor.js.map +1 -0
  32. package/dist/devtools.module.d.ts +14 -0
  33. package/dist/devtools.module.js +81 -0
  34. package/dist/devtools.module.js.map +1 -0
  35. package/dist/devtools.service.d.ts +28 -0
  36. package/dist/devtools.service.js +86 -0
  37. package/dist/devtools.service.js.map +1 -0
  38. package/dist/index.d.ts +7 -0
  39. package/dist/index.js +18 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/interfaces/devtools-collector.interface.d.ts +64 -0
  42. package/dist/interfaces/devtools-collector.interface.js +3 -0
  43. package/dist/interfaces/devtools-collector.interface.js.map +1 -0
  44. package/dist/interfaces/index.d.ts +1 -0
  45. package/dist/interfaces/index.js +18 -0
  46. package/dist/interfaces/index.js.map +1 -0
  47. package/package.json +53 -0
package/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # NestJS Devtools Module
2
+
3
+ Symfony-style debug toolbar for NestJS applications.
4
+
5
+ ## Features
6
+
7
+ - **Request info** - method, path, status code, duration, memory
8
+ - **Performance metrics** - execution time, peak memory, query timing
9
+ - **Database queries** - SQL log with count and timing
10
+ - **Route listing** - all registered routes grouped by HTTP method
11
+ - **Logs & errors** - request-scoped log entries and exceptions
12
+ - **Inject toolbar** - auto-injects debug bar into HTML responses
13
+ - **API endpoint** - access raw debug data at `/__devtools`
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @nestjs/devtools
19
+ # or
20
+ yarn add @nestjs/devtools
21
+ ```
22
+
23
+ ## Usage
24
+
25
+ Import in your root `AppModule`:
26
+
27
+ ```typescript
28
+ import { Module } from '@nestjs/common';
29
+ import { DevtoolsModule } from '@nestjs/devtools';
30
+
31
+ @Module({
32
+ imports: [
33
+ DevtoolsModule.forRoot({
34
+ enabled: process.env.NODE_ENV !== 'production',
35
+ maxHistory: 50,
36
+ injectToolbar: true,
37
+ }),
38
+ ],
39
+ })
40
+ export class AppModule {}
41
+ ```
42
+
43
+ ## Options
44
+
45
+ | Option | Type | Default | Description |
46
+ |----------------|------------|------------------------|--------------------------------------|
47
+ | `enabled` | `boolean` | `NODE_ENV !== 'prod'` | Enable/disable the module |
48
+ | `maxHistory` | `number` | `50` | Max requests kept in history |
49
+ | `injectToolbar`| `boolean` | `true` | Auto-inject toolbar into HTML |
50
+ | `position` | `string` | `'bottom-left'` | Toolbar position on screen |
51
+ | `theme` | `'light'|'dark'` | `'dark'` | Toolbar color theme |
52
+ | `collectors` | `Type[]` | `defaults` | Custom collectors to register |
53
+
54
+ ## Custom Collector
55
+
56
+ ```typescript
57
+ import { Injectable } from '@nestjs/common';
58
+ import { AbstractCollector, DevtoolsData } from '@nestjs/devtools';
59
+
60
+ @Injectable()
61
+ export class CustomCollector extends AbstractCollector {
62
+ readonly name = 'custom';
63
+
64
+ collect(): DevtoolsData {
65
+ return {
66
+ label: 'Custom',
67
+ icon: '🔧',
68
+ summary: 'Custom data',
69
+ details: { key: 'value' },
70
+ };
71
+ }
72
+ }
73
+ ```
74
+
75
+ Then pass it to `forRoot`:
76
+
77
+ ```typescript
78
+ DevtoolsModule.forRoot({ collectors: [CustomCollector] })
79
+ ```
80
+
81
+ ## API Endpoints
82
+
83
+ - `GET /__devtools/data` - Toolbar panel data
84
+ - `GET /__devtools/history` - Request history summary
@@ -0,0 +1,7 @@
1
+ import { DevtoolsData } from '../interfaces';
2
+ export declare abstract class AbstractCollector {
3
+ abstract readonly name: string;
4
+ abstract collect(): DevtoolsData | Promise<DevtoolsData>;
5
+ onModuleInit?(): void;
6
+ onModuleDestroy?(): void;
7
+ }
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AbstractCollector = void 0;
4
+ class AbstractCollector {
5
+ }
6
+ exports.AbstractCollector = AbstractCollector;
7
+ //# sourceMappingURL=abstract.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abstract.collector.js","sourceRoot":"","sources":["../../collectors/abstract.collector.ts"],"names":[],"mappings":";;;AAEA,MAAsB,iBAAiB;CAKtC;AALD,8CAKC"}
@@ -0,0 +1,9 @@
1
+ import { AbstractCollector } from './abstract.collector';
2
+ import { DevtoolsData } from '../interfaces';
3
+ import { DevtoolsService } from '../devtools.service';
4
+ export declare class DatabaseCollector extends AbstractCollector {
5
+ private readonly devtoolsService;
6
+ readonly name = "database";
7
+ constructor(devtoolsService: DevtoolsService);
8
+ collect(): DevtoolsData;
9
+ }
@@ -0,0 +1,47 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DatabaseCollector = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const abstract_collector_1 = require("./abstract.collector");
15
+ const devtools_service_1 = require("../devtools.service");
16
+ let DatabaseCollector = class DatabaseCollector extends abstract_collector_1.AbstractCollector {
17
+ constructor(devtoolsService) {
18
+ super();
19
+ this.devtoolsService = devtoolsService;
20
+ this.name = 'database';
21
+ }
22
+ collect() {
23
+ const last = this.devtoolsService.getLastRequest();
24
+ const queries = last?.queries ?? [];
25
+ const totalDuration = queries.reduce((a, q) => a + q.duration, 0);
26
+ return {
27
+ label: 'Database',
28
+ icon: '🗄️',
29
+ summary: `${queries.length} queries in ${totalDuration.toFixed(1)} ms`,
30
+ details: {
31
+ totalQueries: queries.length,
32
+ totalTime: `${totalDuration.toFixed(2)} ms`,
33
+ queries: queries.map((q, i) => ({
34
+ '#': i + 1,
35
+ sql: q.sql.length > 80 ? q.sql.slice(0, 80) + '...' : q.sql,
36
+ duration: `${q.duration.toFixed(2)} ms`,
37
+ })),
38
+ },
39
+ };
40
+ }
41
+ };
42
+ exports.DatabaseCollector = DatabaseCollector;
43
+ exports.DatabaseCollector = DatabaseCollector = __decorate([
44
+ (0, common_1.Injectable)(),
45
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
46
+ ], DatabaseCollector);
47
+ //# sourceMappingURL=database.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.collector.js","sourceRoot":"","sources":["../../collectors/database.collector.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAEzD,0DAAsD;AAG/C,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,sCAAiB;IAGtD,YAA6B,eAAgC;QAC3D,KAAK,EAAE,CAAC;QADmB,oBAAe,GAAf,eAAe,CAAiB;QAFpD,SAAI,GAAG,UAAU,CAAC;IAI3B,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;QACnD,MAAM,OAAO,GAAG,IAAI,EAAE,OAAO,IAAI,EAAE,CAAC;QACpC,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QAElE,OAAO;YACL,KAAK,EAAE,UAAU;YACjB,IAAI,EAAE,KAAK;YACX,OAAO,EAAE,GAAG,OAAO,CAAC,MAAM,eAAe,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YACtE,OAAO,EAAE;gBACP,YAAY,EAAE,OAAO,CAAC,MAAM;gBAC5B,SAAS,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBAC3C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9B,GAAG,EAAE,CAAC,GAAG,CAAC;oBACV,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;oBAC3D,QAAQ,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;iBACxC,CAAC,CAAC;aACJ;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA3BY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,mBAAU,GAAE;qCAImC,kCAAe;GAHlD,iBAAiB,CA2B7B"}
@@ -0,0 +1,6 @@
1
+ export { AbstractCollector } from './abstract.collector';
2
+ export { RequestCollector } from './request.collector';
3
+ export { PerformanceCollector } from './performance.collector';
4
+ export { DatabaseCollector } from './database.collector';
5
+ export { RouteCollector } from './route.collector';
6
+ export { LogCollector } from './log.collector';
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogCollector = exports.RouteCollector = exports.DatabaseCollector = exports.PerformanceCollector = exports.RequestCollector = exports.AbstractCollector = void 0;
4
+ var abstract_collector_1 = require("./abstract.collector");
5
+ Object.defineProperty(exports, "AbstractCollector", { enumerable: true, get: function () { return abstract_collector_1.AbstractCollector; } });
6
+ var request_collector_1 = require("./request.collector");
7
+ Object.defineProperty(exports, "RequestCollector", { enumerable: true, get: function () { return request_collector_1.RequestCollector; } });
8
+ var performance_collector_1 = require("./performance.collector");
9
+ Object.defineProperty(exports, "PerformanceCollector", { enumerable: true, get: function () { return performance_collector_1.PerformanceCollector; } });
10
+ var database_collector_1 = require("./database.collector");
11
+ Object.defineProperty(exports, "DatabaseCollector", { enumerable: true, get: function () { return database_collector_1.DatabaseCollector; } });
12
+ var route_collector_1 = require("./route.collector");
13
+ Object.defineProperty(exports, "RouteCollector", { enumerable: true, get: function () { return route_collector_1.RouteCollector; } });
14
+ var log_collector_1 = require("./log.collector");
15
+ Object.defineProperty(exports, "LogCollector", { enumerable: true, get: function () { return log_collector_1.LogCollector; } });
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../collectors/index.ts"],"names":[],"mappings":";;;AAAA,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,yDAAuD;AAA9C,qHAAA,gBAAgB,OAAA;AACzB,iEAA+D;AAAtD,6HAAA,oBAAoB,OAAA;AAC7B,2DAAyD;AAAhD,uHAAA,iBAAiB,OAAA;AAC1B,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AACvB,iDAA+C;AAAtC,6GAAA,YAAY,OAAA"}
@@ -0,0 +1,9 @@
1
+ import { AbstractCollector } from './abstract.collector';
2
+ import { DevtoolsData } from '../interfaces';
3
+ import { DevtoolsService } from '../devtools.service';
4
+ export declare class LogCollector extends AbstractCollector {
5
+ private readonly devtoolsService;
6
+ readonly name = "logs";
7
+ constructor(devtoolsService: DevtoolsService);
8
+ collect(): DevtoolsData;
9
+ }
@@ -0,0 +1,56 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.LogCollector = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const abstract_collector_1 = require("./abstract.collector");
15
+ const devtools_service_1 = require("../devtools.service");
16
+ let LogCollector = class LogCollector extends abstract_collector_1.AbstractCollector {
17
+ constructor(devtoolsService) {
18
+ super();
19
+ this.devtoolsService = devtoolsService;
20
+ this.name = 'logs';
21
+ }
22
+ collect() {
23
+ const last = this.devtoolsService.getLastRequest();
24
+ const logs = last?.logs ?? [];
25
+ const errors = logs.filter((l) => l.level === 'error');
26
+ const warnings = logs.filter((l) => l.level === 'warn');
27
+ return {
28
+ label: 'Logs',
29
+ icon: '📝',
30
+ summary: `${logs.length} entries (${errors.length} errors, ${warnings.length} warnings)`,
31
+ details: {
32
+ total: logs.length,
33
+ errors: errors.length,
34
+ warnings: warnings.length,
35
+ entries: logs.slice(-20).map((l) => ({
36
+ level: l.level,
37
+ message: l.message,
38
+ time: l.timestamp.toISOString(),
39
+ })),
40
+ hasException: !!last?.exception,
41
+ exception: last?.exception
42
+ ? {
43
+ message: last.exception.message,
44
+ stack: last.exception.stack,
45
+ }
46
+ : null,
47
+ },
48
+ };
49
+ }
50
+ };
51
+ exports.LogCollector = LogCollector;
52
+ exports.LogCollector = LogCollector = __decorate([
53
+ (0, common_1.Injectable)(),
54
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
55
+ ], LogCollector);
56
+ //# sourceMappingURL=log.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.collector.js","sourceRoot":"","sources":["../../collectors/log.collector.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAEzD,0DAAsD;AAG/C,IAAM,YAAY,GAAlB,MAAM,YAAa,SAAQ,sCAAiB;IAGjD,YAA6B,eAAgC;QAC3D,KAAK,EAAE,CAAC;QADmB,oBAAe,GAAf,eAAe,CAAiB;QAFpD,SAAI,GAAG,MAAM,CAAC;IAIvB,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,CAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;QAExD,OAAO;YACL,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,aAAa,MAAM,CAAC,MAAM,YAAY,QAAQ,CAAC,MAAM,YAAY;YACxF,OAAO,EAAE;gBACP,KAAK,EAAE,IAAI,CAAC,MAAM;gBAClB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,QAAQ,EAAE,QAAQ,CAAC,MAAM;gBACzB,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBACnC,KAAK,EAAE,CAAC,CAAC,KAAK;oBACd,OAAO,EAAE,CAAC,CAAC,OAAO;oBAClB,IAAI,EAAE,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE;iBAChC,CAAC,CAAC;gBACH,YAAY,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS;gBAC/B,SAAS,EAAE,IAAI,EAAE,SAAS;oBACxB,CAAC,CAAC;wBACE,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO;wBAC/B,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;qBAC5B;oBACH,CAAC,CAAC,IAAI;aACT;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AApCY,oCAAY;uBAAZ,YAAY;IADxB,IAAA,mBAAU,GAAE;qCAImC,kCAAe;GAHlD,YAAY,CAoCxB"}
@@ -0,0 +1,9 @@
1
+ import { AbstractCollector } from './abstract.collector';
2
+ import { DevtoolsData } from '../interfaces';
3
+ import { DevtoolsService } from '../devtools.service';
4
+ export declare class PerformanceCollector extends AbstractCollector {
5
+ private readonly devtoolsService;
6
+ readonly name = "performance";
7
+ constructor(devtoolsService: DevtoolsService);
8
+ collect(): DevtoolsData;
9
+ }
@@ -0,0 +1,45 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.PerformanceCollector = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const abstract_collector_1 = require("./abstract.collector");
15
+ const devtools_service_1 = require("../devtools.service");
16
+ let PerformanceCollector = class PerformanceCollector extends abstract_collector_1.AbstractCollector {
17
+ constructor(devtoolsService) {
18
+ super();
19
+ this.devtoolsService = devtoolsService;
20
+ this.name = 'performance';
21
+ }
22
+ collect() {
23
+ const last = this.devtoolsService.getLastRequest();
24
+ if (!last) {
25
+ return { label: 'Performance', icon: '⚡', summary: 'No data', details: {} };
26
+ }
27
+ return {
28
+ label: 'Performance',
29
+ icon: '⚡',
30
+ summary: `${last.duration.toFixed(1)} ms, ${(last.memory / 1024 / 1024).toFixed(1)} MB`,
31
+ details: {
32
+ duration: `${last.duration.toFixed(2)} ms`,
33
+ peakMemory: `${(last.memory / 1024 / 1024).toFixed(2)} MB`,
34
+ queries: last.queries.length,
35
+ queryTime: `${last.queries.reduce((a, q) => a + q.duration, 0).toFixed(2)} ms`,
36
+ },
37
+ };
38
+ }
39
+ };
40
+ exports.PerformanceCollector = PerformanceCollector;
41
+ exports.PerformanceCollector = PerformanceCollector = __decorate([
42
+ (0, common_1.Injectable)(),
43
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
44
+ ], PerformanceCollector);
45
+ //# sourceMappingURL=performance.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"performance.collector.js","sourceRoot":"","sources":["../../collectors/performance.collector.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAEzD,0DAAsD;AAG/C,IAAM,oBAAoB,GAA1B,MAAM,oBAAqB,SAAQ,sCAAiB;IAGzD,YAA6B,eAAgC;QAC3D,KAAK,EAAE,CAAC;QADmB,oBAAe,GAAf,eAAe,CAAiB;QAFpD,SAAI,GAAG,aAAa,CAAC;IAI9B,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC9E,CAAC;QAED,OAAO;YACL,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE,GAAG;YACT,OAAO,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;YACvF,OAAO,EAAE;gBACP,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBAC1C,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBAC1D,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,MAAM;gBAC5B,SAAS,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;aAC/E;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AAzBY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;qCAImC,kCAAe;GAHlD,oBAAoB,CAyBhC"}
@@ -0,0 +1,9 @@
1
+ import { AbstractCollector } from './abstract.collector';
2
+ import { DevtoolsData } from '../interfaces';
3
+ import { DevtoolsService } from '../devtools.service';
4
+ export declare class RequestCollector extends AbstractCollector {
5
+ private readonly devtoolsService;
6
+ readonly name = "request";
7
+ constructor(devtoolsService: DevtoolsService);
8
+ collect(): DevtoolsData;
9
+ }
@@ -0,0 +1,48 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RequestCollector = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const abstract_collector_1 = require("./abstract.collector");
15
+ const devtools_service_1 = require("../devtools.service");
16
+ let RequestCollector = class RequestCollector extends abstract_collector_1.AbstractCollector {
17
+ constructor(devtoolsService) {
18
+ super();
19
+ this.devtoolsService = devtoolsService;
20
+ this.name = 'request';
21
+ }
22
+ collect() {
23
+ const last = this.devtoolsService.getLastRequest();
24
+ if (!last) {
25
+ return { label: 'Request', icon: '🌐', summary: 'No requests', details: {} };
26
+ }
27
+ return {
28
+ label: 'Request',
29
+ icon: '🌐',
30
+ summary: `${last.method} ${last.path} → ${last.statusCode}`,
31
+ details: {
32
+ method: last.method,
33
+ path: last.path,
34
+ status: last.statusCode,
35
+ duration: `${last.duration.toFixed(2)} ms`,
36
+ memory: `${(last.memory / 1024 / 1024).toFixed(2)} MB`,
37
+ timestamp: last.timestamp.toISOString(),
38
+ route: last.route,
39
+ },
40
+ };
41
+ }
42
+ };
43
+ exports.RequestCollector = RequestCollector;
44
+ exports.RequestCollector = RequestCollector = __decorate([
45
+ (0, common_1.Injectable)(),
46
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
47
+ ], RequestCollector);
48
+ //# sourceMappingURL=request.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request.collector.js","sourceRoot":"","sources":["../../collectors/request.collector.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6DAAyD;AAEzD,0DAAsD;AAG/C,IAAM,gBAAgB,GAAtB,MAAM,gBAAiB,SAAQ,sCAAiB;IAGrD,YAA6B,eAAgC;QAC3D,KAAK,EAAE,CAAC;QADmB,oBAAe,GAAf,eAAe,CAAiB;QAFpD,SAAI,GAAG,SAAS,CAAC;IAI1B,CAAC;IAED,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,cAAc,EAAE,CAAC;QACnD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QAC/E,CAAC;QAED,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,IAAI,EAAE,IAAI;YACV,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,UAAU,EAAE;YAC3D,OAAO,EAAE;gBACP,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,MAAM,EAAE,IAAI,CAAC,UAAU;gBACvB,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBAC1C,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,IAAI,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK;gBACtD,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE;gBACvC,KAAK,EAAE,IAAI,CAAC,KAAK;aAClB;SACF,CAAC;IACJ,CAAC;CACF,CAAA;AA5BY,4CAAgB;2BAAhB,gBAAgB;IAD5B,IAAA,mBAAU,GAAE;qCAImC,kCAAe;GAHlD,gBAAgB,CA4B5B"}
@@ -0,0 +1,13 @@
1
+ import { OnModuleInit } from '@nestjs/common';
2
+ import { ModuleRef } from '@nestjs/core';
3
+ import { AbstractCollector } from './abstract.collector';
4
+ import { DevtoolsData } from '../interfaces';
5
+ export declare class RouteCollector extends AbstractCollector implements OnModuleInit {
6
+ private readonly moduleRef;
7
+ readonly name = "routes";
8
+ private routes;
9
+ constructor(moduleRef: ModuleRef);
10
+ onModuleInit(): void;
11
+ private discoverRoutes;
12
+ collect(): DevtoolsData;
13
+ }
@@ -0,0 +1,92 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RouteCollector = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const core_1 = require("@nestjs/core");
15
+ const abstract_collector_1 = require("./abstract.collector");
16
+ const constants_1 = require("@nestjs/common/constants");
17
+ let RouteCollector = class RouteCollector extends abstract_collector_1.AbstractCollector {
18
+ constructor(moduleRef) {
19
+ super();
20
+ this.moduleRef = moduleRef;
21
+ this.name = 'routes';
22
+ this.routes = [];
23
+ }
24
+ onModuleInit() {
25
+ this.discoverRoutes();
26
+ }
27
+ discoverRoutes() {
28
+ try {
29
+ const container = this.moduleRef.container;
30
+ if (!container)
31
+ return;
32
+ const modules = container.getModules();
33
+ modules?.forEach((module) => {
34
+ module.controllers?.forEach((controller) => {
35
+ const instance = controller.instance;
36
+ if (!instance)
37
+ return;
38
+ const controllerPath = Reflect.getMetadata(constants_1.PATH_METADATA, instance.constructor) ?? '';
39
+ const prototype = Object.getPrototypeOf(instance);
40
+ const methods = Object.getOwnPropertyNames(prototype).filter((m) => m !== 'constructor' && typeof prototype[m] === 'function');
41
+ for (const methodName of methods) {
42
+ const handler = prototype[methodName];
43
+ const methodMeta = Reflect.getMetadata(constants_1.METHOD_METADATA, handler);
44
+ const pathMeta = Reflect.getMetadata(constants_1.PATH_METADATA, handler);
45
+ if (methodMeta) {
46
+ this.routes.push({
47
+ path: `/${[controllerPath, pathMeta].filter(Boolean).join('/').replace(/\/+/g, '/')}`,
48
+ method: methodMeta,
49
+ controller: instance.constructor.name,
50
+ handler: methodName,
51
+ });
52
+ }
53
+ }
54
+ });
55
+ });
56
+ }
57
+ catch {
58
+ this.routes = [];
59
+ }
60
+ }
61
+ collect() {
62
+ const grouped = this.routes.reduce((acc, r) => {
63
+ const key = r.method;
64
+ if (!acc[key])
65
+ acc[key] = [];
66
+ acc[key].push(r);
67
+ return acc;
68
+ }, {});
69
+ return {
70
+ label: 'Routes',
71
+ icon: '📋',
72
+ summary: `${this.routes.length} routes registered`,
73
+ details: {
74
+ total: this.routes.length,
75
+ grouped: Object.entries(grouped).map(([method, routes]) => ({
76
+ method,
77
+ count: routes.length,
78
+ routes: routes.map((r) => ({
79
+ path: r.path,
80
+ controller: `${r.controller}.${r.handler}`,
81
+ })),
82
+ })),
83
+ },
84
+ };
85
+ }
86
+ };
87
+ exports.RouteCollector = RouteCollector;
88
+ exports.RouteCollector = RouteCollector = __decorate([
89
+ (0, common_1.Injectable)(),
90
+ __metadata("design:paramtypes", [core_1.ModuleRef])
91
+ ], RouteCollector);
92
+ //# sourceMappingURL=route.collector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route.collector.js","sourceRoot":"","sources":["../../collectors/route.collector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { DevtoolsService } from './devtools.service';
2
+ import { AbstractCollector } from './collectors';
3
+ export declare class DevtoolsController {
4
+ private readonly devtoolsService;
5
+ private readonly collectors;
6
+ constructor(devtoolsService: DevtoolsService, collectors?: AbstractCollector[]);
7
+ getToolbarData(): Record<string, unknown>;
8
+ getHistory(): {
9
+ id: string;
10
+ method: string;
11
+ path: string;
12
+ statusCode: number;
13
+ duration: number;
14
+ timestamp: Date;
15
+ }[];
16
+ getRequestDetail(id: string): import("./interfaces").RequestDebugInfo | null;
17
+ }
@@ -0,0 +1,69 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DevtoolsController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const devtools_service_1 = require("./devtools.service");
18
+ const devtools_module_1 = require("./devtools.module");
19
+ let DevtoolsController = class DevtoolsController {
20
+ constructor(devtoolsService, collectors = []) {
21
+ this.devtoolsService = devtoolsService;
22
+ this.collectors = collectors;
23
+ }
24
+ getToolbarData() {
25
+ const panels = {};
26
+ for (const collector of this.collectors) {
27
+ try {
28
+ panels[collector.name] = collector.collect();
29
+ }
30
+ catch {
31
+ panels[collector.name] = { label: collector.name, summary: 'Error collecting data' };
32
+ }
33
+ }
34
+ return panels;
35
+ }
36
+ getHistory() {
37
+ return this.devtoolsService.getHistorySummary();
38
+ }
39
+ getRequestDetail(id) {
40
+ const history = this.devtoolsService.getHistory();
41
+ return history.find((r) => r.id === id) ?? null;
42
+ }
43
+ };
44
+ exports.DevtoolsController = DevtoolsController;
45
+ __decorate([
46
+ (0, common_1.Get)('data'),
47
+ __metadata("design:type", Function),
48
+ __metadata("design:paramtypes", []),
49
+ __metadata("design:returntype", void 0)
50
+ ], DevtoolsController.prototype, "getToolbarData", null);
51
+ __decorate([
52
+ (0, common_1.Get)('history'),
53
+ __metadata("design:type", Function),
54
+ __metadata("design:paramtypes", []),
55
+ __metadata("design:returntype", void 0)
56
+ ], DevtoolsController.prototype, "getHistory", null);
57
+ __decorate([
58
+ (0, common_1.Get)('request/:id'),
59
+ __metadata("design:type", Function),
60
+ __metadata("design:paramtypes", [String]),
61
+ __metadata("design:returntype", void 0)
62
+ ], DevtoolsController.prototype, "getRequestDetail", null);
63
+ exports.DevtoolsController = DevtoolsController = __decorate([
64
+ (0, common_1.Controller)('__devtools'),
65
+ __param(1, (0, common_1.Optional)()),
66
+ __param(1, (0, common_1.Inject)(devtools_module_1.DEVOOLS_COLLECTORS_TOKEN)),
67
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService, Array])
68
+ ], DevtoolsController);
69
+ //# sourceMappingURL=devtools.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.controller.js","sourceRoot":"","sources":["../devtools.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAmE;AACnE,yDAAqD;AAErD,uDAA6D;AAGtD,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAC7B,YACmB,eAAgC,EAGhC,aAAkC,EAAE;QAHpC,oBAAe,GAAf,eAAe,CAAiB;QAGhC,eAAU,GAAV,UAAU,CAA0B;IACpD,CAAC;IAGJ,cAAc;QACZ,MAAM,MAAM,GAA4B,EAAE,CAAC;QAC3C,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,IAAI,CAAC;gBACH,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC;YACvF,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAGD,UAAU;QACR,OAAO,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC;IAClD,CAAC;IAGD,gBAAgB,CAAC,EAAU;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,IAAI,CAAC;IAClD,CAAC;CACF,CAAA;AA/BY,gDAAkB;AAS7B;IADC,IAAA,YAAG,EAAC,MAAM,CAAC;;;;wDAWX;AAGD;IADC,IAAA,YAAG,EAAC,SAAS,CAAC;;;;oDAGd;AAGD;IADC,IAAA,YAAG,EAAC,aAAa,CAAC;;;;0DAIlB;6BA9BU,kBAAkB;IAD9B,IAAA,mBAAU,EAAC,YAAY,CAAC;IAIpB,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,0CAAwB,CAAC,CAAA;qCAFC,kCAAe;GAFxC,kBAAkB,CA+B9B"}
@@ -0,0 +1,8 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ import { DevtoolsService } from './devtools.service';
4
+ export declare class DevtoolsFilter implements NestInterceptor {
5
+ private readonly devtoolsService;
6
+ constructor(devtoolsService: DevtoolsService);
7
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
8
+ }
@@ -0,0 +1,71 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DevtoolsFilter = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const rxjs_1 = require("rxjs");
15
+ const devtools_service_1 = require("./devtools.service");
16
+ const TOOLBAR_SCRIPT = (dataUrl) => `
17
+ <script id="__devtools">
18
+ (function() {
19
+ var TOOLBAR_URL = '${dataUrl}';
20
+ var container = document.createElement('div');
21
+ container.id = 'nestjs-devtoolbar';
22
+ container.innerHTML = '<div style="position:fixed;bottom:0;left:0;z-index:99999;font-family:system-ui,sans-serif;font-size:12px;background:#1e1e2e;color:#cdd6f4;border-top:2px solid #89b4fa;padding:0;width:100%;display:flex;align-items:center;height:36px;box-shadow:0 -2px 10px rgba(0,0,0,0.3)">Loading NestJS Devtools...</div>';
23
+ document.body.appendChild(container);
24
+
25
+ fetch(TOOLBAR_URL)
26
+ .then(function(r) { return r.json(); })
27
+ .then(function(data) {
28
+ var html = '<div style="position:fixed;bottom:0;left:0;z-index:99999;font-family:system-ui,sans-serif;font-size:12px;background:#1e1e2e;color:#cdd6f4;border-top:2px solid #89b4fa;width:100%;box-shadow:0 -2px 10px rgba(0,0,0,0.3)">';
29
+ html += '<div style="display:flex;align-items:center;height:36px;padding:0 12px;gap:6px;overflow-x:auto;white-space:nowrap">';
30
+ html += '<span style="font-weight:700;color:#89b4fa;margin-right:8px">DEV</span>';
31
+ html += '<span style="background:#313244;padding:2px 8px;border-radius:4px;color:#a6e3a1">' + (data.request?.summary || 'N/A') + '</span>';
32
+ html += '<span style="background:#313244;padding:2px 8px;border-radius:4px;color:#f9e2af">' + (data.performance?.summary || '') + '</span>';
33
+ html += '<span style="background:#313244;padding:2px 8px;border-radius:4px;color:#89b4fa">' + (data.database?.summary || '') + '</span>';
34
+ html += '<span style="background:#313244;padding:2px 8px;border-radius:4px;color:#94e2d5">' + (data.routes?.summary || '') + '</span>';
35
+ html += '<span style="background:#313244;padding:2px 8px;border-radius:4px;color:#fab387">' + (data.logs?.summary || '') + '</span>';
36
+ html += '<span style="margin-left:auto;color:#6c7086;cursor:pointer" onclick="var d=document.getElementById(\\'nestjs-devtoolbar-detail\\');d.style.display=d.style.display===\\'none\\'?\\'flex\\':\\'none\\'">&#x25B2; Details</span>';
37
+ html += '</div>';
38
+
39
+ html += '<div id="nestjs-devtoolbar-detail" style="display:none;border-top:1px solid #313244;padding:12px;max-height:300px;overflow-y:auto;background:#181825;font-size:11px">';
40
+ html += '<pre style="margin:0;color:#cdd6f4;white-space:pre-wrap;font-family:monospace">' + JSON.stringify(data, null, 2) + '</pre>';
41
+ html += '</div>';
42
+
43
+ html += '</div>';
44
+ container.innerHTML = html;
45
+ })
46
+ .catch(function() {
47
+ container.innerHTML = '';
48
+ });
49
+ })();
50
+ </script>`;
51
+ let DevtoolsFilter = class DevtoolsFilter {
52
+ constructor(devtoolsService) {
53
+ this.devtoolsService = devtoolsService;
54
+ }
55
+ intercept(context, next) {
56
+ return next.handle().pipe((0, rxjs_1.map)((data) => {
57
+ const response = context.switchToHttp().getResponse();
58
+ const contentType = response.getHeader('content-type') ?? '';
59
+ if (typeof data === 'string' && contentType.includes('text/html')) {
60
+ return data.replace('</body>', TOOLBAR_SCRIPT('/__devtools/data') + '</body>');
61
+ }
62
+ return data;
63
+ }));
64
+ }
65
+ };
66
+ exports.DevtoolsFilter = DevtoolsFilter;
67
+ exports.DevtoolsFilter = DevtoolsFilter = __decorate([
68
+ (0, common_1.Injectable)(),
69
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
70
+ ], DevtoolsFilter);
71
+ //# sourceMappingURL=devtools.filter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.filter.js","sourceRoot":"","sources":["../devtools.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,+BAAuC;AACvC,yDAAqD;AAErD,MAAM,cAAc,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC;;;uBAGrB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA+BpB,CAAC;AAGJ,IAAM,cAAc,GAApB,MAAM,cAAc;IACzB,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAEjE,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC,CAAC,IAAI,EAAE,EAAE;YACX,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,CAAC;YACtD,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAE7D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;gBAClE,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC,CAAC;YACjF,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAjBY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,mBAAU,GAAE;qCAEmC,kCAAe;GADlD,cAAc,CAiB1B"}
@@ -0,0 +1,8 @@
1
+ import { NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
2
+ import { Observable } from 'rxjs';
3
+ import { DevtoolsService } from './devtools.service';
4
+ export declare class DevtoolsInterceptor implements NestInterceptor {
5
+ private readonly devtoolsService;
6
+ constructor(devtoolsService: DevtoolsService);
7
+ intercept(context: ExecutionContext, next: CallHandler): Observable<unknown>;
8
+ }
@@ -0,0 +1,72 @@
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
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.DevtoolsInterceptor = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const rxjs_1 = require("rxjs");
15
+ const uuid_1 = require("uuid");
16
+ const devtools_service_1 = require("./devtools.service");
17
+ let DevtoolsInterceptor = class DevtoolsInterceptor {
18
+ constructor(devtoolsService) {
19
+ this.devtoolsService = devtoolsService;
20
+ }
21
+ intercept(context, next) {
22
+ const request = context.switchToHttp().getRequest();
23
+ const response = context.switchToHttp().getResponse();
24
+ const startTime = process.hrtime.bigint();
25
+ const startMemory = process.memoryUsage().heapUsed;
26
+ const handler = context.getHandler();
27
+ const controller = context.getClass();
28
+ const debugInfo = {
29
+ id: (0, uuid_1.v4)(),
30
+ method: request.method,
31
+ path: request.path ?? request.url,
32
+ statusCode: 200,
33
+ duration: 0,
34
+ memory: 0,
35
+ timestamp: new Date(),
36
+ route: `${controller?.name ?? 'Unknown'}.${handler?.name ?? 'unknown'}`,
37
+ queries: [],
38
+ logs: [],
39
+ cacheHits: 0,
40
+ cacheMisses: 0,
41
+ };
42
+ this.devtoolsService.setCurrentRequest(debugInfo);
43
+ return next.handle().pipe((0, rxjs_1.tap)({
44
+ next: () => {
45
+ const endTime = process.hrtime.bigint();
46
+ const endMemory = process.memoryUsage().heapUsed;
47
+ debugInfo.duration = Number(endTime - startTime) / 1_000_000;
48
+ debugInfo.memory = Math.max(0, endMemory - startMemory);
49
+ debugInfo.statusCode = response.statusCode;
50
+ this.devtoolsService.finishRequest();
51
+ },
52
+ error: (error) => {
53
+ const endTime = process.hrtime.bigint();
54
+ const endMemory = process.memoryUsage().heapUsed;
55
+ debugInfo.duration = Number(endTime - startTime) / 1_000_000;
56
+ debugInfo.memory = Math.max(0, endMemory - startMemory);
57
+ debugInfo.statusCode = error instanceof common_1.HttpException ? error.getStatus() : 500;
58
+ debugInfo.exception = {
59
+ message: error.message,
60
+ stack: error.stack ?? '',
61
+ };
62
+ this.devtoolsService.finishRequest();
63
+ },
64
+ }));
65
+ }
66
+ };
67
+ exports.DevtoolsInterceptor = DevtoolsInterceptor;
68
+ exports.DevtoolsInterceptor = DevtoolsInterceptor = __decorate([
69
+ (0, common_1.Injectable)(),
70
+ __metadata("design:paramtypes", [devtools_service_1.DevtoolsService])
71
+ ], DevtoolsInterceptor);
72
+ //# sourceMappingURL=devtools.interceptor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.interceptor.js","sourceRoot":"","sources":["../devtools.interceptor.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAMwB;AACxB,+BAAuC;AACvC,+BAAkC;AAClC,yDAAqD;AAI9C,IAAM,mBAAmB,GAAzB,MAAM,mBAAmB;IAC9B,YAA6B,eAAgC;QAAhC,oBAAe,GAAf,eAAe,CAAiB;IAAG,CAAC;IAEjE,SAAS,CAAC,OAAyB,EAAE,IAAiB;QACpD,MAAM,OAAO,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,UAAU,EAAE,CAAC;QACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,WAAW,EAAE,CAAC;QACtD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC;QAEnD,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;QAEtC,MAAM,SAAS,GAAqB;YAClC,EAAE,EAAE,IAAA,SAAI,GAAE;YACV,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG;YACjC,UAAU,EAAE,GAAG;YACf,QAAQ,EAAE,CAAC;YACX,MAAM,EAAE,CAAC;YACT,SAAS,EAAE,IAAI,IAAI,EAAE;YACrB,KAAK,EAAE,GAAG,UAAU,EAAE,IAAI,IAAI,SAAS,IAAI,OAAO,EAAE,IAAI,IAAI,SAAS,EAAE;YACvE,OAAO,EAAE,EAAE;YACX,IAAI,EAAE,EAAE;YACR,SAAS,EAAE,CAAC;YACZ,WAAW,EAAE,CAAC;SACf,CAAC;QAEF,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC;QAElD,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CACvB,IAAA,UAAG,EAAC;YACF,IAAI,EAAE,GAAG,EAAE;gBACT,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC;gBACjD,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;gBAC7D,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;gBACxD,SAAS,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;gBAC3C,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;YACvC,CAAC;YACD,KAAK,EAAE,CAAC,KAAY,EAAE,EAAE;gBACtB,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACxC,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC;gBACjD,SAAS,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,GAAG,SAAS,CAAC,GAAG,SAAS,CAAC;gBAC7D,SAAS,CAAC,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC,CAAC;gBACxD,SAAS,CAAC,UAAU,GAAG,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;gBAChF,SAAS,CAAC,SAAS,GAAG;oBACpB,OAAO,EAAE,KAAK,CAAC,OAAO;oBACtB,KAAK,EAAE,KAAK,CAAC,KAAK,IAAI,EAAE;iBACzB,CAAC;gBACF,IAAI,CAAC,eAAe,CAAC,aAAa,EAAE,CAAC;YACvC,CAAC;SACF,CAAC,CACH,CAAC;IACJ,CAAC;CACF,CAAA;AAtDY,kDAAmB;8BAAnB,mBAAmB;IAD/B,IAAA,mBAAU,GAAE;qCAEmC,kCAAe;GADlD,mBAAmB,CAsD/B"}
@@ -0,0 +1,14 @@
1
+ import { DynamicModule, Type } from '@nestjs/common';
2
+ import { AbstractCollector } from './collectors/abstract.collector';
3
+ export declare const DEVOOLS_COLLECTORS_TOKEN = "DEVOOLS_COLLECTORS_TOKEN";
4
+ export interface DevtoolsModuleOptions {
5
+ enabled?: boolean;
6
+ position?: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
7
+ theme?: 'light' | 'dark';
8
+ maxHistory?: number;
9
+ collectors?: Type<AbstractCollector>[];
10
+ injectToolbar?: boolean;
11
+ }
12
+ export declare class DevtoolsModule {
13
+ static forRoot(options?: DevtoolsModuleOptions): DynamicModule;
14
+ }
@@ -0,0 +1,81 @@
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 DevtoolsModule_1;
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.DevtoolsModule = exports.DEVOOLS_COLLECTORS_TOKEN = void 0;
11
+ const common_1 = require("@nestjs/common");
12
+ const core_1 = require("@nestjs/core");
13
+ const devtools_service_1 = require("./devtools.service");
14
+ const devtools_interceptor_1 = require("./devtools.interceptor");
15
+ const devtools_filter_1 = require("./devtools.filter");
16
+ const devtools_controller_1 = require("./devtools.controller");
17
+ const collectors_1 = require("./collectors");
18
+ exports.DEVOOLS_COLLECTORS_TOKEN = 'DEVOOLS_COLLECTORS_TOKEN';
19
+ const DEFAULT_COLLECTORS = [
20
+ collectors_1.RequestCollector,
21
+ collectors_1.PerformanceCollector,
22
+ collectors_1.DatabaseCollector,
23
+ collectors_1.RouteCollector,
24
+ collectors_1.LogCollector,
25
+ ];
26
+ const SHARED_PROVIDERS = [
27
+ devtools_service_1.DevtoolsService,
28
+ collectors_1.RequestCollector,
29
+ collectors_1.PerformanceCollector,
30
+ collectors_1.DatabaseCollector,
31
+ collectors_1.RouteCollector,
32
+ collectors_1.LogCollector,
33
+ ];
34
+ let DevtoolsModule = DevtoolsModule_1 = class DevtoolsModule {
35
+ static forRoot(options = {}) {
36
+ const { enabled = process.env.NODE_ENV !== 'production', maxHistory = 50, collectors = DEFAULT_COLLECTORS, injectToolbar = true, } = options;
37
+ if (!enabled) {
38
+ return {
39
+ module: DevtoolsModule_1,
40
+ providers: [
41
+ {
42
+ provide: devtools_service_1.DevtoolsService,
43
+ useValue: null,
44
+ },
45
+ ],
46
+ exports: [],
47
+ };
48
+ }
49
+ const allCollectors = [...new Set([...DEFAULT_COLLECTORS, ...collectors])];
50
+ const collectorProvider = {
51
+ provide: exports.DEVOOLS_COLLECTORS_TOKEN,
52
+ useFactory: (...instances) => instances,
53
+ inject: allCollectors,
54
+ };
55
+ const providers = [
56
+ ...SHARED_PROVIDERS,
57
+ collectorProvider,
58
+ {
59
+ provide: core_1.APP_INTERCEPTOR,
60
+ useClass: devtools_interceptor_1.DevtoolsInterceptor,
61
+ },
62
+ ];
63
+ if (injectToolbar) {
64
+ providers.push({
65
+ provide: core_1.APP_INTERCEPTOR,
66
+ useClass: devtools_filter_1.DevtoolsFilter,
67
+ });
68
+ }
69
+ return {
70
+ module: DevtoolsModule_1,
71
+ controllers: [devtools_controller_1.DevtoolsController],
72
+ providers,
73
+ exports: [devtools_service_1.DevtoolsService, exports.DEVOOLS_COLLECTORS_TOKEN, ...SHARED_PROVIDERS],
74
+ };
75
+ }
76
+ };
77
+ exports.DevtoolsModule = DevtoolsModule;
78
+ exports.DevtoolsModule = DevtoolsModule = DevtoolsModule_1 = __decorate([
79
+ (0, common_1.Module)({})
80
+ ], DevtoolsModule);
81
+ //# sourceMappingURL=devtools.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.module.js","sourceRoot":"","sources":["../devtools.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAuE;AACvE,uCAA+C;AAC/C,yDAAqD;AACrD,iEAA6D;AAC7D,uDAAmD;AACnD,+DAA2D;AAE3D,6CAMsB;AAET,QAAA,wBAAwB,GAAG,0BAA0B,CAAC;AAWnE,MAAM,kBAAkB,GAA8B;IACpD,6BAAgB;IAChB,iCAAoB;IACpB,8BAAiB;IACjB,2BAAc;IACd,yBAAY;CACb,CAAC;AAEF,MAAM,gBAAgB,GAAe;IACnC,kCAAe;IACf,6BAAgB;IAChB,iCAAoB;IACpB,8BAAiB;IACjB,2BAAc;IACd,yBAAY;CACb,CAAC;AAGK,IAAM,cAAc,sBAApB,MAAM,cAAc;IACzB,MAAM,CAAC,OAAO,CAAC,UAAiC,EAAE;QAChD,MAAM,EACJ,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,EAC/C,UAAU,GAAG,EAAE,EACf,UAAU,GAAG,kBAAkB,EAC/B,aAAa,GAAG,IAAI,GACrB,GAAG,OAAO,CAAC;QAEZ,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO;gBACL,MAAM,EAAE,gBAAc;gBACtB,SAAS,EAAE;oBACT;wBACE,OAAO,EAAE,kCAAe;wBACxB,QAAQ,EAAE,IAAI;qBACf;iBACF;gBACD,OAAO,EAAE,EAAE;aACZ,CAAC;QACJ,CAAC;QAED,MAAM,aAAa,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,kBAAkB,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;QAE3E,MAAM,iBAAiB,GAAa;YAClC,OAAO,EAAE,gCAAwB;YACjC,UAAU,EAAE,CAAC,GAAG,SAA8B,EAAE,EAAE,CAAC,SAAS;YAC5D,MAAM,EAAE,aAAa;SACtB,CAAC;QAEF,MAAM,SAAS,GAAe;YAC5B,GAAG,gBAAgB;YACnB,iBAAiB;YACjB;gBACE,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,0CAAmB;aAC9B;SACF,CAAC;QAEF,IAAI,aAAa,EAAE,CAAC;YAClB,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO,EAAE,sBAAe;gBACxB,QAAQ,EAAE,gCAAc;aACzB,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,MAAM,EAAE,gBAAc;YACtB,WAAW,EAAE,CAAC,wCAAkB,CAAC;YACjC,SAAS;YACT,OAAO,EAAE,CAAC,kCAAe,EAAE,gCAAwB,EAAE,GAAG,gBAAgB,CAAC;SAC1E,CAAC;IACJ,CAAC;CACF,CAAA;AArDY,wCAAc;yBAAd,cAAc;IAD1B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,cAAc,CAqD1B"}
@@ -0,0 +1,28 @@
1
+ import { RequestDebugInfo } from './interfaces';
2
+ export declare class DevtoolsService {
3
+ private readonly history;
4
+ private readonly maxHistory;
5
+ constructor(maxHistory?: number);
6
+ private currentRequest;
7
+ getCurrentRequest(): RequestDebugInfo | null;
8
+ setCurrentRequest(info: RequestDebugInfo): void;
9
+ addQuery(sql: string, duration: number): void;
10
+ addLog(message: string, level: string): void;
11
+ recordCacheHit(): void;
12
+ recordCacheMiss(): void;
13
+ setException(exception: {
14
+ message: string;
15
+ stack: string;
16
+ }): void;
17
+ finishRequest(): void;
18
+ getLastRequest(): RequestDebugInfo | null;
19
+ getHistory(): RequestDebugInfo[];
20
+ getHistorySummary(): {
21
+ id: string;
22
+ method: string;
23
+ path: string;
24
+ statusCode: number;
25
+ duration: number;
26
+ timestamp: Date;
27
+ }[];
28
+ }
@@ -0,0 +1,86 @@
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 __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.DevtoolsService = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ let DevtoolsService = class DevtoolsService {
18
+ constructor(maxHistory = 50) {
19
+ this.history = [];
20
+ this.currentRequest = null;
21
+ this.maxHistory = maxHistory;
22
+ }
23
+ getCurrentRequest() {
24
+ return this.currentRequest;
25
+ }
26
+ setCurrentRequest(info) {
27
+ this.currentRequest = info;
28
+ }
29
+ addQuery(sql, duration) {
30
+ if (this.currentRequest) {
31
+ this.currentRequest.queries.push({ sql, duration });
32
+ }
33
+ }
34
+ addLog(message, level) {
35
+ if (this.currentRequest) {
36
+ this.currentRequest.logs.push({ message, level, timestamp: new Date() });
37
+ }
38
+ }
39
+ recordCacheHit() {
40
+ if (this.currentRequest) {
41
+ this.currentRequest.cacheHits++;
42
+ }
43
+ }
44
+ recordCacheMiss() {
45
+ if (this.currentRequest) {
46
+ this.currentRequest.cacheMisses++;
47
+ }
48
+ }
49
+ setException(exception) {
50
+ if (this.currentRequest) {
51
+ this.currentRequest.exception = exception;
52
+ }
53
+ }
54
+ finishRequest() {
55
+ if (this.currentRequest) {
56
+ this.history.unshift(this.currentRequest);
57
+ if (this.history.length > this.maxHistory) {
58
+ this.history.pop();
59
+ }
60
+ this.currentRequest = null;
61
+ }
62
+ }
63
+ getLastRequest() {
64
+ return this.history[0] ?? null;
65
+ }
66
+ getHistory() {
67
+ return this.history;
68
+ }
69
+ getHistorySummary() {
70
+ return this.history.map((r) => ({
71
+ id: r.id,
72
+ method: r.method,
73
+ path: r.path,
74
+ statusCode: r.statusCode,
75
+ duration: r.duration,
76
+ timestamp: r.timestamp,
77
+ }));
78
+ }
79
+ };
80
+ exports.DevtoolsService = DevtoolsService;
81
+ exports.DevtoolsService = DevtoolsService = __decorate([
82
+ (0, common_1.Injectable)(),
83
+ __param(0, (0, common_1.Optional)()),
84
+ __metadata("design:paramtypes", [Object])
85
+ ], DevtoolsService);
86
+ //# sourceMappingURL=devtools.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools.service.js","sourceRoot":"","sources":["../devtools.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAsD;AAI/C,IAAM,eAAe,GAArB,MAAM,eAAe;IAI1B,YAAwB,aAAa,EAAE;QAHtB,YAAO,GAAuB,EAAE,CAAC;QAO1C,mBAAc,GAA4B,IAAI,CAAC;QAHrD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAID,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED,iBAAiB,CAAC,IAAsB;QACtC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,QAAgB;QACpC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,CAAC;QACtD,CAAC;IACH,CAAC;IAED,MAAM,CAAC,OAAe,EAAE,KAAa;QACnC,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,SAAS,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IAED,eAAe;QACb,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,WAAW,EAAE,CAAC;QACpC,CAAC;IACH,CAAC;IAED,YAAY,CAAC,SAA6C;QACxD,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,cAAc,CAAC,SAAS,GAAG,SAAS,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,aAAa;QACX,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YAC1C,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC1C,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;YACrB,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,cAAc;QACZ,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACjC,CAAC;IAED,UAAU;QACR,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC9B,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,MAAM,EAAE,CAAC,CAAC,MAAM;YAChB,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,UAAU,EAAE,CAAC,CAAC,UAAU;YACxB,QAAQ,EAAE,CAAC,CAAC,QAAQ;YACpB,SAAS,EAAE,CAAC,CAAC,SAAS;SACvB,CAAC,CAAC,CAAC;IACN,CAAC;CACF,CAAA;AA5EY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,mBAAU,GAAE;IAKE,WAAA,IAAA,iBAAQ,GAAE,CAAA;;GAJZ,eAAe,CA4E3B"}
@@ -0,0 +1,7 @@
1
+ export { DevtoolsModule } from './devtools.module';
2
+ export type { DevtoolsModuleOptions } from './devtools.module';
3
+ export { DevtoolsService } from './devtools.service';
4
+ export { DevtoolsInterceptor } from './devtools.interceptor';
5
+ export { AbstractCollector } from './collectors';
6
+ export { RequestCollector, PerformanceCollector, DatabaseCollector, RouteCollector, LogCollector } from './collectors';
7
+ export type { DevtoolsData, ToolbarConfig, RequestDebugInfo } from './interfaces';
package/dist/index.js ADDED
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LogCollector = exports.RouteCollector = exports.DatabaseCollector = exports.PerformanceCollector = exports.RequestCollector = exports.AbstractCollector = exports.DevtoolsInterceptor = exports.DevtoolsService = exports.DevtoolsModule = void 0;
4
+ var devtools_module_1 = require("./devtools.module");
5
+ Object.defineProperty(exports, "DevtoolsModule", { enumerable: true, get: function () { return devtools_module_1.DevtoolsModule; } });
6
+ var devtools_service_1 = require("./devtools.service");
7
+ Object.defineProperty(exports, "DevtoolsService", { enumerable: true, get: function () { return devtools_service_1.DevtoolsService; } });
8
+ var devtools_interceptor_1 = require("./devtools.interceptor");
9
+ Object.defineProperty(exports, "DevtoolsInterceptor", { enumerable: true, get: function () { return devtools_interceptor_1.DevtoolsInterceptor; } });
10
+ var collectors_1 = require("./collectors");
11
+ Object.defineProperty(exports, "AbstractCollector", { enumerable: true, get: function () { return collectors_1.AbstractCollector; } });
12
+ var collectors_2 = require("./collectors");
13
+ Object.defineProperty(exports, "RequestCollector", { enumerable: true, get: function () { return collectors_2.RequestCollector; } });
14
+ Object.defineProperty(exports, "PerformanceCollector", { enumerable: true, get: function () { return collectors_2.PerformanceCollector; } });
15
+ Object.defineProperty(exports, "DatabaseCollector", { enumerable: true, get: function () { return collectors_2.DatabaseCollector; } });
16
+ Object.defineProperty(exports, "RouteCollector", { enumerable: true, get: function () { return collectors_2.RouteCollector; } });
17
+ Object.defineProperty(exports, "LogCollector", { enumerable: true, get: function () { return collectors_2.LogCollector; } });
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;AAAA,qDAAmD;AAA1C,iHAAA,cAAc,OAAA;AAEvB,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,+DAA6D;AAApD,2HAAA,mBAAmB,OAAA;AAC5B,2CAAiD;AAAxC,+GAAA,iBAAiB,OAAA;AAC1B,2CAAuH;AAA9G,8GAAA,gBAAgB,OAAA;AAAE,kHAAA,oBAAoB,OAAA;AAAE,+GAAA,iBAAiB,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,0GAAA,YAAY,OAAA"}
@@ -0,0 +1,64 @@
1
+ import { InjectionToken } from '@nestjs/common';
2
+ export interface DevtoolsData {
3
+ label: string;
4
+ icon: string;
5
+ summary: string;
6
+ details: Record<string, unknown>;
7
+ }
8
+ export interface ToolbarConfig {
9
+ enabled: boolean;
10
+ position: 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right';
11
+ theme: 'light' | 'dark';
12
+ collectors?: InjectionToken[];
13
+ maxHistory?: number;
14
+ }
15
+ export interface RequestDebugInfo {
16
+ id: string;
17
+ method: string;
18
+ path: string;
19
+ statusCode: number;
20
+ duration: number;
21
+ memory: number;
22
+ timestamp: Date;
23
+ route: string;
24
+ queries: {
25
+ sql: string;
26
+ duration: number;
27
+ }[];
28
+ logs: {
29
+ message: string;
30
+ level: string;
31
+ timestamp: Date;
32
+ }[];
33
+ cacheHits: number;
34
+ cacheMisses: number;
35
+ exception?: {
36
+ message: string;
37
+ stack: string;
38
+ };
39
+ }
40
+ export interface RequestCollectorData {
41
+ method: string;
42
+ path: string;
43
+ statusCode: number;
44
+ headers: Record<string, string>;
45
+ query: Record<string, unknown>;
46
+ params: Record<string, unknown>;
47
+ ip: string;
48
+ }
49
+ export interface PerformanceCollectorData {
50
+ duration: number;
51
+ memory: number;
52
+ memoryPeak: number;
53
+ cpuUsage?: NodeJS.CpuUsage;
54
+ }
55
+ export interface QueryCollectorData {
56
+ queries: {
57
+ sql: string;
58
+ params: unknown[];
59
+ duration: number;
60
+ connection: string;
61
+ }[];
62
+ totalQueries: number;
63
+ totalDuration: number;
64
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=devtools-collector.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"devtools-collector.interface.js","sourceRoot":"","sources":["../../interfaces/devtools-collector.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ export * from './devtools-collector.interface';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./devtools-collector.interface"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../interfaces/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iEAA+C"}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "nestjs-devtools",
3
+ "version": "1.0.0",
4
+ "description": "Symfony-style debug toolbar for NestJS applications",
5
+ "keywords": [
6
+ "nestjs",
7
+ "devtools",
8
+ "debug",
9
+ "toolbar",
10
+ "debug-bar",
11
+ "symfony",
12
+ "profiler",
13
+ "development"
14
+ ],
15
+ "homepage": "https://github.com/nestjs-devtools/nestjs-devtools#readme",
16
+ "bugs": {
17
+ "url": "https://github.com/nestjs-devtools/nestjs-devtools/issues"
18
+ },
19
+ "license": "MIT",
20
+ "author": "NestJS Devtools",
21
+ "main": "dist/index.js",
22
+ "types": "dist/index.d.ts",
23
+ "files": [
24
+ "dist",
25
+ "README.md"
26
+ ],
27
+ "scripts": {
28
+ "build": "tsc",
29
+ "prepublishOnly": "npm run build",
30
+ "watch": "tsc --watch"
31
+ },
32
+ "dependencies": {
33
+ "uuid": "^9.0.0"
34
+ },
35
+ "peerDependencies": {
36
+ "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
37
+ "@nestjs/core": "^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0",
38
+ "rxjs": "^7.0.0",
39
+ "reflect-metadata": "^0.1.13"
40
+ },
41
+ "devDependencies": {
42
+ "@nestjs/common": "^11.0.0",
43
+ "@nestjs/core": "^11.0.0",
44
+ "@types/node": "^22.0.0",
45
+ "@types/uuid": "^9.0.0",
46
+ "reflect-metadata": "^0.1.13",
47
+ "rxjs": "^7.8.0",
48
+ "typescript": "^5.5.0"
49
+ },
50
+ "publishConfig": {
51
+ "access": "public"
52
+ }
53
+ }