@webda/debug 4.0.0-beta.3
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/LICENSE +166 -0
- package/README.md +95 -0
- package/lib/bodycapture.d.ts +66 -0
- package/lib/bodycapture.js +162 -0
- package/lib/bodycapture.js.map +1 -0
- package/lib/debugservice.service.d.ts +166 -0
- package/lib/debugservice.service.js +609 -0
- package/lib/debugservice.service.js.map +1 -0
- package/lib/index.d.ts +7 -0
- package/lib/index.js +7 -0
- package/lib/index.js.map +1 -0
- package/lib/introspection.d.ts +115 -0
- package/lib/introspection.js +260 -0
- package/lib/introspection.js.map +1 -0
- package/lib/logbuffer.d.ts +75 -0
- package/lib/logbuffer.js +98 -0
- package/lib/logbuffer.js.map +1 -0
- package/lib/requestlog.d.ts +181 -0
- package/lib/requestlog.js +153 -0
- package/lib/requestlog.js.map +1 -0
- package/lib/tui/client.d.ts +165 -0
- package/lib/tui/client.js +220 -0
- package/lib/tui/client.js.map +1 -0
- package/lib/tui/panels/config.d.ts +79 -0
- package/lib/tui/panels/config.js +291 -0
- package/lib/tui/panels/config.js.map +1 -0
- package/lib/tui/panels/logs.d.ts +106 -0
- package/lib/tui/panels/logs.js +342 -0
- package/lib/tui/panels/logs.js.map +1 -0
- package/lib/tui/panels/models.d.ts +47 -0
- package/lib/tui/panels/models.js +193 -0
- package/lib/tui/panels/models.js.map +1 -0
- package/lib/tui/panels/operations.d.ts +55 -0
- package/lib/tui/panels/operations.js +241 -0
- package/lib/tui/panels/operations.js.map +1 -0
- package/lib/tui/panels/panel.d.ts +55 -0
- package/lib/tui/panels/panel.js +31 -0
- package/lib/tui/panels/panel.js.map +1 -0
- package/lib/tui/panels/requests.d.ts +156 -0
- package/lib/tui/panels/requests.js +512 -0
- package/lib/tui/panels/requests.js.map +1 -0
- package/lib/tui/panels/routes.d.ts +45 -0
- package/lib/tui/panels/routes.js +154 -0
- package/lib/tui/panels/routes.js.map +1 -0
- package/lib/tui/panels/services.d.ts +49 -0
- package/lib/tui/panels/services.js +266 -0
- package/lib/tui/panels/services.js.map +1 -0
- package/lib/tui/tui.d.ts +58 -0
- package/lib/tui/tui.js +236 -0
- package/lib/tui/tui.js.map +1 -0
- package/package.json +60 -0
- package/webui/app.js +177 -0
- package/webui/components/logs.js +128 -0
- package/webui/components/model-graph.js +292 -0
- package/webui/components/models.js +213 -0
- package/webui/components/operations.js +315 -0
- package/webui/components/requests.js +264 -0
- package/webui/components/schema-form.js +268 -0
- package/webui/components/services.js +248 -0
- package/webui/index.html +22 -0
- package/webui/logo.svg +1 -0
- package/webui/styles.css +685 -0
- package/webui/vendor/htm.js +1 -0
- package/webui/vendor/preact-hooks.js +2 -0
- package/webui/vendor/preact.js +2 -0
- package/webui/webda.png +0 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import type { Panel } from "./panel.js";
|
|
2
|
+
import type { DebugClient } from "../client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Requests panel: displays a live-updating list of HTTP requests
|
|
5
|
+
* received from the debug server WebSocket. Newest entries appear at top.
|
|
6
|
+
*
|
|
7
|
+
* Press Enter or Right-arrow on a row to drill into the captured
|
|
8
|
+
* headers/bodies. Press Left-arrow, Escape, or Enter again to return to the list.
|
|
9
|
+
*/
|
|
10
|
+
export declare class RequestsPanel implements Panel {
|
|
11
|
+
private client;
|
|
12
|
+
name: string;
|
|
13
|
+
private entries;
|
|
14
|
+
/** Map of request id to entry for updating on result */
|
|
15
|
+
private byId;
|
|
16
|
+
/** Unsubscribe function for WebSocket events */
|
|
17
|
+
private unsubscribe?;
|
|
18
|
+
/** Maximum entries to keep in memory */
|
|
19
|
+
private maxEntries;
|
|
20
|
+
/** Scroll offset from top */
|
|
21
|
+
private scrollOffset;
|
|
22
|
+
/** Cursor position into the entries array */
|
|
23
|
+
private cursor;
|
|
24
|
+
/** Visible rows (updated on render) */
|
|
25
|
+
private visibleRows;
|
|
26
|
+
/** When non-null, the panel is showing a detail view for this id */
|
|
27
|
+
private detailId;
|
|
28
|
+
/** Cached detail entry currently displayed */
|
|
29
|
+
private detail;
|
|
30
|
+
/** Detail view error message, if any */
|
|
31
|
+
private detailError;
|
|
32
|
+
/** Loading flag for detail */
|
|
33
|
+
private detailLoading;
|
|
34
|
+
/** Detail view scroll offset */
|
|
35
|
+
private detailScroll;
|
|
36
|
+
/**
|
|
37
|
+
* @param client - Debug API client
|
|
38
|
+
*/
|
|
39
|
+
constructor(client: DebugClient);
|
|
40
|
+
/**
|
|
41
|
+
* Load existing request history and subscribe to live events.
|
|
42
|
+
*/
|
|
43
|
+
refresh(): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Convert a raw RequestLogEntry summary to a display entry.
|
|
46
|
+
*
|
|
47
|
+
* @param raw - raw entry from the API
|
|
48
|
+
* @returns formatted display entry
|
|
49
|
+
*/
|
|
50
|
+
private toDisplay;
|
|
51
|
+
/**
|
|
52
|
+
* Handle a WebSocket event and update the entries list.
|
|
53
|
+
* @param event - WebSocket event to process
|
|
54
|
+
*/
|
|
55
|
+
private handleEvent;
|
|
56
|
+
/**
|
|
57
|
+
* Asynchronously load the detail for the currently selected request id.
|
|
58
|
+
* Updates internal state; the next render will reflect the result.
|
|
59
|
+
*
|
|
60
|
+
* @param id - request id to fetch
|
|
61
|
+
*/
|
|
62
|
+
private loadDetail;
|
|
63
|
+
/**
|
|
64
|
+
* Open the detail view for the entry at the current cursor.
|
|
65
|
+
*/
|
|
66
|
+
private openDetail;
|
|
67
|
+
/**
|
|
68
|
+
* Close the detail view and return to the list.
|
|
69
|
+
*/
|
|
70
|
+
private closeDetail;
|
|
71
|
+
/**
|
|
72
|
+
* Handle keyboard input.
|
|
73
|
+
* @param key - key name from terminal-kit
|
|
74
|
+
*/
|
|
75
|
+
onKey(key: string): void;
|
|
76
|
+
/**
|
|
77
|
+
* Move cursor by delta, keeping it in range and adjusting scroll.
|
|
78
|
+
*
|
|
79
|
+
* @param delta - rows to move (negative = up)
|
|
80
|
+
*/
|
|
81
|
+
private moveCursor;
|
|
82
|
+
/**
|
|
83
|
+
* Render the panel: either the request list or the detail view.
|
|
84
|
+
*
|
|
85
|
+
* @param term - terminal-kit instance
|
|
86
|
+
* @param startRow - first row available for content
|
|
87
|
+
* @param endRow - last row available for content
|
|
88
|
+
* @param width - terminal width in columns
|
|
89
|
+
*/
|
|
90
|
+
render(term: any, startRow: number, endRow: number, width: number): void;
|
|
91
|
+
/**
|
|
92
|
+
* Render the request list (default view).
|
|
93
|
+
*
|
|
94
|
+
* @param term - terminal-kit instance
|
|
95
|
+
* @param startRow - first row available for content
|
|
96
|
+
* @param endRow - last row available for content
|
|
97
|
+
* @param width - terminal width in columns
|
|
98
|
+
*/
|
|
99
|
+
private renderList;
|
|
100
|
+
/**
|
|
101
|
+
* Render the detail view for the selected request.
|
|
102
|
+
*
|
|
103
|
+
* @param term - terminal-kit instance
|
|
104
|
+
* @param startRow - first row available for content
|
|
105
|
+
* @param endRow - last row available for content
|
|
106
|
+
* @param width - terminal width in columns
|
|
107
|
+
*/
|
|
108
|
+
private renderDetail;
|
|
109
|
+
/**
|
|
110
|
+
* Build the wrapped, formatted lines that make up the detail view.
|
|
111
|
+
* Returns an array of strings (one per terminal row).
|
|
112
|
+
*
|
|
113
|
+
* @param width - terminal width
|
|
114
|
+
* @returns array of formatted lines
|
|
115
|
+
*/
|
|
116
|
+
private buildDetailLines;
|
|
117
|
+
/**
|
|
118
|
+
* Append a flat key/value list of headers to a line buffer.
|
|
119
|
+
*
|
|
120
|
+
* @param lines - target line buffer that receives the formatted lines
|
|
121
|
+
* @param headers - header map to render, may be undefined
|
|
122
|
+
*/
|
|
123
|
+
private appendHeadersBlock;
|
|
124
|
+
/**
|
|
125
|
+
* Append a body capture (text / text-truncated / binary / empty) to the
|
|
126
|
+
* line buffer, wrapping long lines to the terminal width.
|
|
127
|
+
*
|
|
128
|
+
* @param lines - target line buffer that receives the formatted lines
|
|
129
|
+
* @param body - the captured body record (or undefined)
|
|
130
|
+
* @param width - terminal width in columns, used for line wrapping
|
|
131
|
+
*/
|
|
132
|
+
private appendBodyBlock;
|
|
133
|
+
/**
|
|
134
|
+
* Render an HTTP method with appropriate color.
|
|
135
|
+
* @param term - terminal-kit instance
|
|
136
|
+
* @param method - padded method string to render
|
|
137
|
+
*/
|
|
138
|
+
private renderMethod;
|
|
139
|
+
/**
|
|
140
|
+
* Format a timestamp as HH:MM:SS.
|
|
141
|
+
* @param ts - Unix timestamp in milliseconds
|
|
142
|
+
* @returns formatted time string
|
|
143
|
+
*/
|
|
144
|
+
private formatTime;
|
|
145
|
+
/**
|
|
146
|
+
* Format a byte count for display in the detail view.
|
|
147
|
+
*
|
|
148
|
+
* @param n - byte count, possibly undefined
|
|
149
|
+
* @returns formatted human-readable byte count (e.g. "12.3 KB")
|
|
150
|
+
*/
|
|
151
|
+
private formatBytes;
|
|
152
|
+
/**
|
|
153
|
+
* Clean up panel resources and unsubscribe from events.
|
|
154
|
+
*/
|
|
155
|
+
destroy(): void;
|
|
156
|
+
}
|
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Requests panel: displays a live-updating list of HTTP requests
|
|
3
|
+
* received from the debug server WebSocket. Newest entries appear at top.
|
|
4
|
+
*
|
|
5
|
+
* Press Enter or Right-arrow on a row to drill into the captured
|
|
6
|
+
* headers/bodies. Press Left-arrow, Escape, or Enter again to return to the list.
|
|
7
|
+
*/
|
|
8
|
+
export class RequestsPanel {
|
|
9
|
+
/**
|
|
10
|
+
* @param client - Debug API client
|
|
11
|
+
*/
|
|
12
|
+
constructor(client) {
|
|
13
|
+
this.client = client;
|
|
14
|
+
this.name = "Requests";
|
|
15
|
+
this.entries = [];
|
|
16
|
+
/** Map of request id to entry for updating on result */
|
|
17
|
+
this.byId = new Map();
|
|
18
|
+
/** Maximum entries to keep in memory */
|
|
19
|
+
this.maxEntries = 500;
|
|
20
|
+
/** Scroll offset from top */
|
|
21
|
+
this.scrollOffset = 0;
|
|
22
|
+
/** Cursor position into the entries array */
|
|
23
|
+
this.cursor = 0;
|
|
24
|
+
/** Visible rows (updated on render) */
|
|
25
|
+
this.visibleRows = 0;
|
|
26
|
+
/** When non-null, the panel is showing a detail view for this id */
|
|
27
|
+
this.detailId = null;
|
|
28
|
+
/** Cached detail entry currently displayed */
|
|
29
|
+
this.detail = null;
|
|
30
|
+
/** Detail view error message, if any */
|
|
31
|
+
this.detailError = null;
|
|
32
|
+
/** Loading flag for detail */
|
|
33
|
+
this.detailLoading = false;
|
|
34
|
+
/** Detail view scroll offset */
|
|
35
|
+
this.detailScroll = 0;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Load existing request history and subscribe to live events.
|
|
39
|
+
*/
|
|
40
|
+
async refresh() {
|
|
41
|
+
// Fetch historical entries
|
|
42
|
+
try {
|
|
43
|
+
const history = await this.client.getRequests();
|
|
44
|
+
this.entries = history.map((entry) => this.toDisplay(entry)).reverse();
|
|
45
|
+
this.byId.clear();
|
|
46
|
+
for (const entry of this.entries)
|
|
47
|
+
this.byId.set(entry.id, entry);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
this.entries = [];
|
|
51
|
+
this.byId.clear();
|
|
52
|
+
}
|
|
53
|
+
// Subscribe to WebSocket events (only once)
|
|
54
|
+
if (!this.unsubscribe) {
|
|
55
|
+
this.unsubscribe = this.client.onEvent((event) => {
|
|
56
|
+
this.handleEvent(event);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Convert a raw RequestLogEntry summary to a display entry.
|
|
62
|
+
*
|
|
63
|
+
* @param raw - raw entry from the API
|
|
64
|
+
* @returns formatted display entry
|
|
65
|
+
*/
|
|
66
|
+
toDisplay(raw) {
|
|
67
|
+
return {
|
|
68
|
+
id: raw.id,
|
|
69
|
+
time: this.formatTime(raw.timestamp),
|
|
70
|
+
timestamp: raw.timestamp,
|
|
71
|
+
method: raw.method || "?",
|
|
72
|
+
url: raw.url || "/",
|
|
73
|
+
statusCode: raw.statusCode || 0,
|
|
74
|
+
duration: raw.duration || 0,
|
|
75
|
+
pending: !raw.statusCode
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Handle a WebSocket event and update the entries list.
|
|
80
|
+
* @param event - WebSocket event to process
|
|
81
|
+
*/
|
|
82
|
+
handleEvent(event) {
|
|
83
|
+
if (event.type === "request") {
|
|
84
|
+
const entry = {
|
|
85
|
+
id: event.id,
|
|
86
|
+
time: this.formatTime(event.timestamp),
|
|
87
|
+
timestamp: event.timestamp,
|
|
88
|
+
method: event.method,
|
|
89
|
+
url: event.url,
|
|
90
|
+
statusCode: 0,
|
|
91
|
+
duration: 0,
|
|
92
|
+
pending: true
|
|
93
|
+
};
|
|
94
|
+
this.entries.unshift(entry);
|
|
95
|
+
this.byId.set(event.id, entry);
|
|
96
|
+
// Trim old entries
|
|
97
|
+
if (this.entries.length > this.maxEntries) {
|
|
98
|
+
const removed = this.entries.pop();
|
|
99
|
+
if (removed)
|
|
100
|
+
this.byId.delete(removed.id);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (event.type === "result") {
|
|
104
|
+
const entry = this.byId.get(event.id);
|
|
105
|
+
if (entry) {
|
|
106
|
+
entry.statusCode = event.statusCode;
|
|
107
|
+
entry.duration = event.duration;
|
|
108
|
+
entry.pending = false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
else if (event.type === "404") {
|
|
112
|
+
const entry = this.byId.get(event.id);
|
|
113
|
+
if (entry) {
|
|
114
|
+
entry.statusCode = 404;
|
|
115
|
+
entry.pending = false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Asynchronously load the detail for the currently selected request id.
|
|
121
|
+
* Updates internal state; the next render will reflect the result.
|
|
122
|
+
*
|
|
123
|
+
* @param id - request id to fetch
|
|
124
|
+
*/
|
|
125
|
+
async loadDetail(id) {
|
|
126
|
+
this.detailLoading = true;
|
|
127
|
+
this.detailError = null;
|
|
128
|
+
this.detail = null;
|
|
129
|
+
try {
|
|
130
|
+
this.detail = await this.client.getRequestDetail(id);
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
this.detailError = err?.message ?? String(err);
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
this.detailLoading = false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Open the detail view for the entry at the current cursor.
|
|
141
|
+
*/
|
|
142
|
+
openDetail() {
|
|
143
|
+
const entry = this.entries[this.cursor];
|
|
144
|
+
if (!entry)
|
|
145
|
+
return;
|
|
146
|
+
this.detailId = entry.id;
|
|
147
|
+
this.detailScroll = 0;
|
|
148
|
+
// Fire-and-forget — render will show "Loading..." until the promise lands.
|
|
149
|
+
void this.loadDetail(entry.id);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Close the detail view and return to the list.
|
|
153
|
+
*/
|
|
154
|
+
closeDetail() {
|
|
155
|
+
this.detailId = null;
|
|
156
|
+
this.detail = null;
|
|
157
|
+
this.detailError = null;
|
|
158
|
+
this.detailLoading = false;
|
|
159
|
+
this.detailScroll = 0;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Handle keyboard input.
|
|
163
|
+
* @param key - key name from terminal-kit
|
|
164
|
+
*/
|
|
165
|
+
onKey(key) {
|
|
166
|
+
if (this.detailId) {
|
|
167
|
+
// Detail view key handling
|
|
168
|
+
switch (key) {
|
|
169
|
+
case "ESCAPE":
|
|
170
|
+
case "LEFT":
|
|
171
|
+
case "BACKSPACE":
|
|
172
|
+
this.closeDetail();
|
|
173
|
+
break;
|
|
174
|
+
case "UP":
|
|
175
|
+
this.detailScroll = Math.max(0, this.detailScroll - 1);
|
|
176
|
+
break;
|
|
177
|
+
case "DOWN":
|
|
178
|
+
this.detailScroll++;
|
|
179
|
+
break;
|
|
180
|
+
case "PAGE_UP":
|
|
181
|
+
this.detailScroll = Math.max(0, this.detailScroll - this.visibleRows);
|
|
182
|
+
break;
|
|
183
|
+
case "PAGE_DOWN":
|
|
184
|
+
this.detailScroll += this.visibleRows;
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
switch (key) {
|
|
190
|
+
case "UP":
|
|
191
|
+
this.moveCursor(-1);
|
|
192
|
+
break;
|
|
193
|
+
case "DOWN":
|
|
194
|
+
this.moveCursor(1);
|
|
195
|
+
break;
|
|
196
|
+
case "PAGE_UP":
|
|
197
|
+
this.moveCursor(-this.visibleRows);
|
|
198
|
+
break;
|
|
199
|
+
case "PAGE_DOWN":
|
|
200
|
+
this.moveCursor(this.visibleRows);
|
|
201
|
+
break;
|
|
202
|
+
case "HOME":
|
|
203
|
+
this.cursor = 0;
|
|
204
|
+
this.scrollOffset = 0;
|
|
205
|
+
break;
|
|
206
|
+
case "END":
|
|
207
|
+
this.cursor = Math.max(0, this.entries.length - 1);
|
|
208
|
+
break;
|
|
209
|
+
case "ENTER":
|
|
210
|
+
case "RIGHT":
|
|
211
|
+
this.openDetail();
|
|
212
|
+
break;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Move cursor by delta, keeping it in range and adjusting scroll.
|
|
217
|
+
*
|
|
218
|
+
* @param delta - rows to move (negative = up)
|
|
219
|
+
*/
|
|
220
|
+
moveCursor(delta) {
|
|
221
|
+
if (this.entries.length === 0)
|
|
222
|
+
return;
|
|
223
|
+
this.cursor = Math.max(0, Math.min(this.entries.length - 1, this.cursor + delta));
|
|
224
|
+
if (this.cursor < this.scrollOffset) {
|
|
225
|
+
this.scrollOffset = this.cursor;
|
|
226
|
+
}
|
|
227
|
+
else if (this.cursor >= this.scrollOffset + this.visibleRows) {
|
|
228
|
+
this.scrollOffset = this.cursor - this.visibleRows + 1;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Render the panel: either the request list or the detail view.
|
|
233
|
+
*
|
|
234
|
+
* @param term - terminal-kit instance
|
|
235
|
+
* @param startRow - first row available for content
|
|
236
|
+
* @param endRow - last row available for content
|
|
237
|
+
* @param width - terminal width in columns
|
|
238
|
+
*/
|
|
239
|
+
render(term, startRow, endRow, width) {
|
|
240
|
+
if (this.detailId) {
|
|
241
|
+
this.renderDetail(term, startRow, endRow, width);
|
|
242
|
+
}
|
|
243
|
+
else {
|
|
244
|
+
this.renderList(term, startRow, endRow, width);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Render the request list (default view).
|
|
249
|
+
*
|
|
250
|
+
* @param term - terminal-kit instance
|
|
251
|
+
* @param startRow - first row available for content
|
|
252
|
+
* @param endRow - last row available for content
|
|
253
|
+
* @param width - terminal width in columns
|
|
254
|
+
*/
|
|
255
|
+
renderList(term, startRow, endRow, width) {
|
|
256
|
+
this.visibleRows = endRow - startRow - 1;
|
|
257
|
+
// Header
|
|
258
|
+
term.moveTo(1, startRow);
|
|
259
|
+
term.eraseLine();
|
|
260
|
+
term.bold(" Time Method URL" + " ".repeat(Math.max(1, 40 - 3)) + "Status Duration");
|
|
261
|
+
const dataStart = startRow + 1;
|
|
262
|
+
if (this.entries.length === 0) {
|
|
263
|
+
term.moveTo(1, dataStart);
|
|
264
|
+
term.eraseLine();
|
|
265
|
+
term(" Waiting for requests...");
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
for (let i = 0; i < this.visibleRows; i++) {
|
|
269
|
+
const idx = this.scrollOffset + i;
|
|
270
|
+
const row = dataStart + i;
|
|
271
|
+
term.moveTo(1, row);
|
|
272
|
+
term.eraseLine();
|
|
273
|
+
if (idx >= this.entries.length)
|
|
274
|
+
continue;
|
|
275
|
+
const entry = this.entries[idx];
|
|
276
|
+
const isCurrent = idx === this.cursor;
|
|
277
|
+
if (isCurrent) {
|
|
278
|
+
term.bgGray();
|
|
279
|
+
}
|
|
280
|
+
// Time
|
|
281
|
+
term.dim(` ${entry.time} `);
|
|
282
|
+
// Method (color-coded)
|
|
283
|
+
const methodStr = entry.method.padEnd(6);
|
|
284
|
+
this.renderMethod(term, methodStr);
|
|
285
|
+
term(" ");
|
|
286
|
+
// URL (truncated)
|
|
287
|
+
const maxUrlLen = Math.max(10, width - 55);
|
|
288
|
+
const url = entry.url.length > maxUrlLen ? entry.url.substring(0, maxUrlLen - 3) + "..." : entry.url;
|
|
289
|
+
term(url.padEnd(maxUrlLen));
|
|
290
|
+
term(" ");
|
|
291
|
+
// Status + Duration
|
|
292
|
+
if (entry.pending) {
|
|
293
|
+
term.yellow("...");
|
|
294
|
+
}
|
|
295
|
+
else {
|
|
296
|
+
const status = String(entry.statusCode);
|
|
297
|
+
if (entry.statusCode >= 200 && entry.statusCode < 300) {
|
|
298
|
+
term.green(status);
|
|
299
|
+
}
|
|
300
|
+
else if (entry.statusCode >= 300 && entry.statusCode < 400) {
|
|
301
|
+
term.yellow(status);
|
|
302
|
+
}
|
|
303
|
+
else {
|
|
304
|
+
term.red(status);
|
|
305
|
+
}
|
|
306
|
+
term(` ${entry.duration}ms`);
|
|
307
|
+
}
|
|
308
|
+
if (isCurrent) {
|
|
309
|
+
term.styleReset();
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Render the detail view for the selected request.
|
|
315
|
+
*
|
|
316
|
+
* @param term - terminal-kit instance
|
|
317
|
+
* @param startRow - first row available for content
|
|
318
|
+
* @param endRow - last row available for content
|
|
319
|
+
* @param width - terminal width in columns
|
|
320
|
+
*/
|
|
321
|
+
renderDetail(term, startRow, endRow, width) {
|
|
322
|
+
this.visibleRows = endRow - startRow - 1;
|
|
323
|
+
const lines = this.buildDetailLines(width);
|
|
324
|
+
// Top header
|
|
325
|
+
term.moveTo(1, startRow);
|
|
326
|
+
term.eraseLine();
|
|
327
|
+
term.bold(" Request Detail ");
|
|
328
|
+
term.dim("(Esc/← to return, ↑↓ to scroll)");
|
|
329
|
+
const dataStart = startRow + 1;
|
|
330
|
+
// Clamp scroll to content length
|
|
331
|
+
const maxScroll = Math.max(0, lines.length - this.visibleRows);
|
|
332
|
+
if (this.detailScroll > maxScroll)
|
|
333
|
+
this.detailScroll = maxScroll;
|
|
334
|
+
for (let i = 0; i < this.visibleRows; i++) {
|
|
335
|
+
const row = dataStart + i;
|
|
336
|
+
const lineIdx = this.detailScroll + i;
|
|
337
|
+
term.moveTo(1, row);
|
|
338
|
+
term.eraseLine();
|
|
339
|
+
if (lineIdx >= lines.length)
|
|
340
|
+
continue;
|
|
341
|
+
term(lines[lineIdx]);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Build the wrapped, formatted lines that make up the detail view.
|
|
346
|
+
* Returns an array of strings (one per terminal row).
|
|
347
|
+
*
|
|
348
|
+
* @param width - terminal width
|
|
349
|
+
* @returns array of formatted lines
|
|
350
|
+
*/
|
|
351
|
+
buildDetailLines(width) {
|
|
352
|
+
const lines = [];
|
|
353
|
+
if (this.detailLoading) {
|
|
354
|
+
lines.push(" Loading...");
|
|
355
|
+
return lines;
|
|
356
|
+
}
|
|
357
|
+
if (this.detailError) {
|
|
358
|
+
lines.push(` Failed to load detail: ${this.detailError}`);
|
|
359
|
+
return lines;
|
|
360
|
+
}
|
|
361
|
+
if (!this.detail) {
|
|
362
|
+
lines.push(" (no detail available)");
|
|
363
|
+
return lines;
|
|
364
|
+
}
|
|
365
|
+
const e = this.detail;
|
|
366
|
+
lines.push(` ${e.method || "?"} ${e.url || "/"}`);
|
|
367
|
+
lines.push(` Status: ${e.statusCode ?? "pending"} Duration: ${e.duration != null ? e.duration + "ms" : "-"} Time: ${this.formatTime(e.timestamp || 0)}`);
|
|
368
|
+
lines.push("");
|
|
369
|
+
if (e.error) {
|
|
370
|
+
lines.push(" Error:");
|
|
371
|
+
lines.push(` ${e.error.message || ""}`);
|
|
372
|
+
if (e.error.stack) {
|
|
373
|
+
for (const stackLine of String(e.error.stack).split("\n")) {
|
|
374
|
+
lines.push(` ${stackLine}`);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
lines.push("");
|
|
378
|
+
}
|
|
379
|
+
lines.push(" Request Headers:");
|
|
380
|
+
this.appendHeadersBlock(lines, e.requestHeaders);
|
|
381
|
+
lines.push("");
|
|
382
|
+
lines.push(" Request Body:");
|
|
383
|
+
this.appendBodyBlock(lines, e.requestBody, width);
|
|
384
|
+
lines.push("");
|
|
385
|
+
lines.push(" Response Headers:");
|
|
386
|
+
this.appendHeadersBlock(lines, e.responseHeaders);
|
|
387
|
+
lines.push("");
|
|
388
|
+
lines.push(" Response Body:");
|
|
389
|
+
this.appendBodyBlock(lines, e.responseBody, width);
|
|
390
|
+
return lines;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Append a flat key/value list of headers to a line buffer.
|
|
394
|
+
*
|
|
395
|
+
* @param lines - target line buffer that receives the formatted lines
|
|
396
|
+
* @param headers - header map to render, may be undefined
|
|
397
|
+
*/
|
|
398
|
+
appendHeadersBlock(lines, headers) {
|
|
399
|
+
if (!headers) {
|
|
400
|
+
lines.push(" (not captured)");
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
const keys = Object.keys(headers).sort();
|
|
404
|
+
if (keys.length === 0) {
|
|
405
|
+
lines.push(" (none)");
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
for (const k of keys) {
|
|
409
|
+
lines.push(` ${k}: ${headers[k]}`);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
/**
|
|
413
|
+
* Append a body capture (text / text-truncated / binary / empty) to the
|
|
414
|
+
* line buffer, wrapping long lines to the terminal width.
|
|
415
|
+
*
|
|
416
|
+
* @param lines - target line buffer that receives the formatted lines
|
|
417
|
+
* @param body - the captured body record (or undefined)
|
|
418
|
+
* @param width - terminal width in columns, used for line wrapping
|
|
419
|
+
*/
|
|
420
|
+
appendBodyBlock(lines, body, width) {
|
|
421
|
+
if (!body) {
|
|
422
|
+
lines.push(" (not captured)");
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
if (body.kind === "empty") {
|
|
426
|
+
lines.push(" (empty)");
|
|
427
|
+
return;
|
|
428
|
+
}
|
|
429
|
+
if (body.kind === "binary") {
|
|
430
|
+
lines.push(` Binary, ${this.formatBytes(body.size)} (preview: 0x${body.preview || ""})`);
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
// text or text-truncated — render content with a 4-space indent, wrap at width
|
|
434
|
+
const content = body.content || "";
|
|
435
|
+
const wrapWidth = Math.max(20, width - 6);
|
|
436
|
+
for (const rawLine of content.split("\n")) {
|
|
437
|
+
if (rawLine.length <= wrapWidth) {
|
|
438
|
+
lines.push(` ${rawLine}`);
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
for (let i = 0; i < rawLine.length; i += wrapWidth) {
|
|
442
|
+
lines.push(` ${rawLine.substring(i, i + wrapWidth)}`);
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
if (body.kind === "text-truncated") {
|
|
447
|
+
lines.push(` [truncated — total ${this.formatBytes(body.size)}]`);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Render an HTTP method with appropriate color.
|
|
452
|
+
* @param term - terminal-kit instance
|
|
453
|
+
* @param method - padded method string to render
|
|
454
|
+
*/
|
|
455
|
+
renderMethod(term, method) {
|
|
456
|
+
const m = method.trim().toUpperCase();
|
|
457
|
+
if (m === "GET")
|
|
458
|
+
term.green(method);
|
|
459
|
+
else if (m === "POST")
|
|
460
|
+
term.cyan(method);
|
|
461
|
+
else if (m === "PUT")
|
|
462
|
+
term.yellow(method);
|
|
463
|
+
else if (m === "DELETE")
|
|
464
|
+
term.red(method);
|
|
465
|
+
else if (m === "PATCH")
|
|
466
|
+
term.magenta(method);
|
|
467
|
+
else
|
|
468
|
+
term(method);
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Format a timestamp as HH:MM:SS.
|
|
472
|
+
* @param ts - Unix timestamp in milliseconds
|
|
473
|
+
* @returns formatted time string
|
|
474
|
+
*/
|
|
475
|
+
formatTime(ts) {
|
|
476
|
+
const d = new Date(ts);
|
|
477
|
+
return (String(d.getHours()).padStart(2, "0") +
|
|
478
|
+
":" +
|
|
479
|
+
String(d.getMinutes()).padStart(2, "0") +
|
|
480
|
+
":" +
|
|
481
|
+
String(d.getSeconds()).padStart(2, "0"));
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Format a byte count for display in the detail view.
|
|
485
|
+
*
|
|
486
|
+
* @param n - byte count, possibly undefined
|
|
487
|
+
* @returns formatted human-readable byte count (e.g. "12.3 KB")
|
|
488
|
+
*/
|
|
489
|
+
formatBytes(n) {
|
|
490
|
+
if (n == null)
|
|
491
|
+
return "?";
|
|
492
|
+
if (n < 1024)
|
|
493
|
+
return `${n} B`;
|
|
494
|
+
if (n < 1024 * 1024)
|
|
495
|
+
return `${(n / 1024).toFixed(1)} KB`;
|
|
496
|
+
return `${(n / (1024 * 1024)).toFixed(2)} MB`;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Clean up panel resources and unsubscribe from events.
|
|
500
|
+
*/
|
|
501
|
+
destroy() {
|
|
502
|
+
if (this.unsubscribe) {
|
|
503
|
+
this.unsubscribe();
|
|
504
|
+
this.unsubscribe = undefined;
|
|
505
|
+
}
|
|
506
|
+
this.entries = [];
|
|
507
|
+
this.byId.clear();
|
|
508
|
+
this.detail = null;
|
|
509
|
+
this.detailId = null;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
//# sourceMappingURL=requests.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/tui/panels/requests.ts"],"names":[],"mappings":"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"}
|