nestjs-devtools 1.5.4 → 1.5.6
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/dist/devtools.controller.js +2 -2
- package/dist/devtools.controller.js.map +1 -1
- package/dist/devtools.service.d.ts +2 -1
- package/dist/devtools.service.js +69 -0
- package/dist/devtools.service.js.map +1 -1
- package/dist/toolbar/profiler.js +138 -59
- package/dist/toolbar/profiler.js.map +1 -1
- package/package.json +1 -1
|
@@ -48,8 +48,8 @@ let DevtoolsController = class DevtoolsController {
|
|
|
48
48
|
res.send(this.devtoolsService.getHistorySummary());
|
|
49
49
|
}
|
|
50
50
|
getRequestDetail(id, res) {
|
|
51
|
-
const
|
|
52
|
-
res.send(
|
|
51
|
+
const panels = this.devtoolsService.getRequestPanels(id);
|
|
52
|
+
res.send(panels ?? null);
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
exports.DevtoolsController = DevtoolsController;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.controller.js","sourceRoot":"","sources":["../devtools.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA+E;AAC/E,yDAAqD;AAErD,6DAAwF;AACxF,iDAAuE;AAIhE,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAC7B,YACmB,eAAgC,EAGhC,aAAkC,EAAE,EAEpC,cAA0D;QAL1D,oBAAe,GAAf,eAAe,CAAiB;QAGhC,eAAU,GAAV,UAAU,CAA0B;QAEpC,mBAAc,GAAd,cAAc,CAA4C;IAC1E,CAAC;IAGJ,WAAW,CAAQ,GAAQ;QACzB,IAAI,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAAC,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,IAAA,wBAAa,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/C,CAAC;IAGD,cAAc,CAAQ,GAAQ;QAC5B,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,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;IAGD,UAAU,CAAQ,GAAQ;QACxB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACrD,CAAC;IAGD,gBAAgB,CAAc,EAAU,EAAS,GAAQ;QACvD,MAAM,
|
|
1
|
+
{"version":3,"file":"devtools.controller.js","sourceRoot":"","sources":["../devtools.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAA+E;AAC/E,yDAAqD;AAErD,6DAAwF;AACxF,iDAAuE;AAIhE,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAC7B,YACmB,eAAgC,EAGhC,aAAkC,EAAE,EAEpC,cAA0D;QAL1D,oBAAe,GAAf,eAAe,CAAiB;QAGhC,eAAU,GAAV,UAAU,CAA0B;QAEpC,mBAAc,GAAd,cAAc,CAA4C;IAC1E,CAAC;IAGJ,WAAW,CAAQ,GAAQ;QACzB,IAAI,CAAC;YAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,WAAW,CAAC,CAAC;QAAC,CAAC;QACjF,GAAG,CAAC,IAAI,CAAC,IAAA,wBAAa,EAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC;IAC/C,CAAC;IAGD,cAAc,CAAQ,GAAQ;QAC5B,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,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACnB,CAAC;IAGD,UAAU,CAAQ,GAAQ;QACxB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACrD,CAAC;IAGD,gBAAgB,CAAc,EAAU,EAAS,GAAQ;QACvD,MAAM,MAAM,GAAG,IAAI,CAAC,eAAe,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACzD,GAAG,CAAC,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC;IAC3B,CAAC;CACF,CAAA;AAvCY,gDAAkB;AAW7B;IADC,IAAA,YAAG,GAAE;IACO,WAAA,IAAA,YAAG,GAAE,CAAA;;;;qDAGjB;AAGD;IADC,IAAA,YAAG,EAAC,MAAM,CAAC;IACI,WAAA,IAAA,YAAG,GAAE,CAAA;;;;wDAUpB;AAGD;IADC,IAAA,YAAG,EAAC,SAAS,CAAC;IACH,WAAA,IAAA,YAAG,GAAE,CAAA;;;;oDAEhB;AAGD;IADC,IAAA,YAAG,EAAC,aAAa,CAAC;IACD,WAAA,IAAA,cAAK,EAAC,IAAI,CAAC,CAAA;IAAc,WAAA,IAAA,YAAG,GAAE,CAAA;;;;0DAG/C;6BAtCU,kBAAkB;IAD9B,IAAA,mBAAU,EAAC,YAAY,CAAC;IAIpB,WAAA,IAAA,iBAAQ,GAAE,CAAA;IACV,WAAA,IAAA,eAAM,EAAC,8CAAyB,CAAC,CAAA;IAEjC,WAAA,IAAA,eAAM,EAAC,0CAAqB,CAAC,CAAA;qCAJI,kCAAe;GAFxC,kBAAkB,CAuC9B"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestDebugInfo } from './interfaces';
|
|
1
|
+
import { RequestDebugInfo, DevtoolsData } from './interfaces';
|
|
2
2
|
export declare class DevtoolsService {
|
|
3
3
|
private readonly history;
|
|
4
4
|
private readonly maxHistory;
|
|
@@ -25,4 +25,5 @@ export declare class DevtoolsService {
|
|
|
25
25
|
duration: number;
|
|
26
26
|
timestamp: Date;
|
|
27
27
|
}[];
|
|
28
|
+
getRequestPanels(id: string): Record<string, DevtoolsData> | null;
|
|
28
29
|
}
|
package/dist/devtools.service.js
CHANGED
|
@@ -73,6 +73,75 @@ let DevtoolsService = class DevtoolsService {
|
|
|
73
73
|
timestamp: r.timestamp,
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
76
|
+
getRequestPanels(id) {
|
|
77
|
+
const req = this.history.find((r) => r.id === id);
|
|
78
|
+
if (!req)
|
|
79
|
+
return null;
|
|
80
|
+
const panels = {};
|
|
81
|
+
panels.request = {
|
|
82
|
+
label: 'Request',
|
|
83
|
+
icon: '🌐',
|
|
84
|
+
summary: `${req.method} ${req.path} → ${req.statusCode}`,
|
|
85
|
+
details: {
|
|
86
|
+
method: req.method,
|
|
87
|
+
path: req.path,
|
|
88
|
+
status: req.statusCode,
|
|
89
|
+
duration: `${req.duration.toFixed(2)} ms`,
|
|
90
|
+
memory: `${(req.memory / 1024 / 1024).toFixed(2)} MB`,
|
|
91
|
+
timestamp: req.timestamp.toISOString(),
|
|
92
|
+
route: req.route,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
panels.performance = {
|
|
96
|
+
label: 'Performance',
|
|
97
|
+
icon: '⚡',
|
|
98
|
+
summary: `${req.duration.toFixed(1)} ms, ${(req.memory / 1024 / 1024).toFixed(1)} MB`,
|
|
99
|
+
details: {
|
|
100
|
+
duration: `${req.duration.toFixed(2)} ms`,
|
|
101
|
+
peakMemory: `${(req.memory / 1024 / 1024).toFixed(2)} MB`,
|
|
102
|
+
queries: req.queries.length,
|
|
103
|
+
queryTime: `${req.queries.reduce((a, q) => a + q.duration, 0).toFixed(2)} ms`,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const totalQueryDuration = req.queries.reduce((a, q) => a + q.duration, 0);
|
|
107
|
+
panels.database = {
|
|
108
|
+
label: 'Database',
|
|
109
|
+
icon: '🗄️',
|
|
110
|
+
summary: `${req.queries.length} queries in ${totalQueryDuration.toFixed(1)} ms`,
|
|
111
|
+
details: {
|
|
112
|
+
totalQueries: req.queries.length,
|
|
113
|
+
totalTime: `${totalQueryDuration.toFixed(2)} ms`,
|
|
114
|
+
queries: req.queries.map((q) => ({
|
|
115
|
+
sql: q.sql,
|
|
116
|
+
duration: `${q.duration.toFixed(2)} ms`,
|
|
117
|
+
})),
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
const errors = req.logs.filter((l) => l.level === 'error');
|
|
121
|
+
const warnings = req.logs.filter((l) => l.level === 'warn');
|
|
122
|
+
const logsDetails = {
|
|
123
|
+
total: req.logs.length,
|
|
124
|
+
errors: errors.length,
|
|
125
|
+
warnings: warnings.length,
|
|
126
|
+
entries: req.logs.slice(-20).map((l) => ({
|
|
127
|
+
level: l.level,
|
|
128
|
+
message: l.message,
|
|
129
|
+
})),
|
|
130
|
+
};
|
|
131
|
+
if (req.exception) {
|
|
132
|
+
logsDetails.exception = {
|
|
133
|
+
message: req.exception.message,
|
|
134
|
+
stack: req.exception.stack,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
panels.logs = {
|
|
138
|
+
label: 'Logs',
|
|
139
|
+
icon: '📝',
|
|
140
|
+
summary: `${req.logs.length} entries (${errors.length} errors, ${warnings.length} warnings)`,
|
|
141
|
+
details: logsDetails,
|
|
142
|
+
};
|
|
143
|
+
return panels;
|
|
144
|
+
}
|
|
76
145
|
};
|
|
77
146
|
exports.DevtoolsService = DevtoolsService;
|
|
78
147
|
exports.DevtoolsService = DevtoolsService = __decorate([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"devtools.service.js","sourceRoot":"","sources":["../devtools.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAIrC,IAAM,eAAe,GAArB,MAAM,eAAe;IAI1B,YAAY,UAAU,GAAG,EAAE;QAHV,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;
|
|
1
|
+
{"version":3,"file":"devtools.service.js","sourceRoot":"","sources":["../devtools.service.ts"],"names":[],"mappings":"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"}
|
package/dist/toolbar/profiler.js
CHANGED
|
@@ -64,14 +64,9 @@ const PROFILER_PAGE = (config) => {
|
|
|
64
64
|
.panel-body tr:last-child td, .panel-body tr:last-child th { border-bottom: none; }
|
|
65
65
|
.empty { color: #bbb; font-size: 12px; }
|
|
66
66
|
.mono { font-family: SF Mono,Menlo,monospace; font-size: 11px; }
|
|
67
|
-
#history-detail { display: none; margin-top: 12px; }
|
|
68
|
-
#history-detail.open { display: block; }
|
|
69
67
|
#history-body tr { cursor: pointer; }
|
|
70
68
|
#history-body tr:hover { background: #f0f7ff; }
|
|
71
69
|
#history-body tr.selected { background: #e1effa; }
|
|
72
|
-
.detail-section { margin-bottom: 12px; }
|
|
73
|
-
.detail-section:last-child { margin-bottom: 0; }
|
|
74
|
-
.detail-section h4 { font-size: 10px; text-transform: uppercase; letter-spacing: 0.5px; color: #999; margin-bottom: 6px; }
|
|
75
70
|
.query-table { width: 100%; }
|
|
76
71
|
.query-row { display: flex; align-items: flex-start; padding: 5px 0; gap: 6px; border-bottom: 1px solid #eee; font-size: 11px; }
|
|
77
72
|
.query-row:last-child { border-bottom: none; }
|
|
@@ -102,6 +97,37 @@ const PROFILER_PAGE = (config) => {
|
|
|
102
97
|
.status-300 { background: #fff3cd; color: #856404; }
|
|
103
98
|
.status-400 { background: #f8d7da; color: #721c24; }
|
|
104
99
|
.status-500 { background: #f8d7da; color: #721c24; }
|
|
100
|
+
#history-body tr { cursor: pointer; }
|
|
101
|
+
#history-body tr:hover { background: #f0f7ff; }
|
|
102
|
+
#history-body tr.selected { background: #e1effa; }
|
|
103
|
+
.sf-detail { display: none; }
|
|
104
|
+
.sf-detail.open { display: flex; }
|
|
105
|
+
.sf-toolbar {
|
|
106
|
+
background: #1a1a1a; color: #ccc; display: flex; align-items: center;
|
|
107
|
+
height: 30px; padding: 0 10px; font-size: 11px;
|
|
108
|
+
box-shadow: 0 1px 4px rgba(0,0,0,0.3);
|
|
109
|
+
}
|
|
110
|
+
.sf-toolbar .back { color: #888; cursor: pointer; font-size: 11px; padding: 0 8px; text-decoration: none; }
|
|
111
|
+
.sf-toolbar .back:hover { color: #fff; }
|
|
112
|
+
.sf-toolbar .spacer { flex: 1; }
|
|
113
|
+
.sf-toolbar .req-summary { display: flex; align-items: center; gap: 8px; font-size: 11px; }
|
|
114
|
+
.sf-sidebar {
|
|
115
|
+
width: 200px; background: #fff; border-right: 1px solid #ddd;
|
|
116
|
+
flex-shrink: 0; font-size: 12px; overflow-y: auto;
|
|
117
|
+
}
|
|
118
|
+
.sf-sidebar .sf-metrics { padding: 12px; border-bottom: 1px solid #eee; }
|
|
119
|
+
.sf-sidebar .sf-metrics .m-row { display: flex; justify-content: space-between; padding: 2px 0; font-size: 11px; }
|
|
120
|
+
.sf-sidebar .sf-metrics .m-label { color: #999; }
|
|
121
|
+
.sf-sidebar .sf-metrics .m-value { color: #333; font-weight: 500; text-align: right; font-size: 11px; }
|
|
122
|
+
.sf-sidebar .panel-nav { list-style: none; padding: 0; margin: 0; }
|
|
123
|
+
.sf-sidebar .panel-nav li {
|
|
124
|
+
padding: 6px 12px; cursor: pointer; font-size: 11px; color: #555;
|
|
125
|
+
border-bottom: 1px solid #f0f0f0; display: flex; align-items: center; gap: 6px;
|
|
126
|
+
}
|
|
127
|
+
.sf-sidebar .panel-nav li:hover { background: #f5f9ff; color: #222; }
|
|
128
|
+
.sf-sidebar .panel-nav li.active { background: #e8f0fe; color: #1a73e8; font-weight: 600; border-right: 3px solid #1a73e8; }
|
|
129
|
+
.sf-main { flex: 1; padding: 16px; overflow-y: auto; }
|
|
130
|
+
.sf-main .panel { margin-bottom: 0; }
|
|
105
131
|
</style>
|
|
106
132
|
</head>
|
|
107
133
|
<body>
|
|
@@ -130,9 +156,20 @@ const PROFILER_PAGE = (config) => {
|
|
|
130
156
|
<thead><tr style="background:#fafafa"><th style="padding:8px 12px;text-align:left;color:#888;font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid #ddd">Time</th><th style="padding:8px 12px;text-align:left;color:#888;font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid #ddd">Method</th><th style="padding:8px 12px;text-align:left;color:#888;font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid #ddd">Path</th><th style="padding:8px 12px;text-align:left;color:#888;font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid #ddd">Status</th><th style="padding:8px 12px;text-align:left;color:#888;font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:0.5px;border-bottom:1px solid #ddd">Duration</th></tr></thead>
|
|
131
157
|
<tbody id="history-body"></tbody>
|
|
132
158
|
</table>
|
|
133
|
-
|
|
134
|
-
|
|
159
|
+
</div>
|
|
160
|
+
</div>
|
|
161
|
+
<div id="tab-request" class="tab-content" style="display:none">
|
|
162
|
+
<div class="sf-toolbar">
|
|
163
|
+
<a class="back" id="back-to-history">← Back to list</a>
|
|
164
|
+
<span class="spacer"></span>
|
|
165
|
+
<span class="req-summary" id="detail-toolbar-summary"></span>
|
|
166
|
+
</div>
|
|
167
|
+
<div class="layout" style="min-height:calc(100vh - 60px)">
|
|
168
|
+
<div class="sf-sidebar">
|
|
169
|
+
<div class="sf-metrics" id="detail-metrics"></div>
|
|
170
|
+
<ul class="panel-nav" id="detail-panel-nav"></ul>
|
|
135
171
|
</div>
|
|
172
|
+
<div class="sf-main" id="detail-main"></div>
|
|
136
173
|
</div>
|
|
137
174
|
</div>
|
|
138
175
|
</div>
|
|
@@ -147,12 +184,9 @@ const PROFILER_PAGE = (config) => {
|
|
|
147
184
|
|
|
148
185
|
document.querySelectorAll('[data-tab]').forEach(function(el){
|
|
149
186
|
el.addEventListener('click', function(){
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
activeTab = el.getAttribute('data-tab');
|
|
154
|
-
document.getElementById('tab-'+activeTab).style.display='';
|
|
155
|
-
if (activeTab==='history') loadHistory();
|
|
187
|
+
var tab = el.getAttribute('data-tab');
|
|
188
|
+
switchTab(tab);
|
|
189
|
+
if (tab==='history') loadHistory();
|
|
156
190
|
});
|
|
157
191
|
});
|
|
158
192
|
|
|
@@ -260,74 +294,117 @@ const PROFILER_PAGE = (config) => {
|
|
|
260
294
|
});
|
|
261
295
|
}
|
|
262
296
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
297
|
+
var panelOrder = ['request','performance','database','routes','logs'];
|
|
298
|
+
var currentPanels = {};
|
|
299
|
+
var currentPanelKey = '';
|
|
300
|
+
|
|
301
|
+
function showPanel(key) {
|
|
302
|
+
currentPanelKey = key;
|
|
303
|
+
var p = currentPanels[key];
|
|
304
|
+
if (!p) return;
|
|
305
|
+
document.querySelectorAll('#detail-panel-nav li').forEach(function(l){l.classList.remove('active')});
|
|
306
|
+
var navItem = document.getElementById('nav-'+key);
|
|
307
|
+
if (navItem) navItem.classList.add('active');
|
|
308
|
+
document.getElementById('detail-main').innerHTML =
|
|
309
|
+
'<div class="panel"><div class="panel-header" style="cursor:default"><span>'+escape(p.label)+'</span><span class="summary">'+escape(p.summary||'')+'</span></div><div class="panel-body open" style="display:block">'+renderPanelContent(p)+'</div></div>';
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function showRequestDetail(id) {
|
|
313
|
+
fetch(BASE + '/__devtools/request/' + id).then(function(r){return r.json()}).then(function(panels){
|
|
314
|
+
if (!panels) { return; }
|
|
315
|
+
currentPanels = panels;
|
|
316
|
+
|
|
317
|
+
var first = null;
|
|
318
|
+
var firstKey = null;
|
|
319
|
+
var order = panelOrder;
|
|
320
|
+
for (var i=0;i<order.length;i++) {
|
|
321
|
+
var p = panels[order[i]];
|
|
322
|
+
if (p && p.label) { first = p; firstKey = order[i]; break; }
|
|
323
|
+
}
|
|
324
|
+
if (!first) {
|
|
325
|
+
for (var k in panels) { first = panels[k]; firstKey = k; break; }
|
|
326
|
+
}
|
|
327
|
+
if (!first || !first.details) { return; }
|
|
328
|
+
var dd = first.details;
|
|
329
|
+
|
|
330
|
+
document.getElementById('detail-toolbar-summary').innerHTML =
|
|
331
|
+
'<span class="badge badge-'+((dd.method||'get').toLowerCase())+'">'+escape(dd.method||'')+'</span>'+
|
|
332
|
+
' <span class="mono" style="color:#ddd">'+escape(dd.path||'')+'</span>'+
|
|
333
|
+
' <span class="status-badge status-'+(dd.status||'')+'">'+escape(dd.status||'')+'</span>'+
|
|
334
|
+
' <span style="color:#999">'+escape(dd.duration||'')+'</span>'+
|
|
335
|
+
' <span style="color:#999">'+escape(dd.memory||'')+'</span>';
|
|
336
|
+
|
|
337
|
+
var metricsHtml = '';
|
|
338
|
+
var metricFields = ['method','path','status','duration','memory','route'];
|
|
339
|
+
for (var i=0;i<metricFields.length;i++) {
|
|
340
|
+
var k = metricFields[i];
|
|
341
|
+
var v = dd[k];
|
|
342
|
+
if (v==null) continue;
|
|
343
|
+
if (k==='method') {
|
|
344
|
+
metricsHtml += '<div class="m-row"><span class="m-label">Method</span><span class="m-value"><span class="badge badge-'+v.toLowerCase()+'">'+escape(v)+'</span></span></div>';
|
|
345
|
+
} else if (k==='status') {
|
|
346
|
+
metricsHtml += '<div class="m-row"><span class="m-label">Status</span><span class="m-value"><span class="status-badge status-'+v+'">'+escape(v)+'</span></span></div>';
|
|
347
|
+
} else {
|
|
348
|
+
metricsHtml += '<div class="m-row"><span class="m-label">'+escape(k.charAt(0).toUpperCase()+k.slice(1))+'</span><span class="m-value '+(k==='path'||k==='route'?'mono':'')+'">'+escape(v)+'</span></div>';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
document.getElementById('detail-metrics').innerHTML = metricsHtml;
|
|
352
|
+
|
|
353
|
+
var navHtml = '';
|
|
354
|
+
for (var i=0;i<order.length;i++) {
|
|
355
|
+
var p = panels[order[i]];
|
|
356
|
+
if (!p || !p.label) continue;
|
|
357
|
+
var active = order[i]===firstKey ? ' class="active"' : '';
|
|
358
|
+
navHtml += '<li id="nav-'+order[i]+'"'+active+' data-panel="'+order[i]+'">'+escape(p.icon||'')+' '+escape(p.label)+'</li>';
|
|
359
|
+
}
|
|
360
|
+
for (var k in panels) {
|
|
361
|
+
if (order.indexOf(k)!==-1) continue;
|
|
362
|
+
var p = panels[k];
|
|
363
|
+
if (!p || !p.label) continue;
|
|
364
|
+
navHtml += '<li id="nav-'+k+'" data-panel="'+k+'">'+escape(p.icon||'')+' '+escape(p.label)+'</li>';
|
|
365
|
+
}
|
|
366
|
+
document.getElementById('detail-panel-nav').innerHTML = navHtml;
|
|
367
|
+
|
|
368
|
+
document.querySelectorAll('#detail-panel-nav li').forEach(function(el){
|
|
369
|
+
el.addEventListener('click', function(){ showPanel(this.getAttribute('data-panel')); });
|
|
286
370
|
});
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
371
|
+
|
|
372
|
+
switchTab('request');
|
|
373
|
+
showPanel(firstKey);
|
|
374
|
+
}).catch(function(e){
|
|
375
|
+
console.error('[Devtools] Failed to load request detail:', e);
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
function switchTab(tab) {
|
|
380
|
+
document.querySelectorAll('[data-tab]').forEach(function(b){b.classList.remove('active')});
|
|
381
|
+
document.querySelectorAll('.tab-content').forEach(function(c){c.style.display='none'});
|
|
382
|
+
activeTab = tab;
|
|
383
|
+
var tabBtn = document.querySelector('[data-tab="'+tab+'"]');
|
|
384
|
+
if (tabBtn) tabBtn.classList.add('active');
|
|
385
|
+
document.getElementById('tab-'+tab).style.display='';
|
|
293
386
|
}
|
|
294
387
|
|
|
295
388
|
function loadHistory() {
|
|
296
389
|
fetch(BASE + '/__devtools/history').then(function(r){return r.json()}).then(function(rows){
|
|
297
390
|
var tbody = document.getElementById('history-body');
|
|
298
|
-
var detail = document.getElementById('history-detail');
|
|
299
391
|
tbody.innerHTML = '';
|
|
300
392
|
if (!rows || rows.length===0) {
|
|
301
393
|
tbody.innerHTML = '<tr><td colspan="5" style="padding:20px;text-align:center;color:#bbb">No requests recorded yet</td></tr>';
|
|
302
394
|
return;
|
|
303
395
|
}
|
|
304
|
-
var selectedId = tbody.getAttribute('data-selected');
|
|
305
396
|
rows.forEach(function(r){
|
|
306
397
|
var sc = r.statusCode;
|
|
307
398
|
var scCls = sc>=400 ? 'error-text' : sc>=300 ? 'warn-text' : 'ok-text';
|
|
308
399
|
var mCls = 'badge-'+r.method.toLowerCase();
|
|
309
|
-
var sel = r.id===selectedId ? ' selected' : '';
|
|
310
400
|
var tr = document.createElement('tr');
|
|
311
|
-
tr.className = sel;
|
|
312
401
|
tr.innerHTML =
|
|
313
402
|
'<td style="padding:8px 12px;border-bottom:1px solid #eee;color:#888">'+escape(new Date(r.timestamp).toLocaleTimeString())+'</td>'+
|
|
314
403
|
'<td style="padding:8px 12px;border-bottom:1px solid #eee"><span class="badge '+mCls+'">'+escape(r.method)+'</span></td>'+
|
|
315
404
|
'<td style="padding:8px 12px;border-bottom:1px solid #eee;font-family:SF Mono,Menlo,monospace;font-size:11px">'+escape(r.path)+'</td>'+
|
|
316
405
|
'<td style="padding:8px 12px;border-bottom:1px solid #eee"><span class="'+scCls+'">'+sc+'</span></td>'+
|
|
317
406
|
'<td style="padding:8px 12px;border-bottom:1px solid #eee;color:#888;font-family:SF Mono,Menlo,monospace">'+(r.duration!=null?r.duration.toFixed(1):'')+' ms</td>';
|
|
318
|
-
tr.addEventListener('click', function(){
|
|
319
|
-
document.querySelectorAll('#history-body tr').forEach(function(t){t.classList.remove('selected')});
|
|
320
|
-
tr.classList.add('selected');
|
|
321
|
-
tbody.setAttribute('data-selected', r.id);
|
|
322
|
-
fetch(BASE + '/__devtools/request/' + r.id).then(function(r2){return r2.json()}).then(function(detailData){
|
|
323
|
-
document.getElementById('history-detail-body').innerHTML = renderRequestDetail(detailData);
|
|
324
|
-
detail.classList.add('open');
|
|
325
|
-
}).catch(function(e){
|
|
326
|
-
console.error('[Devtools] Failed to load request detail:', e);
|
|
327
|
-
document.getElementById('history-detail-body').innerHTML = '<span class="empty">Failed to load detail</span>';
|
|
328
|
-
detail.classList.add('open');
|
|
329
|
-
});
|
|
330
|
-
});
|
|
407
|
+
tr.addEventListener('click', function(){ showRequestDetail(r.id); });
|
|
331
408
|
tbody.appendChild(tr);
|
|
332
409
|
});
|
|
333
410
|
}).catch(function(e){
|
|
@@ -336,6 +413,8 @@ const PROFILER_PAGE = (config) => {
|
|
|
336
413
|
});
|
|
337
414
|
}
|
|
338
415
|
|
|
416
|
+
document.getElementById('back-to-history').addEventListener('click', function(){ switchTab('history'); loadHistory(); });
|
|
417
|
+
|
|
339
418
|
loadDashboard();
|
|
340
419
|
})();
|
|
341
420
|
</script>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profiler.js","sourceRoot":"","sources":["../../toolbar/profiler.ts"],"names":[],"mappings":";;;AAIO,MAAM,aAAa,GAAG,CAAC,MAAoC,EAAE,EAAE;IACpE,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;IAExC,OAAO
|
|
1
|
+
{"version":3,"file":"profiler.js","sourceRoot":"","sources":["../../toolbar/profiler.ts"],"names":[],"mappings":";;;AAIO,MAAM,aAAa,GAAG,CAAC,MAAoC,EAAE,EAAE;IACpE,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;IAExC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;QAgaD,CAAC;AACT,CAAC,CAAC;AApaW,QAAA,aAAa,iBAoaxB"}
|