@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.
Files changed (66) hide show
  1. package/LICENSE +166 -0
  2. package/README.md +95 -0
  3. package/lib/bodycapture.d.ts +66 -0
  4. package/lib/bodycapture.js +162 -0
  5. package/lib/bodycapture.js.map +1 -0
  6. package/lib/debugservice.service.d.ts +166 -0
  7. package/lib/debugservice.service.js +609 -0
  8. package/lib/debugservice.service.js.map +1 -0
  9. package/lib/index.d.ts +7 -0
  10. package/lib/index.js +7 -0
  11. package/lib/index.js.map +1 -0
  12. package/lib/introspection.d.ts +115 -0
  13. package/lib/introspection.js +260 -0
  14. package/lib/introspection.js.map +1 -0
  15. package/lib/logbuffer.d.ts +75 -0
  16. package/lib/logbuffer.js +98 -0
  17. package/lib/logbuffer.js.map +1 -0
  18. package/lib/requestlog.d.ts +181 -0
  19. package/lib/requestlog.js +153 -0
  20. package/lib/requestlog.js.map +1 -0
  21. package/lib/tui/client.d.ts +165 -0
  22. package/lib/tui/client.js +220 -0
  23. package/lib/tui/client.js.map +1 -0
  24. package/lib/tui/panels/config.d.ts +79 -0
  25. package/lib/tui/panels/config.js +291 -0
  26. package/lib/tui/panels/config.js.map +1 -0
  27. package/lib/tui/panels/logs.d.ts +106 -0
  28. package/lib/tui/panels/logs.js +342 -0
  29. package/lib/tui/panels/logs.js.map +1 -0
  30. package/lib/tui/panels/models.d.ts +47 -0
  31. package/lib/tui/panels/models.js +193 -0
  32. package/lib/tui/panels/models.js.map +1 -0
  33. package/lib/tui/panels/operations.d.ts +55 -0
  34. package/lib/tui/panels/operations.js +241 -0
  35. package/lib/tui/panels/operations.js.map +1 -0
  36. package/lib/tui/panels/panel.d.ts +55 -0
  37. package/lib/tui/panels/panel.js +31 -0
  38. package/lib/tui/panels/panel.js.map +1 -0
  39. package/lib/tui/panels/requests.d.ts +156 -0
  40. package/lib/tui/panels/requests.js +512 -0
  41. package/lib/tui/panels/requests.js.map +1 -0
  42. package/lib/tui/panels/routes.d.ts +45 -0
  43. package/lib/tui/panels/routes.js +154 -0
  44. package/lib/tui/panels/routes.js.map +1 -0
  45. package/lib/tui/panels/services.d.ts +49 -0
  46. package/lib/tui/panels/services.js +266 -0
  47. package/lib/tui/panels/services.js.map +1 -0
  48. package/lib/tui/tui.d.ts +58 -0
  49. package/lib/tui/tui.js +236 -0
  50. package/lib/tui/tui.js.map +1 -0
  51. package/package.json +60 -0
  52. package/webui/app.js +177 -0
  53. package/webui/components/logs.js +128 -0
  54. package/webui/components/model-graph.js +292 -0
  55. package/webui/components/models.js +213 -0
  56. package/webui/components/operations.js +315 -0
  57. package/webui/components/requests.js +264 -0
  58. package/webui/components/schema-form.js +268 -0
  59. package/webui/components/services.js +248 -0
  60. package/webui/index.html +22 -0
  61. package/webui/logo.svg +1 -0
  62. package/webui/styles.css +685 -0
  63. package/webui/vendor/htm.js +1 -0
  64. package/webui/vendor/preact-hooks.js +2 -0
  65. package/webui/vendor/preact.js +2 -0
  66. package/webui/webda.png +0 -0
