network-terminal 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.
package/dist/index.js ADDED
@@ -0,0 +1,759 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ LogEntry: () => LogEntry,
24
+ NetworkTerminal: () => NetworkTerminal,
25
+ Terminal: () => Terminal,
26
+ TerminalHeader: () => TerminalHeader,
27
+ formatJson: () => formatJson,
28
+ formatTime: () => formatTime,
29
+ getMethodColor: () => getMethodColor,
30
+ getStatusColor: () => getStatusColor,
31
+ truncate: () => truncate,
32
+ useNetworkInterceptor: () => useNetworkInterceptor
33
+ });
34
+ module.exports = __toCommonJS(index_exports);
35
+
36
+ // src/components/NetworkTerminal.tsx
37
+ var import_react3 = require("react");
38
+
39
+ // src/components/Terminal.tsx
40
+ var import_react = require("react");
41
+
42
+ // src/components/TerminalHeader.tsx
43
+ var import_jsx_runtime = require("react/jsx-runtime");
44
+ var styles = {
45
+ header: {
46
+ display: "flex",
47
+ alignItems: "center",
48
+ justifyContent: "space-between",
49
+ padding: "8px 16px",
50
+ backgroundColor: "#1f2937",
51
+ borderBottom: "1px solid #374151"
52
+ },
53
+ left: {
54
+ display: "flex",
55
+ alignItems: "center",
56
+ gap: "8px"
57
+ },
58
+ trafficLights: {
59
+ display: "flex",
60
+ gap: "6px"
61
+ },
62
+ dot: {
63
+ width: "12px",
64
+ height: "12px",
65
+ borderRadius: "50%"
66
+ },
67
+ title: {
68
+ color: "#d1d5db",
69
+ fontFamily: "monospace",
70
+ fontSize: "14px",
71
+ marginLeft: "8px"
72
+ },
73
+ count: {
74
+ color: "#6b7280",
75
+ fontFamily: "monospace",
76
+ fontSize: "12px"
77
+ },
78
+ right: {
79
+ display: "flex",
80
+ alignItems: "center",
81
+ gap: "8px"
82
+ },
83
+ button: {
84
+ color: "#9ca3af",
85
+ fontSize: "12px",
86
+ fontFamily: "monospace",
87
+ padding: "4px 8px",
88
+ borderRadius: "4px",
89
+ border: "none",
90
+ background: "transparent",
91
+ cursor: "pointer"
92
+ }
93
+ };
94
+ var TerminalHeader = ({
95
+ title,
96
+ count,
97
+ expanded,
98
+ onClear,
99
+ onToggleExpand
100
+ }) => {
101
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.header, children: [
102
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.left, children: [
103
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.trafficLights, children: [
104
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.dot, backgroundColor: "#ef4444" } }),
105
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.dot, backgroundColor: "#eab308" } }),
106
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { ...styles.dot, backgroundColor: "#22c55e" } })
107
+ ] }),
108
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: styles.title, children: title }),
109
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { style: styles.count, children: [
110
+ "(",
111
+ count,
112
+ " entries)"
113
+ ] })
114
+ ] }),
115
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: styles.right, children: [
116
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
117
+ "button",
118
+ {
119
+ onClick: onClear,
120
+ style: styles.button,
121
+ onMouseEnter: (e) => e.currentTarget.style.color = "#fff",
122
+ onMouseLeave: (e) => e.currentTarget.style.color = "#9ca3af",
123
+ children: "Clear"
124
+ }
125
+ ),
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
127
+ "button",
128
+ {
129
+ onClick: onToggleExpand,
130
+ style: styles.button,
131
+ onMouseEnter: (e) => e.currentTarget.style.color = "#fff",
132
+ onMouseLeave: (e) => e.currentTarget.style.color = "#9ca3af",
133
+ children: expanded ? "\u25BC" : "\u25B2"
134
+ }
135
+ )
136
+ ] })
137
+ ] });
138
+ };
139
+
140
+ // src/utils/formatters.ts
141
+ var formatJson = (data) => {
142
+ if (!data) return "";
143
+ try {
144
+ if (typeof data === "string") {
145
+ const parsed = JSON.parse(data);
146
+ return JSON.stringify(parsed, null, 2);
147
+ }
148
+ return JSON.stringify(data, null, 2);
149
+ } catch {
150
+ return String(data);
151
+ }
152
+ };
153
+ var truncate = (str, maxLength) => {
154
+ if (str.length <= maxLength) return str;
155
+ return str.slice(0, maxLength) + "...";
156
+ };
157
+ var formatTime = (date) => {
158
+ return date.toLocaleTimeString("en-US", {
159
+ hour12: false,
160
+ hour: "2-digit",
161
+ minute: "2-digit",
162
+ second: "2-digit"
163
+ });
164
+ };
165
+
166
+ // src/utils/colors.ts
167
+ var getStatusColor = (status) => {
168
+ if (!status) return "#9ca3af";
169
+ if (status >= 200 && status < 300) return "#4ade80";
170
+ if (status >= 300 && status < 400) return "#facc15";
171
+ if (status >= 400 && status < 500) return "#fb923c";
172
+ return "#f87171";
173
+ };
174
+ var getMethodColor = (method) => {
175
+ const colors = {
176
+ GET: "#22d3ee",
177
+ // cyan-400
178
+ POST: "#4ade80",
179
+ // green-400
180
+ PUT: "#facc15",
181
+ // yellow-400
182
+ PATCH: "#fb923c",
183
+ // orange-400
184
+ DELETE: "#f87171"
185
+ // red-400
186
+ };
187
+ return colors[method.toUpperCase()] || "#9ca3af";
188
+ };
189
+
190
+ // src/components/LogEntry.tsx
191
+ var import_jsx_runtime2 = require("react/jsx-runtime");
192
+ var styles2 = {
193
+ container: {
194
+ marginBottom: "16px",
195
+ borderBottom: "1px solid #1f2937",
196
+ paddingBottom: "16px"
197
+ },
198
+ header: {
199
+ display: "flex",
200
+ alignItems: "center",
201
+ gap: "8px",
202
+ marginBottom: "4px",
203
+ flexWrap: "wrap"
204
+ },
205
+ timestamp: {
206
+ color: "#6b7280",
207
+ fontSize: "12px",
208
+ fontFamily: "monospace"
209
+ },
210
+ method: {
211
+ fontWeight: "bold",
212
+ fontFamily: "monospace"
213
+ },
214
+ status: {
215
+ fontWeight: "bold",
216
+ fontFamily: "monospace"
217
+ },
218
+ duration: {
219
+ color: "#6b7280",
220
+ fontSize: "12px",
221
+ fontFamily: "monospace"
222
+ },
223
+ url: {
224
+ color: "#60a5fa",
225
+ wordBreak: "break-all",
226
+ marginBottom: "8px",
227
+ fontFamily: "monospace",
228
+ fontSize: "13px"
229
+ },
230
+ bodyContainer: {
231
+ marginTop: "8px"
232
+ },
233
+ bodyLabel: {
234
+ color: "#a78bfa",
235
+ fontSize: "12px",
236
+ marginBottom: "4px",
237
+ fontFamily: "monospace"
238
+ },
239
+ pre: {
240
+ backgroundColor: "#1f2937",
241
+ padding: "8px",
242
+ borderRadius: "4px",
243
+ color: "#86efac",
244
+ overflowX: "auto",
245
+ fontSize: "12px",
246
+ whiteSpace: "pre-wrap",
247
+ fontFamily: "monospace",
248
+ maxHeight: "192px",
249
+ overflowY: "auto",
250
+ margin: 0
251
+ },
252
+ errorPre: {
253
+ backgroundColor: "#1f2937",
254
+ padding: "8px",
255
+ borderRadius: "4px",
256
+ color: "#fca5a5",
257
+ overflowX: "auto",
258
+ fontSize: "12px",
259
+ whiteSpace: "pre-wrap",
260
+ fontFamily: "monospace",
261
+ margin: 0
262
+ }
263
+ };
264
+ var LogEntry = ({ log, type }) => {
265
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.container, children: [
266
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.header, children: [
267
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles2.timestamp, children: [
268
+ "[",
269
+ formatTime(log.timestamp),
270
+ "]"
271
+ ] }),
272
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { ...styles2.method, color: getMethodColor(log.method) }, children: log.method }),
273
+ type === "response" && log.status && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { ...styles2.status, color: getStatusColor(log.status) }, children: [
274
+ log.status,
275
+ " ",
276
+ log.statusText
277
+ ] }),
278
+ log.duration !== void 0 && type === "response" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: styles2.duration, children: [
279
+ "(",
280
+ log.duration,
281
+ "ms)"
282
+ ] })
283
+ ] }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: styles2.url, children: log.url }),
285
+ type === "request" ? log.requestBody ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.bodyContainer, children: [
286
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.bodyLabel, children: [
287
+ "\u25B8",
288
+ " Payload:"
289
+ ] }),
290
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { style: styles2.pre, children: formatJson(log.requestBody) })
291
+ ] }) : null : log.error ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.bodyContainer, children: [
292
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { ...styles2.bodyLabel, color: "#f87171" }, children: [
293
+ "\u25B8",
294
+ " Error:"
295
+ ] }),
296
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { style: styles2.errorPre, children: log.error })
297
+ ] }) : log.responseBody ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.bodyContainer, children: [
298
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: styles2.bodyLabel, children: [
299
+ "\u25B8",
300
+ " Response:"
301
+ ] }),
302
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { style: styles2.pre, children: formatJson(log.responseBody) })
303
+ ] }) : null
304
+ ] });
305
+ };
306
+
307
+ // src/components/Terminal.tsx
308
+ var import_jsx_runtime3 = require("react/jsx-runtime");
309
+ var styles3 = {
310
+ container: {
311
+ display: "flex",
312
+ flexDirection: "column",
313
+ backgroundColor: "#111827",
314
+ borderRadius: "8px",
315
+ border: "1px solid #374151",
316
+ overflow: "hidden",
317
+ transition: "all 0.2s",
318
+ flex: 1
319
+ },
320
+ collapsed: {
321
+ height: "48px",
322
+ flex: "none"
323
+ },
324
+ body: {
325
+ flex: 1,
326
+ overflow: "auto",
327
+ padding: "16px",
328
+ fontFamily: "monospace",
329
+ fontSize: "14px",
330
+ minHeight: "200px",
331
+ maxHeight: "400px"
332
+ },
333
+ empty: {
334
+ color: "#6b7280",
335
+ fontStyle: "italic"
336
+ }
337
+ };
338
+ var Terminal = ({
339
+ title,
340
+ logs,
341
+ type,
342
+ onClear,
343
+ expanded,
344
+ onToggleExpand
345
+ }) => {
346
+ const terminalRef = (0, import_react.useRef)(null);
347
+ const [autoScroll, setAutoScroll] = (0, import_react.useState)(true);
348
+ (0, import_react.useEffect)(() => {
349
+ if (autoScroll && terminalRef.current) {
350
+ terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
351
+ }
352
+ }, [logs, autoScroll]);
353
+ const handleScroll = () => {
354
+ if (terminalRef.current) {
355
+ const { scrollTop, scrollHeight, clientHeight } = terminalRef.current;
356
+ setAutoScroll(scrollHeight - scrollTop - clientHeight < 50);
357
+ }
358
+ };
359
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
360
+ "div",
361
+ {
362
+ style: {
363
+ ...styles3.container,
364
+ ...expanded ? {} : styles3.collapsed
365
+ },
366
+ children: [
367
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
368
+ TerminalHeader,
369
+ {
370
+ title,
371
+ count: logs.length,
372
+ expanded,
373
+ onClear,
374
+ onToggleExpand
375
+ }
376
+ ),
377
+ expanded && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { ref: terminalRef, onScroll: handleScroll, style: styles3.body, children: logs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { style: styles3.empty, children: "Waiting for network requests..." }) : logs.map((log) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LogEntry, { log, type }, log.id)) })
378
+ ]
379
+ }
380
+ );
381
+ };
382
+
383
+ // src/hooks/useNetworkInterceptor.ts
384
+ var import_react2 = require("react");
385
+ var useNetworkInterceptor = ({
386
+ enabled,
387
+ onLogAdd,
388
+ onLogUpdate
389
+ }) => {
390
+ const originalFetch = (0, import_react2.useRef)(null);
391
+ const originalXHROpen = (0, import_react2.useRef)(null);
392
+ const originalXHRSend = (0, import_react2.useRef)(null);
393
+ const generateId = (0, import_react2.useCallback)((prefix) => {
394
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
395
+ }, []);
396
+ (0, import_react2.useEffect)(() => {
397
+ if (!enabled) return;
398
+ originalFetch.current = window.fetch;
399
+ window.fetch = async function(input, init) {
400
+ const id = generateId("fetch");
401
+ const startTime = performance.now();
402
+ const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
403
+ const method = init?.method || "GET";
404
+ let requestBody = null;
405
+ if (init?.body) {
406
+ try {
407
+ requestBody = typeof init.body === "string" ? JSON.parse(init.body) : init.body;
408
+ } catch {
409
+ requestBody = init.body;
410
+ }
411
+ }
412
+ onLogAdd({
413
+ id,
414
+ timestamp: /* @__PURE__ */ new Date(),
415
+ method: method.toUpperCase(),
416
+ url,
417
+ requestBody,
418
+ type: "fetch"
419
+ });
420
+ try {
421
+ const response = await originalFetch.current(input, init);
422
+ const duration = Math.round(performance.now() - startTime);
423
+ const clonedResponse = response.clone();
424
+ let responseBody = null;
425
+ try {
426
+ responseBody = await clonedResponse.json();
427
+ } catch {
428
+ try {
429
+ responseBody = await clonedResponse.text();
430
+ } catch {
431
+ responseBody = "[Could not read response body]";
432
+ }
433
+ }
434
+ onLogUpdate(id, {
435
+ status: response.status,
436
+ statusText: response.statusText,
437
+ responseBody,
438
+ duration
439
+ });
440
+ return response;
441
+ } catch (error) {
442
+ const duration = Math.round(performance.now() - startTime);
443
+ const errorMessage = error instanceof Error ? error.message : "Network Error";
444
+ onLogUpdate(id, {
445
+ error: errorMessage,
446
+ duration
447
+ });
448
+ throw error;
449
+ }
450
+ };
451
+ return () => {
452
+ if (originalFetch.current) {
453
+ window.fetch = originalFetch.current;
454
+ }
455
+ };
456
+ }, [enabled, onLogAdd, onLogUpdate, generateId]);
457
+ (0, import_react2.useEffect)(() => {
458
+ if (!enabled) return;
459
+ originalXHROpen.current = XMLHttpRequest.prototype.open;
460
+ originalXHRSend.current = XMLHttpRequest.prototype.send;
461
+ XMLHttpRequest.prototype.open = function(method, url) {
462
+ this._networkTerminal = {
463
+ id: generateId("xhr"),
464
+ method: method.toUpperCase(),
465
+ url: url.toString(),
466
+ startTime: 0,
467
+ timestamp: /* @__PURE__ */ new Date(),
468
+ type: "xhr"
469
+ };
470
+ return originalXHROpen.current.apply(
471
+ this,
472
+ arguments
473
+ );
474
+ };
475
+ XMLHttpRequest.prototype.send = function(body) {
476
+ const meta = this._networkTerminal;
477
+ if (meta) {
478
+ meta.startTime = performance.now();
479
+ let requestBody = null;
480
+ if (body) {
481
+ try {
482
+ requestBody = typeof body === "string" ? JSON.parse(body) : body;
483
+ } catch {
484
+ requestBody = body;
485
+ }
486
+ }
487
+ onLogAdd({
488
+ id: meta.id,
489
+ timestamp: /* @__PURE__ */ new Date(),
490
+ method: meta.method,
491
+ url: meta.url,
492
+ requestBody,
493
+ type: "xhr"
494
+ });
495
+ this.addEventListener("load", function() {
496
+ const duration = Math.round(performance.now() - meta.startTime);
497
+ let responseBody = null;
498
+ try {
499
+ responseBody = JSON.parse(this.responseText);
500
+ } catch {
501
+ responseBody = this.responseText;
502
+ }
503
+ onLogUpdate(meta.id, {
504
+ status: this.status,
505
+ statusText: this.statusText,
506
+ responseBody,
507
+ duration
508
+ });
509
+ });
510
+ this.addEventListener("error", function() {
511
+ const duration = Math.round(performance.now() - meta.startTime);
512
+ onLogUpdate(meta.id, {
513
+ error: "Network Error",
514
+ duration
515
+ });
516
+ });
517
+ }
518
+ return originalXHRSend.current.apply(
519
+ this,
520
+ arguments
521
+ );
522
+ };
523
+ return () => {
524
+ if (originalXHROpen.current) {
525
+ XMLHttpRequest.prototype.open = originalXHROpen.current;
526
+ }
527
+ if (originalXHRSend.current) {
528
+ XMLHttpRequest.prototype.send = originalXHRSend.current;
529
+ }
530
+ };
531
+ }, [enabled, onLogAdd, onLogUpdate, generateId]);
532
+ };
533
+
534
+ // src/components/NetworkTerminal.tsx
535
+ var import_jsx_runtime4 = require("react/jsx-runtime");
536
+ var styles4 = {
537
+ floatingButton: {
538
+ position: "fixed",
539
+ bottom: "16px",
540
+ right: "16px",
541
+ zIndex: 9999,
542
+ backgroundColor: "#1f2937",
543
+ color: "#4ade80",
544
+ padding: "8px 16px",
545
+ borderRadius: "8px",
546
+ fontFamily: "monospace",
547
+ fontSize: "14px",
548
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1)",
549
+ border: "1px solid #374151",
550
+ cursor: "pointer"
551
+ },
552
+ container: {
553
+ position: "fixed",
554
+ bottom: 0,
555
+ left: 0,
556
+ right: 0,
557
+ zIndex: 9999,
558
+ backgroundColor: "#111827",
559
+ borderTop: "2px solid #22c55e",
560
+ boxShadow: "0 -10px 15px -3px rgba(0, 0, 0, 0.1)"
561
+ },
562
+ containerTop: {
563
+ position: "fixed",
564
+ top: 0,
565
+ left: 0,
566
+ right: 0,
567
+ zIndex: 9999,
568
+ backgroundColor: "#111827",
569
+ borderBottom: "2px solid #22c55e",
570
+ boxShadow: "0 10px 15px -3px rgba(0, 0, 0, 0.1)"
571
+ },
572
+ mainHeader: {
573
+ display: "flex",
574
+ alignItems: "center",
575
+ justifyContent: "space-between",
576
+ padding: "8px 16px",
577
+ backgroundColor: "#1f2937",
578
+ borderBottom: "1px solid #374151"
579
+ },
580
+ headerLeft: {
581
+ display: "flex",
582
+ alignItems: "center",
583
+ gap: "12px"
584
+ },
585
+ title: {
586
+ color: "#4ade80",
587
+ fontFamily: "monospace",
588
+ fontWeight: "bold"
589
+ },
590
+ hint: {
591
+ color: "#6b7280",
592
+ fontFamily: "monospace",
593
+ fontSize: "12px"
594
+ },
595
+ headerRight: {
596
+ display: "flex",
597
+ alignItems: "center",
598
+ gap: "8px"
599
+ },
600
+ clearButton: {
601
+ color: "#9ca3af",
602
+ fontSize: "14px",
603
+ fontFamily: "monospace",
604
+ padding: "4px 12px",
605
+ borderRadius: "4px",
606
+ border: "none",
607
+ background: "transparent",
608
+ cursor: "pointer"
609
+ },
610
+ closeButton: {
611
+ color: "#9ca3af",
612
+ fontSize: "18px",
613
+ fontWeight: "bold",
614
+ padding: "0 8px",
615
+ border: "none",
616
+ background: "transparent",
617
+ cursor: "pointer",
618
+ borderRadius: "4px"
619
+ },
620
+ terminalsContainer: {
621
+ display: "flex",
622
+ gap: "8px",
623
+ padding: "8px",
624
+ height: "450px"
625
+ },
626
+ terminalWrapper: {
627
+ flex: 1,
628
+ display: "flex",
629
+ flexDirection: "column"
630
+ }
631
+ };
632
+ var NetworkTerminal = ({
633
+ maxLogs = 100,
634
+ defaultVisible = false,
635
+ position = "bottom",
636
+ height = "450px",
637
+ zIndex = 9999
638
+ }) => {
639
+ const [logs, setLogs] = (0, import_react3.useState)([]);
640
+ const [isVisible, setIsVisible] = (0, import_react3.useState)(defaultVisible);
641
+ const [requestExpanded, setRequestExpanded] = (0, import_react3.useState)(true);
642
+ const [responseExpanded, setResponseExpanded] = (0, import_react3.useState)(true);
643
+ const addLog = (0, import_react3.useCallback)(
644
+ (log) => {
645
+ setLogs((prev) => [...prev.slice(-(maxLogs - 1)), log]);
646
+ },
647
+ [maxLogs]
648
+ );
649
+ const updateLog = (0, import_react3.useCallback)((id, updates) => {
650
+ setLogs(
651
+ (prev) => prev.map((log) => log.id === id ? { ...log, ...updates } : log)
652
+ );
653
+ }, []);
654
+ useNetworkInterceptor({
655
+ enabled: isVisible,
656
+ onLogAdd: addLog,
657
+ onLogUpdate: updateLog
658
+ });
659
+ (0, import_react3.useEffect)(() => {
660
+ const handleKeyDown = (e) => {
661
+ if (e.ctrlKey && e.shiftKey && e.key === "N") {
662
+ e.preventDefault();
663
+ setIsVisible((prev) => !prev);
664
+ }
665
+ };
666
+ window.addEventListener("keydown", handleKeyDown);
667
+ return () => window.removeEventListener("keydown", handleKeyDown);
668
+ }, []);
669
+ const clearLogs = () => setLogs([]);
670
+ if (!isVisible) {
671
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
672
+ "button",
673
+ {
674
+ onClick: () => setIsVisible(true),
675
+ style: {
676
+ ...styles4.floatingButton,
677
+ zIndex
678
+ },
679
+ title: "Open Network Terminal (Ctrl+Shift+N)",
680
+ children: [
681
+ ">",
682
+ "_ Network"
683
+ ]
684
+ }
685
+ );
686
+ }
687
+ const containerStyle = position === "top" ? { ...styles4.containerTop, zIndex } : { ...styles4.container, zIndex };
688
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: containerStyle, children: [
689
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles4.mainHeader, children: [
690
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles4.headerLeft, children: [
691
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { style: styles4.title, children: [
692
+ ">",
693
+ "_ Network Terminal"
694
+ ] }),
695
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: styles4.hint, children: "Press Ctrl+Shift+N to toggle" })
696
+ ] }),
697
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: styles4.headerRight, children: [
698
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
699
+ "button",
700
+ {
701
+ onClick: clearLogs,
702
+ style: styles4.clearButton,
703
+ onMouseEnter: (e) => e.currentTarget.style.color = "#fff",
704
+ onMouseLeave: (e) => e.currentTarget.style.color = "#9ca3af",
705
+ children: "Clear All"
706
+ }
707
+ ),
708
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
709
+ "button",
710
+ {
711
+ onClick: () => setIsVisible(false),
712
+ style: styles4.closeButton,
713
+ onMouseEnter: (e) => e.currentTarget.style.color = "#f87171",
714
+ onMouseLeave: (e) => e.currentTarget.style.color = "#9ca3af",
715
+ children: "\xD7"
716
+ }
717
+ )
718
+ ] })
719
+ ] }),
720
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { ...styles4.terminalsContainer, height }, children: [
721
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles4.terminalWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
722
+ Terminal,
723
+ {
724
+ title: "Requests",
725
+ logs,
726
+ type: "request",
727
+ onClear: clearLogs,
728
+ expanded: requestExpanded,
729
+ onToggleExpand: () => setRequestExpanded(!requestExpanded)
730
+ }
731
+ ) }),
732
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: styles4.terminalWrapper, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
733
+ Terminal,
734
+ {
735
+ title: "Responses",
736
+ logs,
737
+ type: "response",
738
+ onClear: clearLogs,
739
+ expanded: responseExpanded,
740
+ onToggleExpand: () => setResponseExpanded(!responseExpanded)
741
+ }
742
+ ) })
743
+ ] })
744
+ ] });
745
+ };
746
+ // Annotate the CommonJS export names for ESM import in node:
747
+ 0 && (module.exports = {
748
+ LogEntry,
749
+ NetworkTerminal,
750
+ Terminal,
751
+ TerminalHeader,
752
+ formatJson,
753
+ formatTime,
754
+ getMethodColor,
755
+ getStatusColor,
756
+ truncate,
757
+ useNetworkInterceptor
758
+ });
759
+ //# sourceMappingURL=index.js.map