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