@@ -0,0 +1,106 @@
1
+ import type { Panel } from "./panel.js";
2
+ import type { DebugClient, WsEvent } from "../client.js";
3
+ /**
4
+ * Logs panel: displays application log entries with color-coded
5
+ * levels and search filtering. Receives live log events via
6
+ * WebSocket and allows searching with `/`.
7
+ */
8
+ export declare class LogsPanel implements Panel {
9
+ private client;
10
+ name: string;
11
+ private entries;
12
+ private cursor;
13
+ private scrollOffset;
14
+ private visibleRows;
15
+ private searchQuery;
16
+ private searchMode;
17
+ /** Current minimum log level filter */
18
+ private levelFilter;
19
+ /** Maximum entries to keep in memory */
20
+ private maxEntries;
21
+ /** Persisted TUI state file — survives across `webda debug` restarts */
22
+ private static readonly STATE_FILE;
23
+ /**
24
+ * @param client - Debug API client
25
+ */
26
+ constructor(client: DebugClient);
27
+ /**
28
+ * Restore the log level filter from `.webda/debug-state.json` if present.
29
+ * Silent on any failure — stale/corrupt state falls back to the INFO default.
30
+ */
31
+ private loadState;
32
+ /**
33
+ * Persist the current log level filter. Creates `.webda/` on demand.
34
+ * Silent on failure — the user can still use the TUI without persistence.
35
+ */
36
+ private saveState;
37
+ /**
38
+ * Fetch existing log entries from the server.
39
+ */
40
+ refresh(): Promise<void>;
41
+ /**
42
+ * Handle a WebSocket event. Adds log events to the entries list.
43
+ *
44
+ * @param event - WebSocket event to process
45
+ */
46
+ onWsEvent(event: WsEvent): void;
47
+ /**
48
+ * Convert a raw log object to a display entry.
49
+ *
50
+ * @param raw - raw log data from API or WebSocket
51
+ * @returns formatted log entry
52
+ */
53
+ private toLogEntry;
54
+ /**
55
+ * Format a timestamp as HH:MM:SS.mmm.
56
+ *
57
+ * @param ts - Unix timestamp in milliseconds
58
+ * @returns formatted time string
59
+ */
60
+ private formatTime;
61
+ /**
62
+ * Log level severity order — higher index means more severe.
63
+ */
64
+ private static readonly LOG_LEVELS;
65
+ /**
66
+ * Get entries filtered by the current log level and optional search query.
67
+ * Level filter is always applied. Text search is additional.
68
+ *
69
+ * @returns filtered log entries
70
+ */
71
+ private getFilteredEntries;
72
+ /**
73
+ * Cycle the log level filter to the next level.
74
+ */
75
+ private cycleLevelUp;
76
+ /**
77
+ * Cycle the log level filter to the previous level.
78
+ */
79
+ private cycleLevelDown;
80
+ /**
81
+ * Handle keyboard input for scrolling and search.
82
+ *
83
+ * @param key - key name from terminal-kit
84
+ */
85
+ onKey(key: string): void;
86
+ /**
87
+ * Render the log entries with color-coded levels and optional search bar.
88
+ *
89
+ * @param term - terminal-kit instance
90
+ * @param startRow - first available row
91
+ * @param endRow - last available row
92
+ * @param width - terminal width in columns
93
+ */
94
+ render(term: any, startRow: number, endRow: number, width: number): void;
95
+ /**
96
+ * Render a log level with appropriate color.
97
+ *
98
+ * @param term - terminal-kit instance
99
+ * @param level - log level string
100
+ */
101
+ private renderLevel;
102
+ /**
103
+ * Clean up panel resources.
104
+ */
105
+ destroy(): void;
106
+ }
@@ -0,0 +1,342 @@
1
+ import { readFileSync, writeFileSync, mkdirSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ /**
4
+ * Logs panel: displays application log entries with color-coded
5
+ * levels and search filtering. Receives live log events via
6
+ * WebSocket and allows searching with `/`.
7
+ */
8
+ export class LogsPanel {
9
+ /**
10
+ * @param client - Debug API client
11
+ */
12
+ constructor(client) {
13
+ this.client = client;
14
+ this.name = "Logs";
15
+ this.entries = [];
16
+ this.cursor = 0;
17
+ this.scrollOffset = 0;
18
+ this.visibleRows = 0;
19
+ this.searchQuery = "";
20
+ this.searchMode = false;
21
+ /** Current minimum log level filter */
22
+ this.levelFilter = 2; // Index into LOG_LEVELS, default INFO
23
+ /** Maximum entries to keep in memory */
24
+ this.maxEntries = 2000;
25
+ this.loadState();
26
+ }
27
+ /**
28
+ * Restore the log level filter from `.webda/debug-state.json` if present.
29
+ * Silent on any failure — stale/corrupt state falls back to the INFO default.
30
+ */
31
+ loadState() {
32
+ try {
33
+ const raw = readFileSync(LogsPanel.STATE_FILE, "utf8");
34
+ const state = JSON.parse(raw);
35
+ const idx = LogsPanel.LOG_LEVELS.indexOf(state.logLevel);
36
+ if (idx >= 0)
37
+ this.levelFilter = idx;
38
+ }
39
+ catch {
40
+ /* no prior state — keep default */
41
+ }
42
+ }
43
+ /**
44
+ * Persist the current log level filter. Creates `.webda/` on demand.
45
+ * Silent on failure — the user can still use the TUI without persistence.
46
+ */
47
+ saveState() {
48
+ try {
49
+ mkdirSync(".webda", { recursive: true });
50
+ writeFileSync(LogsPanel.STATE_FILE, JSON.stringify({ logLevel: LogsPanel.LOG_LEVELS[this.levelFilter] }));
51
+ }
52
+ catch {
53
+ /* non-fatal — TUI keeps working without persistence */
54
+ }
55
+ }
56
+ /**
57
+ * Fetch existing log entries from the server.
58
+ */
59
+ async refresh() {
60
+ try {
61
+ const logs = await this.client.getLogs();
62
+ this.entries = logs.map((entry) => this.toLogEntry(entry)).reverse();
63
+ }
64
+ catch {
65
+ this.entries = [];
66
+ }
67
+ }
68
+ /**
69
+ * Handle a WebSocket event. Adds log events to the entries list.
70
+ *
71
+ * @param event - WebSocket event to process
72
+ */
73
+ onWsEvent(event) {
74
+ if (event.type === "log") {
75
+ const logEvent = event;
76
+ this.entries.unshift(this.toLogEntry(logEvent));
77
+ if (this.entries.length > this.maxEntries) {
78
+ this.entries.pop();
79
+ }
80
+ }
81
+ }
82
+ /**
83
+ * Convert a raw log object to a display entry.
84
+ *
85
+ * @param raw - raw log data from API or WebSocket
86
+ * @returns formatted log entry
87
+ */
88
+ toLogEntry(raw) {
89
+ const ts = raw.timestamp || Date.now();
90
+ return {
91
+ time: this.formatTime(ts),
92
+ level: (raw.level || "INFO").toUpperCase(),
93
+ message: raw.message || raw.msg || String(raw),
94
+ timestamp: ts
95
+ };
96
+ }
97
+ /**
98
+ * Format a timestamp as HH:MM:SS.mmm.
99
+ *
100
+ * @param ts - Unix timestamp in milliseconds
101
+ * @returns formatted time string
102
+ */
103
+ formatTime(ts) {
104
+ const d = new Date(ts);
105
+ return (String(d.getHours()).padStart(2, "0") +
106
+ ":" +
107
+ String(d.getMinutes()).padStart(2, "0") +
108
+ ":" +
109
+ String(d.getSeconds()).padStart(2, "0") +
110
+ "." +
111
+ String(d.getMilliseconds()).padStart(3, "0"));
112
+ }
113
+ /**
114
+ * Get entries filtered by the current log level and optional search query.
115
+ * Level filter is always applied. Text search is additional.
116
+ *
117
+ * @returns filtered log entries
118
+ */
119
+ getFilteredEntries() {
120
+ // Always filter by minimum level
121
+ let result = this.entries.filter(entry => LogsPanel.LOG_LEVELS.indexOf(entry.level) >= this.levelFilter);
122
+ // Apply text search if active
123
+ if (this.searchQuery) {
124
+ const lq = this.searchQuery.toLowerCase();
125
+ result = result.filter(entry => entry.message.toLowerCase().includes(lq) || entry.level.toLowerCase().includes(lq));
126
+ }
127
+ return result;
128
+ }
129
+ /**
130
+ * Cycle the log level filter to the next level.
131
+ */
132
+ cycleLevelUp() {
133
+ this.levelFilter = Math.min(LogsPanel.LOG_LEVELS.length - 1, this.levelFilter + 1);
134
+ this.cursor = 0;
135
+ this.scrollOffset = 0;
136
+ this.saveState();
137
+ }
138
+ /**
139
+ * Cycle the log level filter to the previous level.
140
+ */
141
+ cycleLevelDown() {
142
+ this.levelFilter = Math.max(0, this.levelFilter - 1);
143
+ this.cursor = 0;
144
+ this.scrollOffset = 0;
145
+ this.saveState();
146
+ }
147
+ /**
148
+ * Handle keyboard input for scrolling and search.
149
+ *
150
+ * @param key - key name from terminal-kit
151
+ */
152
+ onKey(key) {
153
+ if (key === "/") {
154
+ this.searchMode = true;
155
+ this.searchQuery = "";
156
+ return;
157
+ }
158
+ // Level filter: l/+ to increase severity, L/- to decrease
159
+ if (key === "l" || key === "+") {
160
+ this.cycleLevelUp();
161
+ return;
162
+ }
163
+ if (key === "L" || key === "-") {
164
+ this.cycleLevelDown();
165
+ return;
166
+ }
167
+ if (this.searchMode) {
168
+ if (key === "ENTER") {
169
+ this.searchMode = false;
170
+ this.cursor = 0;
171
+ this.scrollOffset = 0;
172
+ }
173
+ else if (key === "ESCAPE") {
174
+ this.searchMode = false;
175
+ this.searchQuery = "";
176
+ this.cursor = 0;
177
+ this.scrollOffset = 0;
178
+ }
179
+ else if (key === "BACKSPACE") {
180
+ this.searchQuery = this.searchQuery.slice(0, -1);
181
+ }
182
+ else if (key.length === 1) {
183
+ this.searchQuery += key;
184
+ }
185
+ return;
186
+ }
187
+ const filtered = this.getFilteredEntries();
188
+ switch (key) {
189
+ case "UP":
190
+ if (this.cursor > 0)
191
+ this.cursor--;
192
+ break;
193
+ case "DOWN":
194
+ if (this.cursor < filtered.length - 1)
195
+ this.cursor++;
196
+ break;
197
+ case "PAGE_UP":
198
+ this.cursor = Math.max(0, this.cursor - this.visibleRows);
199
+ break;
200
+ case "PAGE_DOWN":
201
+ this.cursor = Math.min(filtered.length - 1, this.cursor + this.visibleRows);
202
+ break;
203
+ case "HOME":
204
+ this.cursor = 0;
205
+ this.scrollOffset = 0;
206
+ break;
207
+ case "END":
208
+ this.cursor = Math.max(0, filtered.length - 1);
209
+ break;
210
+ }
211
+ // Adjust scroll to keep cursor visible
212
+ if (this.cursor < this.scrollOffset) {
213
+ this.scrollOffset = this.cursor;
214
+ }
215
+ else if (this.cursor >= this.scrollOffset + this.visibleRows) {
216
+ this.scrollOffset = this.cursor - this.visibleRows + 1;
217
+ }
218
+ }
219
+ /**
220
+ * Render the log entries with color-coded levels and optional search bar.
221
+ *
222
+ * @param term - terminal-kit instance
223
+ * @param startRow - first available row
224
+ * @param endRow - last available row
225
+ * @param width - terminal width in columns
226
+ */
227
+ render(term, startRow, endRow, width) {
228
+ // Level filter bar (always visible, first row)
229
+ term.moveTo(1, startRow);
230
+ term.eraseLine();
231
+ term.dim(" Level: ");
232
+ for (let i = 0; i < LogsPanel.LOG_LEVELS.length; i++) {
233
+ const lvl = LogsPanel.LOG_LEVELS[i];
234
+ if (i === this.levelFilter) {
235
+ term.bgCyan.black.bold(` ${lvl} `);
236
+ }
237
+ else if (i < this.levelFilter) {
238
+ term.dim(` ${lvl} `);
239
+ }
240
+ else {
241
+ this.renderLevel(term, lvl);
242
+ }
243
+ term(" ");
244
+ }
245
+ term.dim(" (l/+ more, L/- less)");
246
+ const contentStart = startRow + 1;
247
+ // Reserve one row for search bar when in search mode
248
+ const searchBarRow = this.searchMode ? endRow - 1 : -1;
249
+ const contentEnd = this.searchMode ? endRow - 1 : endRow;
250
+ this.visibleRows = contentEnd - contentStart;
251
+ const filtered = this.getFilteredEntries();
252
+ // Clamp cursor
253
+ if (filtered.length > 0 && this.cursor >= filtered.length) {
254
+ this.cursor = filtered.length - 1;
255
+ }
256
+ if (filtered.length === 0) {
257
+ term.moveTo(1, contentStart);
258
+ term.eraseLine();
259
+ if (this.searchQuery) {
260
+ term(` No logs matching "${this.searchQuery}"`);
261
+ }
262
+ else {
263
+ term(" No log entries. Press / to search.");
264
+ }
265
+ }
266
+ else {
267
+ for (let i = 0; i < this.visibleRows; i++) {
268
+ const idx = this.scrollOffset + i;
269
+ const row = contentStart + i;
270
+ term.moveTo(1, row);
271
+ term.eraseLine();
272
+ if (idx >= filtered.length)
273
+ continue;
274
+ const entry = filtered[idx];
275
+ const isCurrent = idx === this.cursor;
276
+ if (isCurrent) {
277
+ term.bgGray();
278
+ }
279
+ // Timestamp
280
+ term.dim(` ${entry.time} `);
281
+ // Level with color
282
+ this.renderLevel(term, entry.level);
283
+ // Message (truncated to fit)
284
+ const prefixLen = 2 + 12 + 1 + 6 + 1;
285
+ const maxMsgLen = Math.max(10, width - prefixLen);
286
+ const msg = entry.message.length > maxMsgLen ? entry.message.substring(0, maxMsgLen - 3) + "..." : entry.message;
287
+ term(` ${msg}`);
288
+ if (isCurrent) {
289
+ term.styleReset();
290
+ }
291
+ }
292
+ }
293
+ // Search bar
294
+ if (this.searchMode && searchBarRow > 0) {
295
+ term.moveTo(1, searchBarRow);
296
+ term.eraseLine();
297
+ term.bgBlue.white(` Search: ${this.searchQuery}_ `);
298
+ term.styleReset();
299
+ }
300
+ }
301
+ /**
302
+ * Render a log level with appropriate color.
303
+ *
304
+ * @param term - terminal-kit instance
305
+ * @param level - log level string
306
+ */
307
+ renderLevel(term, level) {
308
+ const padded = level.padEnd(5);
309
+ switch (level) {
310
+ case "ERROR":
311
+ term.red.bold(padded);
312
+ break;
313
+ case "WARN":
314
+ term.yellow(padded);
315
+ break;
316
+ case "INFO":
317
+ term.green(padded);
318
+ break;
319
+ case "DEBUG":
320
+ term.cyan(padded);
321
+ break;
322
+ case "TRACE":
323
+ term.dim(padded);
324
+ break;
325
+ default:
326
+ term(padded);
327
+ }
328
+ }
329
+ /**
330
+ * Clean up panel resources.
331
+ */
332
+ destroy() {
333
+ this.entries = [];
334
+ }
335
+ }
336
+ /** Persisted TUI state file — survives across `webda debug` restarts */
337
+ LogsPanel.STATE_FILE = join(".webda", "debug-state.json");
338
+ /**
339
+ * Log level severity order — higher index means more severe.
340
+ */
341
+ LogsPanel.LOG_LEVELS = ["TRACE", "DEBUG", "INFO", "WARN", "ERROR"];
342
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../../src/tui/panels/logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { ScrollablePanel } from "./panel.js";
2
+ import { DebugClient } from "../client.js";
3
+ /**
4
+ * Models panel: displays registered models in a scrollable list.
5
+ * Press Enter to toggle detail view showing schema, relations, and actions.
6
+ */
7
+ export declare class ModelsPanel extends ScrollablePanel {
8
+ private client;
9
+ name: string;
10
+ private models;
11
+ private detailMode;
12
+ /** Number of visible rows in the viewport (updated on render) */
13
+ private visibleRows;
14
+ /**
15
+ * @param client - Debug API client
16
+ */
17
+ constructor(client: DebugClient);
18
+ /**
19
+ * Fetch models from the debug server.
20
+ */
21
+ refresh(): Promise<void>;
22
+ /**
23
+ * Handle keyboard input.
24
+ * @param key - key name from terminal-kit
25
+ */
26
+ onKey(key: string): void;
27
+ /**
28
+ * Render the models list or detail view.
29
+ * @param term - terminal-kit instance
30
+ * @param startRow - first available row
31
+ * @param endRow - last available row
32
+ * @param width - terminal width in columns
33
+ */
34
+ render(term: any, startRow: number, endRow: number, width: number): void;
35
+ /**
36
+ * Render detail view for the selected model.
37
+ * @param term - terminal-kit instance
38
+ * @param startRow - first available row
39
+ * @param endRow - last available row
40
+ * @param width - terminal width in columns
41
+ */
42
+ private renderDetail;
43
+ /**
44
+ * Clean up panel resources.
45
+ */
46
+ destroy(): void;
47
+ }