nestjs-devtools 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,9 +15,7 @@ Symfony-style debug toolbar for NestJS applications.
15
15
  ## Installation
16
16
 
17
17
  ```bash
18
- npm install @nestjs/devtools
19
- # or
20
- yarn add @nestjs/devtools
18
+ npm install nestjs-devtools
21
19
  ```
22
20
 
23
21
  ## Usage
@@ -26,7 +24,7 @@ Import in your root `AppModule`:
26
24
 
27
25
  ```typescript
28
26
  import { Module } from '@nestjs/common';
29
- import { DevtoolsModule } from '@nestjs/devtools';
27
+ import { DevtoolsModule } from 'nestjs-devtools';
30
28
 
31
29
  @Module({
32
30
  imports: [
@@ -55,7 +53,7 @@ export class AppModule {}
55
53
 
56
54
  ```typescript
57
55
  import { Injectable } from '@nestjs/common';
58
- import { AbstractCollector, DevtoolsData } from '@nestjs/devtools';
56
+ import { AbstractCollector, DevtoolsData } from 'nestjs-devtools';
59
57
 
60
58
  @Injectable()
61
59
  export class CustomCollector extends AbstractCollector {
@@ -75,6 +73,8 @@ export class CustomCollector extends AbstractCollector {
75
73
  Then pass it to `forRoot`:
76
74
 
77
75
  ```typescript
76
+ import { DevtoolsModule } from 'nestjs-devtools';
77
+
78
78
  DevtoolsModule.forRoot({ collectors: [CustomCollector] })
79
79
  ```
80
80
 
@@ -13,41 +13,7 @@ exports.DevtoolsFilter = void 0;
13
13
  const common_1 = require("@nestjs/common");
14
14
  const rxjs_1 = require("rxjs");
15
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>`;
16
+ const template_1 = require("./toolbar/template");
51
17
  let DevtoolsFilter = class DevtoolsFilter {
52
18
  constructor(devtoolsService) {
53
19
  this.devtoolsService = devtoolsService;
@@ -57,7 +23,7 @@ let DevtoolsFilter = class DevtoolsFilter {
57
23
  const response = context.switchToHttp().getResponse();
58
24
  const contentType = response.getHeader('content-type') ?? '';
59
25
  if (typeof data === 'string' && contentType.includes('text/html')) {
60
- return data.replace('</body>', TOOLBAR_SCRIPT('/__devtools/data') + '</body>');
26
+ return data.replace('</body>', (0, template_1.TOOLBAR_TEMPLATE)('/__devtools/data') + '</body>');
61
27
  }
62
28
  return data;
63
29
  }));
@@ -1 +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"}
1
+ {"version":3,"file":"devtools.filter.js","sourceRoot":"","sources":["../devtools.filter.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAKwB;AACxB,+BAAuC;AACvC,yDAAqD;AACrD,iDAAsD;AAG/C,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,IAAA,2BAAgB,EAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC,CAAC;YACnF,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 @@
1
+ export declare const TOOLBAR_TEMPLATE: (dataUrl: string) => string;
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOOLBAR_TEMPLATE = void 0;
4
+ const TOOLBAR_TEMPLATE = (dataUrl) => {
5
+ const id = '__nestDevtools';
6
+ const uid = Math.random().toString(36).slice(2, 8);
7
+ return `<script id="${id}">
8
+ (function(){
9
+ var D=document, B=D.body, C='__nestDt'+'${uid}';
10
+ var c=D.createElement('div'); c.id=C;
11
+ c.innerHTML='<div style="position:fixed;bottom:0;left:0;z-index:99999;font-family:-apple-system,BlinkMacSystemFont,\'Segoe UI\',Roboto,sans-serif;font-size:12px;background:#1f2937;color:#f3f4f6;border-top:2px solid #3b82f6;width:100%;box-shadow:0 -4px 12px rgba(0,0,0,0.35)"><div style="display:flex;align-items:center;height:34px;padding:0 8px;gap:4px;overflow-x:auto;white-space:nowrap;scrollbar-width:none"><span style="font-weight:800;font-size:13px;color:#60a5fa;padding:0 10px 0 4px;letter-spacing:-0.5px">NDev</span><div id="'+C+'-bar"></div><span id="'+C+'-toggle" style="margin-left:auto;color:#6b7280;cursor:pointer;padding:4px 8px;font-size:14px">&#x2039;</span></div><div id="'+C+'-panel" style="display:none;border-top:1px solid #374151;background:#111827;font-size:12px;line-height:1.5"></div></div>';
12
+ B.appendChild(c);
13
+
14
+ var lastActive=null;
15
+ function renderPanel(name, detail) {
16
+ var p=D.getElementById(C+'-panel');
17
+ if (lastActive===name) { p.style.display='none'; lastActive=null; return; }
18
+ lastActive=name;
19
+ var h='<div style="padding:12px 16px;max-height:360px;overflow-y:auto">';
20
+ h+='<div style="display:flex;align-items:center;margin-bottom:10px;gap:8px">';
21
+ h+='<span style="font-weight:700;font-size:13px">'+detail.label+'</span>';
22
+ h+='<span style="color:#9ca3af;font-size:11px">'+detail.summary+'</span>';
23
+ h+='<span style="margin-left:auto;cursor:pointer;color:#6b7280;font-size:16px" onclick="document.getElementById(\''+C+'-panel\').style.display=\'none\';lastActive=null">\u00d7</span>';
24
+ h+='</div>';
25
+ h+='<table style="width:100%;border-collapse:collapse">';
26
+ for (var k in detail.details) {
27
+ var v=detail.details[k];
28
+ if (k==='queries' && Array.isArray(v)) {
29
+ for (var i=0;i<v.length;i++) {
30
+ h+='<tr><td style="padding:4px 8px;color:#9ca3af;border-bottom:1px solid #1f2937;vertical-align:top;width:80px">#'+(i+1)+'</td><td style="padding:4px 8px;border-bottom:1px solid #1f2937;font-family:monospace;font-size:11px;word-break:break-all">'+escapeHtml(v[i].sql||'')+'</td><td style="padding:4px 8px;border-bottom:1px solid #1f2937;text-align:right;color:#fbbf24">'+escapeHtml(v[i].duration||'')+'</td></tr>';
31
+ }
32
+ continue;
33
+ }
34
+ if (k==='entries' && Array.isArray(v)) {
35
+ for (var i=0;i<v.length;i++) {
36
+ var e=v[i];
37
+ var lc=e.level==='error'?'#ef4444':e.level==='warn'?'#f59e0b':'#9ca3af';
38
+ h+='<tr><td style="padding:3px 8px;color:'+lc+';border-bottom:1px solid #1f2937;width:60px;text-transform:uppercase;font-weight:600;font-size:10px">'+escapeHtml(e.level||'')+'</td><td style="padding:3px 8px;border-bottom:1px solid #1f2937;word-break:break-all">'+escapeHtml(e.message||'')+'</td></tr>';
39
+ }
40
+ continue;
41
+ }
42
+ if (k==='grouped' && Array.isArray(v)) {
43
+ for (var i=0;i<v.length;i++) {
44
+ var g=v[i];
45
+ h+='<tr><td colspan="3" style="padding:6px 8px;color:#60a5fa;font-weight:600;border-bottom:1px solid #1f2937">'+escapeHtml(g.method||'')+' ('+(g.count||0)+')</td></tr>';
46
+ if (g.routes) {
47
+ for (var j=0;j<g.routes.length;j++) {
48
+ h+='<tr><td style="padding:2px 8px 2px 24px;border-bottom:1px solid #1f2937;font-family:monospace;font-size:11px" colspan="3">'+escapeHtml(g.routes[j].path||'')+' <span style="color:#6b7280">('+escapeHtml(g.routes[j].controller||'')+')</span></td></tr>';
49
+ }
50
+ }
51
+ }
52
+ continue;
53
+ }
54
+ h+='<tr><td style="padding:4px 8px;color:#9ca3af;border-bottom:1px solid #1f2937;width:120px;vertical-align:top">'+escapeHtml(k)+'</td><td style="padding:4px 8px;border-bottom:1px solid #1f2937;word-break:break-all">'+escapeHtml(String(v))+'</td></tr>';
55
+ }
56
+ h+='</table></div>';
57
+ p.innerHTML=h;
58
+ p.style.display='block';
59
+ D.getElementById(C+'-toggle').innerHTML='&#x203a;';
60
+ }
61
+
62
+ function escapeHtml(s) {
63
+ if (s==null) return '';
64
+ return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;');
65
+ }
66
+
67
+ fetch('${dataUrl}').then(function(r){return r.json()}).then(function(d){
68
+ var bar=D.getElementById(C+'-bar');
69
+ var panels=[];
70
+ if(d.request) panels.push(d.request);
71
+ if(d.performance) panels.push(d.performance);
72
+ if(d.database) panels.push(d.database);
73
+ if(d.routes) panels.push(d.routes);
74
+ if(d.logs) panels.push(d.logs);
75
+ for(var k in d){if(panels.indexOf(d[k])===-1&&d[k]&&d[k].label)panels.push(d[k]);}
76
+ var colors=['#a6e3a1','#f9e2af','#89b4fa','#94e2d5','#fab387','#cba6f7','#f38ba8','#a6e3a1'];
77
+ var icons={request:'\u{1F310}',performance:'\u26A1',database:'\u{1F5C4}\uFE0F',routes:'\u{1F4CB}',logs:'\u{1F4DD}','default':'\u{1F527}'};
78
+ panels.forEach(function(p,i){
79
+ var ic=icons[p.label.toLowerCase()]||icons['default'];
80
+ var btn=D.createElement('span');
81
+ btn.style.cssText='display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:4px;cursor:pointer;color:#d1d5db;background:#374151;margin:0 2px;transition:background .15s';
82
+ btn.innerHTML=ic+' '+escapeHtml(p.summary);
83
+ btn.onmouseenter=function(){this.style.background='#4b5563'};
84
+ btn.onmouseleave=function(){this.style.background='#374151'};
85
+ btn.onclick=function(n){return function(){renderPanel(n,d[n]||d[Object.keys(d).filter(function(k){return d[k]===p})[0]])}}(Object.keys(d).filter(function(k){return d[k]===p})[0]);
86
+ bar.appendChild(btn);
87
+ });
88
+ D.getElementById(C+'-toggle').onclick=function(){
89
+ var p=D.getElementById(C+'-panel');
90
+ p.style.display=p.style.display==='none'?'block':'none';
91
+ this.innerHTML=p.style.display==='block'?'\u203A':'\u2039';
92
+ };
93
+ }).catch(function(){});
94
+ })();
95
+ </script>`;
96
+ };
97
+ exports.TOOLBAR_TEMPLATE = TOOLBAR_TEMPLATE;
98
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../toolbar/template.ts"],"names":[],"mappings":";;;AAAO,MAAM,gBAAgB,GAAG,CAAC,OAAe,EAAE,EAAE;IAClD,MAAM,EAAE,GAAG,gBAAgB,CAAC;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAEnD,OAAO,eAAe,EAAE;;4CAEkB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA0DpC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;UA4BR,CAAC;AACX,CAAC,CAAC;AA7FW,QAAA,gBAAgB,oBA6F3B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nestjs-devtools",
3
- "version": "1.0.0",
3
+ "version": "1.1.0",
4
4
  "description": "Symfony-style debug toolbar for NestJS applications",
5
5
  "keywords": [
6
6
  "nestjs",