network-terminal 1.0.11 → 1.0.13

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 CHANGED
@@ -1,15 +1,8 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
1
  // src/components/NetworkTerminal.tsx
9
- import { useState as useState2, useCallback as useCallback2, useEffect as useEffect3 } from "react";
2
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect3 } from "react";
10
3
 
11
4
  // src/components/Terminal.tsx
12
- import { useRef, useState, useEffect } from "react";
5
+ import { useRef, useState as useState2, useEffect } from "react";
13
6
 
14
7
  // src/components/TerminalHeader.tsx
15
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -109,6 +102,9 @@ var TerminalHeader = ({
109
102
  ] });
110
103
  };
111
104
 
105
+ // src/components/LogEntry.tsx
106
+ import { useState } from "react";
107
+
112
108
  // src/utils/formatters.ts
113
109
  var formatJson = (data) => {
114
110
  if (!data) return "";
@@ -161,6 +157,17 @@ var getMethodColor = (method) => {
161
157
 
162
158
  // src/components/LogEntry.tsx
163
159
  import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
160
+ var decodeSpecialChars = (str) => {
161
+ if (!str) return str;
162
+ try {
163
+ return str.replace(
164
+ /\\u([0-9a-fA-F]{4})/g,
165
+ (_, code) => String.fromCharCode(parseInt(code, 16))
166
+ );
167
+ } catch {
168
+ return str;
169
+ }
170
+ };
164
171
  var styles2 = {
165
172
  container: {
166
173
  marginBottom: "16px",
@@ -231,9 +238,55 @@ var styles2 = {
231
238
  whiteSpace: "pre-wrap",
232
239
  fontFamily: "monospace",
233
240
  margin: 0
241
+ },
242
+ bodyHeader: {
243
+ display: "flex",
244
+ alignItems: "center",
245
+ justifyContent: "space-between",
246
+ marginBottom: "4px"
247
+ },
248
+ copyButton: {
249
+ backgroundColor: "transparent",
250
+ border: "1px solid #4b5563",
251
+ borderRadius: "4px",
252
+ color: "#9ca3af",
253
+ cursor: "pointer",
254
+ fontSize: "11px",
255
+ padding: "2px 8px",
256
+ fontFamily: "monospace",
257
+ transition: "all 0.2s"
258
+ },
259
+ copyButtonHover: {
260
+ backgroundColor: "#374151",
261
+ color: "#fff"
262
+ },
263
+ copyButtonCopied: {
264
+ backgroundColor: "#065f46",
265
+ borderColor: "#10b981",
266
+ color: "#10b981"
234
267
  }
235
268
  };
236
269
  var LogEntry = ({ log, type }) => {
270
+ const [copiedField, setCopiedField] = useState(null);
271
+ const [hoveredButton, setHoveredButton] = useState(null);
272
+ const handleCopy = async (content, field) => {
273
+ try {
274
+ const text = decodeSpecialChars(formatJson(content));
275
+ await navigator.clipboard.writeText(text);
276
+ setCopiedField(field);
277
+ setTimeout(() => setCopiedField(null), 2e3);
278
+ } catch (err) {
279
+ console.error("Failed to copy:", err);
280
+ }
281
+ };
282
+ const getButtonStyle = (field) => ({
283
+ ...styles2.copyButton,
284
+ ...hoveredButton === field && copiedField !== field ? styles2.copyButtonHover : {},
285
+ ...copiedField === field ? styles2.copyButtonCopied : {}
286
+ });
287
+ const formatContent = (data) => {
288
+ return decodeSpecialChars(formatJson(data));
289
+ };
237
290
  return /* @__PURE__ */ jsxs2("div", { style: styles2.container, children: [
238
291
  /* @__PURE__ */ jsxs2("div", { style: styles2.header, children: [
239
292
  /* @__PURE__ */ jsxs2("span", { style: styles2.timestamp, children: [
@@ -255,23 +308,59 @@ var LogEntry = ({ log, type }) => {
255
308
  ] }),
256
309
  /* @__PURE__ */ jsx2("div", { style: styles2.url, children: log.url }),
257
310
  type === "request" ? log.requestBody ? /* @__PURE__ */ jsxs2("div", { style: styles2.bodyContainer, children: [
258
- /* @__PURE__ */ jsxs2("div", { style: styles2.bodyLabel, children: [
259
- "\u25B8",
260
- " Payload:"
311
+ /* @__PURE__ */ jsxs2("div", { style: styles2.bodyHeader, children: [
312
+ /* @__PURE__ */ jsxs2("div", { style: styles2.bodyLabel, children: [
313
+ "\u25B8",
314
+ " Payload:"
315
+ ] }),
316
+ /* @__PURE__ */ jsx2(
317
+ "button",
318
+ {
319
+ style: getButtonStyle("payload"),
320
+ onClick: () => handleCopy(log.requestBody, "payload"),
321
+ onMouseEnter: () => setHoveredButton("payload"),
322
+ onMouseLeave: () => setHoveredButton(null),
323
+ children: copiedField === "payload" ? "Copied!" : "Copy"
324
+ }
325
+ )
261
326
  ] }),
262
- /* @__PURE__ */ jsx2("pre", { style: styles2.pre, children: formatJson(log.requestBody) })
327
+ /* @__PURE__ */ jsx2("pre", { style: styles2.pre, children: formatContent(log.requestBody) })
263
328
  ] }) : null : log.error ? /* @__PURE__ */ jsxs2("div", { style: styles2.bodyContainer, children: [
264
- /* @__PURE__ */ jsxs2("div", { style: { ...styles2.bodyLabel, color: "#f87171" }, children: [
265
- "\u25B8",
266
- " Error:"
329
+ /* @__PURE__ */ jsxs2("div", { style: styles2.bodyHeader, children: [
330
+ /* @__PURE__ */ jsxs2("div", { style: { ...styles2.bodyLabel, color: "#f87171" }, children: [
331
+ "\u25B8",
332
+ " Error:"
333
+ ] }),
334
+ /* @__PURE__ */ jsx2(
335
+ "button",
336
+ {
337
+ style: getButtonStyle("error"),
338
+ onClick: () => handleCopy(log.error, "error"),
339
+ onMouseEnter: () => setHoveredButton("error"),
340
+ onMouseLeave: () => setHoveredButton(null),
341
+ children: copiedField === "error" ? "Copied!" : "Copy"
342
+ }
343
+ )
267
344
  ] }),
268
345
  /* @__PURE__ */ jsx2("pre", { style: styles2.errorPre, children: log.error })
269
346
  ] }) : log.responseBody ? /* @__PURE__ */ jsxs2("div", { style: styles2.bodyContainer, children: [
270
- /* @__PURE__ */ jsxs2("div", { style: styles2.bodyLabel, children: [
271
- "\u25B8",
272
- " Response:"
347
+ /* @__PURE__ */ jsxs2("div", { style: styles2.bodyHeader, children: [
348
+ /* @__PURE__ */ jsxs2("div", { style: styles2.bodyLabel, children: [
349
+ "\u25B8",
350
+ " Response:"
351
+ ] }),
352
+ /* @__PURE__ */ jsx2(
353
+ "button",
354
+ {
355
+ style: getButtonStyle("response"),
356
+ onClick: () => handleCopy(log.responseBody, "response"),
357
+ onMouseEnter: () => setHoveredButton("response"),
358
+ onMouseLeave: () => setHoveredButton(null),
359
+ children: copiedField === "response" ? "Copied!" : "Copy"
360
+ }
361
+ )
273
362
  ] }),
274
- /* @__PURE__ */ jsx2("pre", { style: styles2.pre, children: formatJson(log.responseBody) })
363
+ /* @__PURE__ */ jsx2("pre", { style: styles2.pre, children: formatContent(log.responseBody) })
275
364
  ] }) : null
276
365
  ] });
277
366
  };
@@ -316,7 +405,7 @@ var Terminal = ({
316
405
  onToggleExpand
317
406
  }) => {
318
407
  const terminalRef = useRef(null);
319
- const [autoScroll, setAutoScroll] = useState(true);
408
+ const [autoScroll, setAutoScroll] = useState2(true);
320
409
  useEffect(() => {
321
410
  if (autoScroll && terminalRef.current) {
322
411
  terminalRef.current.scrollTop = terminalRef.current.scrollHeight;
@@ -608,10 +697,10 @@ var NetworkTerminal = ({
608
697
  height = "450px",
609
698
  zIndex = 9999
610
699
  }) => {
611
- const [logs, setLogs] = useState2([]);
612
- const [isVisible, setIsVisible] = useState2(defaultVisible);
613
- const [requestExpanded, setRequestExpanded] = useState2(true);
614
- const [responseExpanded, setResponseExpanded] = useState2(true);
700
+ const [logs, setLogs] = useState3([]);
701
+ const [isVisible, setIsVisible] = useState3(defaultVisible);
702
+ const [requestExpanded, setRequestExpanded] = useState3(true);
703
+ const [responseExpanded, setResponseExpanded] = useState3(true);
615
704
  const addLog = useCallback2(
616
705
  (log) => {
617
706
  setLogs((prev) => [...prev.slice(-(maxLogs - 1)), log]);
@@ -718,6 +807,7 @@ var NetworkTerminal = ({
718
807
 
719
808
  // src/vite-plugin.ts
720
809
  import { createServer } from "http";
810
+ import { exec } from "child_process";
721
811
  var networkLogs = [];
722
812
  var sseClients = /* @__PURE__ */ new Set();
723
813
  function broadcastLog(log) {
@@ -1194,7 +1284,7 @@ function networkTerminal(options = {}) {
1194
1284
  `);
1195
1285
  if (open) {
1196
1286
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
1197
- __require("child_process").exec(`${openCmd} http://localhost:${port}`);
1287
+ exec(`${openCmd} http://localhost:${port}`);
1198
1288
  }
1199
1289
  });
1200
1290
  dashboardServer.on("error", (err) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/NetworkTerminal.tsx","../src/components/Terminal.tsx","../src/components/TerminalHeader.tsx","../src/utils/formatters.ts","../src/utils/colors.ts","../src/components/LogEntry.tsx","../src/hooks/useNetworkInterceptor.ts","../src/vite-plugin.ts"],"sourcesContent":["import React, { useState, useCallback, useEffect } from 'react';\nimport { NetworkLog, NetworkTerminalProps } from '../types';\nimport { Terminal } from './Terminal';\nimport { useNetworkInterceptor } from '../hooks/useNetworkInterceptor';\n\nconst styles = {\n floatingButton: {\n position: 'fixed' as const,\n bottom: '16px',\n right: '16px',\n zIndex: 9999,\n backgroundColor: '#1f2937',\n color: '#4ade80',\n padding: '8px 16px',\n borderRadius: '8px',\n fontFamily: 'monospace',\n fontSize: '14px',\n boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n border: '1px solid #374151',\n cursor: 'pointer',\n },\n container: {\n position: 'fixed' as const,\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 9999,\n backgroundColor: '#111827',\n borderTop: '2px solid #22c55e',\n boxShadow: '0 -10px 15px -3px rgba(0, 0, 0, 0.1)',\n },\n containerTop: {\n position: 'fixed' as const,\n top: 0,\n left: 0,\n right: 0,\n zIndex: 9999,\n backgroundColor: '#111827',\n borderBottom: '2px solid #22c55e',\n boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n },\n mainHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 16px',\n backgroundColor: '#1f2937',\n borderBottom: '1px solid #374151',\n },\n headerLeft: {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n title: {\n color: '#4ade80',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n },\n hint: {\n color: '#6b7280',\n fontFamily: 'monospace',\n fontSize: '12px',\n },\n headerRight: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n clearButton: {\n color: '#9ca3af',\n fontSize: '14px',\n fontFamily: 'monospace',\n padding: '4px 12px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n },\n closeButton: {\n color: '#9ca3af',\n fontSize: '18px',\n fontWeight: 'bold',\n padding: '0 8px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n borderRadius: '4px',\n },\n terminalsContainer: {\n display: 'flex',\n gap: '8px',\n padding: '8px',\n height: '450px',\n },\n terminalWrapper: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n },\n} as const;\n\nexport const NetworkTerminal: React.FC<NetworkTerminalProps> = ({\n maxLogs = 100,\n defaultVisible = false,\n position = 'bottom',\n height = '450px',\n zIndex = 9999,\n}) => {\n const [logs, setLogs] = useState<NetworkLog[]>([]);\n const [isVisible, setIsVisible] = useState(defaultVisible);\n const [requestExpanded, setRequestExpanded] = useState(true);\n const [responseExpanded, setResponseExpanded] = useState(true);\n\n const addLog = useCallback(\n (log: NetworkLog) => {\n setLogs((prev) => [...prev.slice(-(maxLogs - 1)), log]);\n },\n [maxLogs]\n );\n\n const updateLog = useCallback((id: string, updates: Partial<NetworkLog>) => {\n setLogs((prev) =>\n prev.map((log) => (log.id === id ? { ...log, ...updates } : log))\n );\n }, []);\n\n useNetworkInterceptor({\n enabled: isVisible,\n onLogAdd: addLog,\n onLogUpdate: updateLog,\n });\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.ctrlKey && e.shiftKey && e.key === 'N') {\n e.preventDefault();\n setIsVisible((prev) => !prev);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, []);\n\n const clearLogs = () => setLogs([]);\n\n if (!isVisible) {\n return (\n <button\n onClick={() => setIsVisible(true)}\n style={{\n ...styles.floatingButton,\n zIndex,\n }}\n title=\"Open Network Terminal (Ctrl+Shift+N)\"\n >\n {'>'}_ Network\n </button>\n );\n }\n\n const containerStyle =\n position === 'top'\n ? { ...styles.containerTop, zIndex }\n : { ...styles.container, zIndex };\n\n return (\n <div style={containerStyle}>\n <div style={styles.mainHeader}>\n <div style={styles.headerLeft}>\n <span style={styles.title}>{'>'}_ Network Terminal</span>\n <span style={styles.hint}>Press Ctrl+Shift+N to toggle</span>\n </div>\n <div style={styles.headerRight}>\n <button\n onClick={clearLogs}\n style={styles.clearButton}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n Clear All\n </button>\n <button\n onClick={() => setIsVisible(false)}\n style={styles.closeButton}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#f87171')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n {'\\u00D7'}\n </button>\n </div>\n </div>\n\n <div style={{ ...styles.terminalsContainer, height }}>\n <div style={styles.terminalWrapper}>\n <Terminal\n title=\"Requests\"\n logs={logs}\n type=\"request\"\n onClear={clearLogs}\n expanded={requestExpanded}\n onToggleExpand={() => setRequestExpanded(!requestExpanded)}\n />\n </div>\n <div style={styles.terminalWrapper}>\n <Terminal\n title=\"Responses\"\n logs={logs}\n type=\"response\"\n onClear={clearLogs}\n expanded={responseExpanded}\n onToggleExpand={() => setResponseExpanded(!responseExpanded)}\n />\n </div>\n </div>\n </div>\n );\n};\n","import React, { useRef, useState, useEffect } from 'react';\nimport { TerminalProps } from '../types';\nimport { TerminalHeader } from './TerminalHeader';\nimport { LogEntry } from './LogEntry';\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n backgroundColor: '#111827',\n borderRadius: '8px',\n border: '1px solid #374151',\n overflow: 'hidden',\n transition: 'all 0.2s',\n flex: 1,\n },\n collapsed: {\n height: '48px',\n flex: 'none' as const,\n },\n body: {\n flex: 1,\n overflow: 'auto',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '14px',\n minHeight: '200px',\n maxHeight: '400px',\n },\n empty: {\n color: '#6b7280',\n fontStyle: 'italic',\n },\n} as const;\n\nexport const Terminal: React.FC<TerminalProps> = ({\n title,\n logs,\n type,\n onClear,\n expanded,\n onToggleExpand,\n}) => {\n const terminalRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n\n useEffect(() => {\n if (autoScroll && terminalRef.current) {\n terminalRef.current.scrollTop = terminalRef.current.scrollHeight;\n }\n }, [logs, autoScroll]);\n\n const handleScroll = () => {\n if (terminalRef.current) {\n const { scrollTop, scrollHeight, clientHeight } = terminalRef.current;\n setAutoScroll(scrollHeight - scrollTop - clientHeight < 50);\n }\n };\n\n return (\n <div\n style={{\n ...styles.container,\n ...(expanded ? {} : styles.collapsed),\n }}\n >\n <TerminalHeader\n title={title}\n count={logs.length}\n expanded={expanded}\n onClear={onClear}\n onToggleExpand={onToggleExpand}\n />\n\n {expanded && (\n <div ref={terminalRef} onScroll={handleScroll} style={styles.body}>\n {logs.length === 0 ? (\n <div style={styles.empty}>Waiting for network requests...</div>\n ) : (\n logs.map((log) => <LogEntry key={log.id} log={log} type={type} />)\n )}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { TerminalHeaderProps } from '../types';\n\nconst styles = {\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 16px',\n backgroundColor: '#1f2937',\n borderBottom: '1px solid #374151',\n },\n left: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n trafficLights: {\n display: 'flex',\n gap: '6px',\n },\n dot: {\n width: '12px',\n height: '12px',\n borderRadius: '50%',\n },\n title: {\n color: '#d1d5db',\n fontFamily: 'monospace',\n fontSize: '14px',\n marginLeft: '8px',\n },\n count: {\n color: '#6b7280',\n fontFamily: 'monospace',\n fontSize: '12px',\n },\n right: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n button: {\n color: '#9ca3af',\n fontSize: '12px',\n fontFamily: 'monospace',\n padding: '4px 8px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n },\n} as const;\n\nexport const TerminalHeader: React.FC<TerminalHeaderProps> = ({\n title,\n count,\n expanded,\n onClear,\n onToggleExpand,\n}) => {\n return (\n <div style={styles.header}>\n <div style={styles.left}>\n <div style={styles.trafficLights}>\n <div style={{ ...styles.dot, backgroundColor: '#ef4444' }} />\n <div style={{ ...styles.dot, backgroundColor: '#eab308' }} />\n <div style={{ ...styles.dot, backgroundColor: '#22c55e' }} />\n </div>\n <span style={styles.title}>{title}</span>\n <span style={styles.count}>({count} entries)</span>\n </div>\n <div style={styles.right}>\n <button\n onClick={onClear}\n style={styles.button}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n Clear\n </button>\n <button\n onClick={onToggleExpand}\n style={styles.button}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n {expanded ? '\\u25BC' : '\\u25B2'}\n </button>\n </div>\n </div>\n );\n};\n","export const formatJson = (data: unknown): string => {\n if (!data) return '';\n try {\n if (typeof data === 'string') {\n const parsed = JSON.parse(data);\n return JSON.stringify(parsed, null, 2);\n }\n return JSON.stringify(data, null, 2);\n } catch {\n return String(data);\n }\n};\n\nexport const truncate = (str: string, maxLength: number): string => {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength) + '...';\n};\n\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n};\n","export const getStatusColor = (status?: number): string => {\n if (!status) return '#9ca3af'; // gray-400\n if (status >= 200 && status < 300) return '#4ade80'; // green-400\n if (status >= 300 && status < 400) return '#facc15'; // yellow-400\n if (status >= 400 && status < 500) return '#fb923c'; // orange-400\n return '#f87171'; // red-400\n};\n\nexport const getMethodColor = (method: string): string => {\n const colors: Record<string, string> = {\n GET: '#22d3ee', // cyan-400\n POST: '#4ade80', // green-400\n PUT: '#facc15', // yellow-400\n PATCH: '#fb923c', // orange-400\n DELETE: '#f87171', // red-400\n };\n return colors[method.toUpperCase()] || '#9ca3af';\n};\n","import React from 'react';\nimport { LogEntryProps } from '../types';\nimport { formatJson, formatTime } from '../utils/formatters';\nimport { getStatusColor, getMethodColor } from '../utils/colors';\n\nconst styles = {\n container: {\n marginBottom: '16px',\n borderBottom: '1px solid #1f2937',\n paddingBottom: '16px',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginBottom: '4px',\n flexWrap: 'wrap' as const,\n },\n timestamp: {\n color: '#6b7280',\n fontSize: '12px',\n fontFamily: 'monospace',\n },\n method: {\n fontWeight: 'bold',\n fontFamily: 'monospace',\n },\n status: {\n fontWeight: 'bold',\n fontFamily: 'monospace',\n },\n duration: {\n color: '#6b7280',\n fontSize: '12px',\n fontFamily: 'monospace',\n },\n url: {\n color: '#60a5fa',\n wordBreak: 'break-all' as const,\n marginBottom: '8px',\n fontFamily: 'monospace',\n fontSize: '13px',\n },\n bodyContainer: {\n marginTop: '8px',\n },\n bodyLabel: {\n color: '#a78bfa',\n fontSize: '12px',\n marginBottom: '4px',\n fontFamily: 'monospace',\n },\n pre: {\n backgroundColor: '#1f2937',\n padding: '8px',\n borderRadius: '4px',\n color: '#86efac',\n overflowX: 'auto' as const,\n fontSize: '12px',\n whiteSpace: 'pre-wrap' as const,\n fontFamily: 'monospace',\n maxHeight: '192px',\n overflowY: 'auto' as const,\n margin: 0,\n },\n errorPre: {\n backgroundColor: '#1f2937',\n padding: '8px',\n borderRadius: '4px',\n color: '#fca5a5',\n overflowX: 'auto' as const,\n fontSize: '12px',\n whiteSpace: 'pre-wrap' as const,\n fontFamily: 'monospace',\n margin: 0,\n },\n} as const;\n\nexport const LogEntry: React.FC<LogEntryProps> = ({ log, type }) => {\n return (\n <div style={styles.container}>\n <div style={styles.header}>\n <span style={styles.timestamp}>[{formatTime(log.timestamp)}]</span>\n <span style={{ ...styles.method, color: getMethodColor(log.method) }}>\n {log.method}\n </span>\n {type === 'response' && log.status && (\n <span style={{ ...styles.status, color: getStatusColor(log.status) }}>\n {log.status} {log.statusText}\n </span>\n )}\n {log.duration !== undefined && type === 'response' && (\n <span style={styles.duration}>({log.duration}ms)</span>\n )}\n </div>\n\n <div style={styles.url}>{log.url}</div>\n\n {type === 'request' ? (\n log.requestBody ? (\n <div style={styles.bodyContainer}>\n <div style={styles.bodyLabel}>{'\\u25B8'} Payload:</div>\n <pre style={styles.pre}>{formatJson(log.requestBody)}</pre>\n </div>\n ) : null\n ) : log.error ? (\n <div style={styles.bodyContainer}>\n <div style={{ ...styles.bodyLabel, color: '#f87171' }}>\n {'\\u25B8'} Error:\n </div>\n <pre style={styles.errorPre}>{log.error}</pre>\n </div>\n ) : log.responseBody ? (\n <div style={styles.bodyContainer}>\n <div style={styles.bodyLabel}>{'\\u25B8'} Response:</div>\n <pre style={styles.pre}>{formatJson(log.responseBody)}</pre>\n </div>\n ) : null}\n </div>\n );\n};\n","import { useEffect, useRef, useCallback } from 'react';\nimport { NetworkLog, UseNetworkInterceptorProps } from '../types';\n\nexport const useNetworkInterceptor = ({\n enabled,\n onLogAdd,\n onLogUpdate,\n}: UseNetworkInterceptorProps) => {\n const originalFetch = useRef<typeof fetch | null>(null);\n const originalXHROpen = useRef<typeof XMLHttpRequest.prototype.open | null>(null);\n const originalXHRSend = useRef<typeof XMLHttpRequest.prototype.send | null>(null);\n\n const generateId = useCallback((prefix: string) => {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }, []);\n\n // Intercept Fetch\n useEffect(() => {\n if (!enabled) return;\n\n originalFetch.current = window.fetch;\n\n window.fetch = async function (input, init) {\n const id = generateId('fetch');\n const startTime = performance.now();\n\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.href\n : input.url;\n\n const method = init?.method || 'GET';\n\n let requestBody: unknown = null;\n if (init?.body) {\n try {\n requestBody =\n typeof init.body === 'string' ? JSON.parse(init.body) : init.body;\n } catch {\n requestBody = init.body;\n }\n }\n\n onLogAdd({\n id,\n timestamp: new Date(),\n method: method.toUpperCase(),\n url,\n requestBody,\n type: 'fetch',\n });\n\n try {\n const response = await originalFetch.current!(input, init);\n const duration = Math.round(performance.now() - startTime);\n\n const clonedResponse = response.clone();\n let responseBody: unknown = null;\n\n try {\n responseBody = await clonedResponse.json();\n } catch {\n try {\n responseBody = await clonedResponse.text();\n } catch {\n responseBody = '[Could not read response body]';\n }\n }\n\n onLogUpdate(id, {\n status: response.status,\n statusText: response.statusText,\n responseBody,\n duration,\n });\n\n return response;\n } catch (error: unknown) {\n const duration = Math.round(performance.now() - startTime);\n const errorMessage =\n error instanceof Error ? error.message : 'Network Error';\n onLogUpdate(id, {\n error: errorMessage,\n duration,\n });\n throw error;\n }\n };\n\n return () => {\n if (originalFetch.current) {\n window.fetch = originalFetch.current;\n }\n };\n }, [enabled, onLogAdd, onLogUpdate, generateId]);\n\n // Intercept XHR\n useEffect(() => {\n if (!enabled) return;\n\n originalXHROpen.current = XMLHttpRequest.prototype.open;\n originalXHRSend.current = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL\n ) {\n (this as XMLHttpRequest & { _networkTerminal: NetworkLog & { startTime: number } })._networkTerminal = {\n id: generateId('xhr'),\n method: method.toUpperCase(),\n url: url.toString(),\n startTime: 0,\n timestamp: new Date(),\n type: 'xhr',\n };\n return originalXHROpen.current!.apply(\n this,\n arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.open>\n );\n };\n\n XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const meta = (this as XMLHttpRequest & { _networkTerminal?: NetworkLog & { startTime: number } })._networkTerminal;\n\n if (meta) {\n meta.startTime = performance.now();\n\n let requestBody: unknown = null;\n if (body) {\n try {\n requestBody = typeof body === 'string' ? JSON.parse(body) : body;\n } catch {\n requestBody = body;\n }\n }\n\n onLogAdd({\n id: meta.id,\n timestamp: new Date(),\n method: meta.method,\n url: meta.url,\n requestBody,\n type: 'xhr',\n });\n\n this.addEventListener('load', function () {\n const duration = Math.round(performance.now() - meta.startTime);\n\n let responseBody: unknown = null;\n try {\n responseBody = JSON.parse(this.responseText);\n } catch {\n responseBody = this.responseText;\n }\n\n onLogUpdate(meta.id, {\n status: this.status,\n statusText: this.statusText,\n responseBody,\n duration,\n });\n });\n\n this.addEventListener('error', function () {\n const duration = Math.round(performance.now() - meta.startTime);\n onLogUpdate(meta.id, {\n error: 'Network Error',\n duration,\n });\n });\n }\n\n return originalXHRSend.current!.apply(\n this,\n arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.send>\n );\n };\n\n return () => {\n if (originalXHROpen.current) {\n XMLHttpRequest.prototype.open = originalXHROpen.current;\n }\n if (originalXHRSend.current) {\n XMLHttpRequest.prototype.send = originalXHRSend.current;\n }\n };\n }, [enabled, onLogAdd, onLogUpdate, generateId]);\n};\n","import type { Plugin, ViteDevServer } from 'vite';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\n\nexport interface NetworkTerminalPluginOptions {\n /** Port for the dashboard (default: 4001) */\n port?: number;\n /** Auto-open dashboard in browser (default: true) */\n open?: boolean;\n}\n\n// Store network logs\nconst networkLogs: any[] = [];\nconst sseClients = new Set<ServerResponse>();\n\nfunction broadcastLog(log: any) {\n const data = JSON.stringify(log);\n sseClients.forEach(client => {\n client.write(`data: ${data}\\n\\n`);\n });\n}\n\nfunction getDashboardHTML(_port: number): string {\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Network Terminal</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n background: #0a0e17;\n color: #e2e8f0;\n height: 100vh;\n overflow: hidden;\n }\n .header {\n background: #0f172a;\n padding: 12px 24px;\n border-bottom: 2px solid #4ade80;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .title { color: #4ade80; font-size: 18px; font-weight: bold; }\n .subtitle { color: #64748b; font-size: 12px; margin-top: 4px; }\n .controls { display: flex; gap: 12px; align-items: center; }\n .btn {\n background: #1e293b;\n border: 1px solid #334155;\n color: #94a3b8;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-family: inherit;\n }\n .btn:hover { background: #334155; color: #e2e8f0; }\n .container { display: flex; height: calc(100vh - 80px); }\n .panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border-right: 1px solid #1e293b;\n }\n .panel:last-child { border-right: none; }\n .panel-header {\n background: #0f172a;\n padding: 12px 16px;\n border-bottom: 1px solid #1e293b;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .panel-title { font-weight: bold; font-size: 14px; }\n .panel-title.request { color: #3b82f6; }\n .panel-title.response { color: #22c55e; }\n .panel-count {\n background: #1e293b;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n color: #64748b;\n }\n .logs { flex: 1; overflow-y: auto; padding: 8px; }\n .log-entry {\n background: #0f172a;\n border: 1px solid #1e293b;\n border-radius: 8px;\n margin-bottom: 8px;\n overflow: hidden;\n cursor: pointer;\n transition: border-color 0.2s;\n }\n .log-entry:hover { border-color: #334155; }\n .log-entry.selected { border-color: #4ade80; }\n .log-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #1e293b;\n }\n .method {\n font-weight: bold;\n font-size: 11px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .method.GET { background: #166534; color: #4ade80; }\n .method.POST { background: #1e40af; color: #60a5fa; }\n .method.PUT { background: #a16207; color: #fcd34d; }\n .method.DELETE { background: #991b1b; color: #fca5a5; }\n .method.PATCH { background: #7c3aed; color: #c4b5fd; }\n .status { font-size: 11px; padding: 3px 8px; border-radius: 4px; }\n .status.success { background: #166534; color: #4ade80; }\n .status.error { background: #991b1b; color: #fca5a5; }\n .status.pending { background: #374151; color: #9ca3af; }\n .url {\n flex: 1;\n font-size: 12px;\n color: #94a3b8;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .duration { font-size: 11px; color: #64748b; }\n .timestamp { font-size: 10px; color: #475569; }\n .log-body { padding: 12px; font-size: 11px; max-height: 300px; overflow: auto; }\n .log-body pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n color: #cbd5e1;\n line-height: 1.5;\n }\n .log-body.empty { color: #475569; font-style: italic; }\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #475569;\n text-align: center;\n padding: 20px;\n }\n .empty-state svg { width: 48px; height: 48px; margin-bottom: 16px; opacity: 0.5; }\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #22c55e;\n animation: pulse 2s infinite;\n }\n @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }\n .status-dot.disconnected { background: #ef4444; animation: none; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div>\n <div class=\"title\">>_ Network Terminal</div>\n <div class=\"subtitle\">Vite Plugin - Monitoring fetch/XHR requests</div>\n </div>\n <div class=\"controls\">\n <div class=\"status-dot\" id=\"statusDot\"></div>\n <button class=\"btn\" onclick=\"clearLogs()\">Clear All</button>\n </div>\n </div>\n\n <div class=\"container\">\n <div class=\"panel\">\n <div class=\"panel-header\">\n <span class=\"panel-title request\">⬆ REQUESTS</span>\n <span class=\"panel-count\" id=\"requestCount\">0</span>\n </div>\n <div class=\"logs\" id=\"requestLogs\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 19V5M5 12l7-7 7 7\"/>\n </svg>\n <div>Waiting for requests...</div>\n <div style=\"margin-top: 8px; font-size: 11px;\">Make fetch/XHR requests in your app</div>\n </div>\n </div>\n </div>\n\n <div class=\"panel\">\n <div class=\"panel-header\">\n <span class=\"panel-title response\">⬇ RESPONSES</span>\n <span class=\"panel-count\" id=\"responseCount\">0</span>\n </div>\n <div class=\"logs\" id=\"responseLogs\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 5v14M5 12l7 7 7-7\"/>\n </svg>\n <div>Waiting for responses...</div>\n </div>\n </div>\n </div>\n </div>\n\n <script>\n const logs = new Map();\n let selectedId = null;\n\n function formatJson(data) {\n if (!data) return null;\n if (typeof data === 'string') {\n try { data = JSON.parse(data); }\n catch (e) { return escapeHtml(data.substring(0, 2000)); }\n }\n return escapeHtml(JSON.stringify(data, null, 2));\n }\n\n function escapeHtml(str) {\n if (typeof str !== 'string') str = String(str);\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n\n function formatTime(timestamp) {\n const date = new Date(timestamp);\n return date.toLocaleTimeString('en-US', { hour12: false }) + '.' +\n String(date.getMilliseconds()).padStart(3, '0');\n }\n\n function getLogsArray() {\n return Array.from(logs.values()).sort((a, b) =>\n new Date(b.timestamp) - new Date(a.timestamp)\n );\n }\n\n function renderLogs() {\n const logsArray = getLogsArray();\n const requestContainer = document.getElementById('requestLogs');\n const responseContainer = document.getElementById('responseLogs');\n\n document.getElementById('requestCount').textContent = logsArray.length;\n document.getElementById('responseCount').textContent = logsArray.filter(l => l.status).length;\n\n if (logsArray.length === 0) {\n requestContainer.innerHTML = '<div class=\"empty-state\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 19V5M5 12l7-7 7 7\"/></svg><div>Waiting for requests...</div></div>';\n responseContainer.innerHTML = '<div class=\"empty-state\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 5v14M5 12l7 7 7-7\"/></svg><div>Waiting for responses...</div></div>';\n return;\n }\n\n requestContainer.innerHTML = logsArray.map(log => {\n const isSelected = selectedId === log.id;\n const bodyContent = formatJson(log.requestBody);\n return '<div class=\"log-entry '+(isSelected ? 'selected' : '')+'\" onclick=\"selectLog(\\\\''+log.id+'\\\\')\"><div class=\"log-header\"><span class=\"method '+log.method+'\">'+log.method+'</span><span class=\"url\" title=\"'+escapeHtml(log.url)+'\">'+log.url+'</span><span class=\"timestamp\">'+formatTime(log.timestamp)+'</span></div>'+(isSelected ? '<div class=\"log-body '+(bodyContent ? '' : 'empty')+'\">'+(bodyContent ? '<pre>'+bodyContent+'</pre>' : 'No request body')+'</div>' : '')+'</div>';\n }).join('');\n\n responseContainer.innerHTML = logsArray.map(log => {\n const isSelected = selectedId === log.id;\n const statusClass = !log.status ? 'pending' : log.status < 400 ? 'success' : 'error';\n const bodyContent = formatJson(log.responseBody);\n return '<div class=\"log-entry '+(isSelected ? 'selected' : '')+'\" onclick=\"selectLog(\\\\''+log.id+'\\\\')\"><div class=\"log-header\"><span class=\"status '+statusClass+'\">'+(log.status || '...')+'</span><span class=\"url\" title=\"'+escapeHtml(log.url)+'\">'+log.url+'</span><span class=\"duration\">'+(log.duration ? log.duration + 'ms' : '')+'</span></div>'+(isSelected ? '<div class=\"log-body '+(bodyContent ? '' : 'empty')+'\">'+(bodyContent ? '<pre>'+bodyContent+'</pre>' : (log.status ? 'No response body' : 'Pending...'))+'</div>' : '')+'</div>';\n }).join('');\n }\n\n function selectLog(id) {\n selectedId = selectedId === id ? null : id;\n renderLogs();\n }\n\n function clearLogs() {\n logs.clear();\n selectedId = null;\n renderLogs();\n fetch('/clear', { method: 'POST' });\n }\n\n function addLog(log) {\n logs.set(log.id, log);\n if (logs.size > 100) {\n const oldest = getLogsArray().pop();\n if (oldest) logs.delete(oldest.id);\n }\n renderLogs();\n }\n\n function connect() {\n const evtSource = new EventSource('/events');\n evtSource.onopen = () => document.getElementById('statusDot').classList.remove('disconnected');\n evtSource.onmessage = (event) => addLog(JSON.parse(event.data));\n evtSource.onerror = () => {\n document.getElementById('statusDot').classList.add('disconnected');\n evtSource.close();\n setTimeout(connect, 2000);\n };\n }\n\n connect();\n renderLogs();\n </script>\n</body>\n</html>\n`;\n}\n\nfunction getMonitorScript(port: number): string {\n return `\n(function() {\n if (window.__networkTerminalActive) return;\n window.__networkTerminalActive = true;\n\n var DASHBOARD_URL = 'http://localhost:${port}';\n\n function sendLog(log) {\n var xhr = new XMLHttpRequest();\n xhr.open('POST', DASHBOARD_URL + '/log', true);\n xhr.setRequestHeader('Content-Type', 'application/json');\n xhr.send(JSON.stringify(log));\n }\n\n function tryParse(data) {\n if (!data) return null;\n if (typeof data === 'object') return data;\n try { return JSON.parse(data); } catch (e) { return data; }\n }\n\n var originalFetch = window.fetch;\n window.fetch = function() {\n var args = arguments;\n var startTime = Date.now();\n var input = args[0];\n var options = args[1] || {};\n var url = typeof input === 'string' ? input : (input.url || input.toString());\n var method = (options.method || 'GET').toUpperCase();\n\n if (url.includes('localhost:${port}')) {\n return originalFetch.apply(this, args);\n }\n\n var log = {\n id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n method: method,\n url: url,\n timestamp: new Date().toISOString(),\n requestBody: options.body ? tryParse(options.body) : null,\n status: null,\n responseBody: null,\n duration: null,\n };\n\n sendLog(log);\n\n return originalFetch.apply(this, args).then(function(response) {\n log.status = response.status;\n log.duration = Date.now() - startTime;\n var cloned = response.clone();\n cloned.text().then(function(text) {\n log.responseBody = tryParse(text);\n sendLog(log);\n }).catch(function() { sendLog(log); });\n return response;\n }).catch(function(error) {\n log.status = 0;\n log.duration = Date.now() - startTime;\n log.error = error.message;\n sendLog(log);\n throw error;\n });\n };\n\n var OriginalXHR = window.XMLHttpRequest;\n window.XMLHttpRequest = function() {\n var xhr = new OriginalXHR();\n var method, url, requestBody, startTime;\n\n var originalOpen = xhr.open;\n xhr.open = function(m, u) {\n method = m;\n url = u;\n return originalOpen.apply(this, arguments);\n };\n\n var originalSend = xhr.send;\n xhr.send = function(body) {\n if (url && url.includes('localhost:${port}')) {\n return originalSend.apply(this, arguments);\n }\n\n startTime = Date.now();\n requestBody = body;\n\n var log = {\n id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n method: (method || 'GET').toUpperCase(),\n url: url,\n timestamp: new Date().toISOString(),\n requestBody: tryParse(requestBody),\n status: null,\n responseBody: null,\n duration: null,\n };\n\n sendLog(log);\n\n xhr.addEventListener('loadend', function() {\n log.status = xhr.status;\n log.duration = Date.now() - startTime;\n log.responseBody = tryParse(xhr.responseText);\n sendLog(log);\n });\n\n return originalSend.apply(this, arguments);\n };\n\n return xhr;\n };\n\n console.log('[Network Terminal] ✓ Active - Dashboard: http://localhost:${port}');\n})();\n`;\n}\n\nexport function networkTerminal(options: NetworkTerminalPluginOptions = {}): Plugin {\n const { port = 4001, open = true } = options;\n let dashboardServer: ReturnType<typeof createServer> | null = null;\n\n return {\n name: 'vite-plugin-network-terminal',\n apply: 'serve',\n\n configureServer(_server: ViteDevServer) {\n // Start dashboard server\n dashboardServer = createServer((req: IncomingMessage, res: ServerResponse) => {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (req.url === '/events') {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n sseClients.add(res);\n networkLogs.forEach(log => {\n res.write(`data: ${JSON.stringify(log)}\\n\\n`);\n });\n req.on('close', () => sseClients.delete(res));\n return;\n }\n\n if (req.url === '/log' && req.method === 'POST') {\n let body = '';\n req.on('data', (chunk: Buffer) => body += chunk);\n req.on('end', () => {\n try {\n const log = JSON.parse(body);\n const existingIndex = networkLogs.findIndex(l => l.id === log.id);\n if (existingIndex >= 0) {\n networkLogs[existingIndex] = log;\n } else {\n networkLogs.unshift(log);\n if (networkLogs.length > 100) networkLogs.pop();\n }\n broadcastLog(log);\n } catch (e) {}\n res.writeHead(200);\n res.end('OK');\n });\n return;\n }\n\n if (req.url === '/clear' && req.method === 'POST') {\n networkLogs.length = 0;\n res.writeHead(200);\n res.end('OK');\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(getDashboardHTML(port));\n });\n\n dashboardServer.listen(port, () => {\n console.log(`\\n \\x1b[32m>_ Network Terminal\\x1b[0m`);\n console.log(` Dashboard: \\x1b[36mhttp://localhost:${port}\\x1b[0m\\n`);\n\n if (open) {\n const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n require('child_process').exec(`${openCmd} http://localhost:${port}`);\n }\n });\n\n dashboardServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(`\\n \\x1b[33m[Network Terminal]\\x1b[0m Port ${port} in use, dashboard disabled\\n`);\n }\n });\n },\n\n transformIndexHtml(html: string) {\n const script = `<script>${getMonitorScript(port)}</script>`;\n if (html.includes('</head>')) {\n return html.replace('</head>', script + '</head>');\n }\n return script + html;\n },\n\n buildEnd() {\n if (dashboardServer) {\n dashboardServer.close();\n }\n },\n };\n}\n\nexport default networkTerminal;\n"],"mappings":"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","names":["useState","useCallback","useEffect","jsx","jsxs","styles","jsx","jsxs","styles","useEffect","useRef","jsx","jsxs","styles","useState","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../src/components/NetworkTerminal.tsx","../src/components/Terminal.tsx","../src/components/TerminalHeader.tsx","../src/components/LogEntry.tsx","../src/utils/formatters.ts","../src/utils/colors.ts","../src/hooks/useNetworkInterceptor.ts","../src/vite-plugin.ts"],"sourcesContent":["import React, { useState, useCallback, useEffect } from 'react';\nimport { NetworkLog, NetworkTerminalProps } from '../types';\nimport { Terminal } from './Terminal';\nimport { useNetworkInterceptor } from '../hooks/useNetworkInterceptor';\n\nconst styles = {\n floatingButton: {\n position: 'fixed' as const,\n bottom: '16px',\n right: '16px',\n zIndex: 9999,\n backgroundColor: '#1f2937',\n color: '#4ade80',\n padding: '8px 16px',\n borderRadius: '8px',\n fontFamily: 'monospace',\n fontSize: '14px',\n boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n border: '1px solid #374151',\n cursor: 'pointer',\n },\n container: {\n position: 'fixed' as const,\n bottom: 0,\n left: 0,\n right: 0,\n zIndex: 9999,\n backgroundColor: '#111827',\n borderTop: '2px solid #22c55e',\n boxShadow: '0 -10px 15px -3px rgba(0, 0, 0, 0.1)',\n },\n containerTop: {\n position: 'fixed' as const,\n top: 0,\n left: 0,\n right: 0,\n zIndex: 9999,\n backgroundColor: '#111827',\n borderBottom: '2px solid #22c55e',\n boxShadow: '0 10px 15px -3px rgba(0, 0, 0, 0.1)',\n },\n mainHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 16px',\n backgroundColor: '#1f2937',\n borderBottom: '1px solid #374151',\n },\n headerLeft: {\n display: 'flex',\n alignItems: 'center',\n gap: '12px',\n },\n title: {\n color: '#4ade80',\n fontFamily: 'monospace',\n fontWeight: 'bold',\n },\n hint: {\n color: '#6b7280',\n fontFamily: 'monospace',\n fontSize: '12px',\n },\n headerRight: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n clearButton: {\n color: '#9ca3af',\n fontSize: '14px',\n fontFamily: 'monospace',\n padding: '4px 12px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n },\n closeButton: {\n color: '#9ca3af',\n fontSize: '18px',\n fontWeight: 'bold',\n padding: '0 8px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n borderRadius: '4px',\n },\n terminalsContainer: {\n display: 'flex',\n gap: '8px',\n padding: '8px',\n height: '450px',\n },\n terminalWrapper: {\n flex: 1,\n display: 'flex',\n flexDirection: 'column' as const,\n },\n} as const;\n\nexport const NetworkTerminal: React.FC<NetworkTerminalProps> = ({\n maxLogs = 100,\n defaultVisible = false,\n position = 'bottom',\n height = '450px',\n zIndex = 9999,\n}) => {\n const [logs, setLogs] = useState<NetworkLog[]>([]);\n const [isVisible, setIsVisible] = useState(defaultVisible);\n const [requestExpanded, setRequestExpanded] = useState(true);\n const [responseExpanded, setResponseExpanded] = useState(true);\n\n const addLog = useCallback(\n (log: NetworkLog) => {\n setLogs((prev) => [...prev.slice(-(maxLogs - 1)), log]);\n },\n [maxLogs]\n );\n\n const updateLog = useCallback((id: string, updates: Partial<NetworkLog>) => {\n setLogs((prev) =>\n prev.map((log) => (log.id === id ? { ...log, ...updates } : log))\n );\n }, []);\n\n useNetworkInterceptor({\n enabled: isVisible,\n onLogAdd: addLog,\n onLogUpdate: updateLog,\n });\n\n useEffect(() => {\n const handleKeyDown = (e: KeyboardEvent) => {\n if (e.ctrlKey && e.shiftKey && e.key === 'N') {\n e.preventDefault();\n setIsVisible((prev) => !prev);\n }\n };\n\n window.addEventListener('keydown', handleKeyDown);\n return () => window.removeEventListener('keydown', handleKeyDown);\n }, []);\n\n const clearLogs = () => setLogs([]);\n\n if (!isVisible) {\n return (\n <button\n onClick={() => setIsVisible(true)}\n style={{\n ...styles.floatingButton,\n zIndex,\n }}\n title=\"Open Network Terminal (Ctrl+Shift+N)\"\n >\n {'>'}_ Network\n </button>\n );\n }\n\n const containerStyle =\n position === 'top'\n ? { ...styles.containerTop, zIndex }\n : { ...styles.container, zIndex };\n\n return (\n <div style={containerStyle}>\n <div style={styles.mainHeader}>\n <div style={styles.headerLeft}>\n <span style={styles.title}>{'>'}_ Network Terminal</span>\n <span style={styles.hint}>Press Ctrl+Shift+N to toggle</span>\n </div>\n <div style={styles.headerRight}>\n <button\n onClick={clearLogs}\n style={styles.clearButton}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n Clear All\n </button>\n <button\n onClick={() => setIsVisible(false)}\n style={styles.closeButton}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#f87171')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n {'\\u00D7'}\n </button>\n </div>\n </div>\n\n <div style={{ ...styles.terminalsContainer, height }}>\n <div style={styles.terminalWrapper}>\n <Terminal\n title=\"Requests\"\n logs={logs}\n type=\"request\"\n onClear={clearLogs}\n expanded={requestExpanded}\n onToggleExpand={() => setRequestExpanded(!requestExpanded)}\n />\n </div>\n <div style={styles.terminalWrapper}>\n <Terminal\n title=\"Responses\"\n logs={logs}\n type=\"response\"\n onClear={clearLogs}\n expanded={responseExpanded}\n onToggleExpand={() => setResponseExpanded(!responseExpanded)}\n />\n </div>\n </div>\n </div>\n );\n};\n","import React, { useRef, useState, useEffect } from 'react';\nimport { TerminalProps } from '../types';\nimport { TerminalHeader } from './TerminalHeader';\nimport { LogEntry } from './LogEntry';\n\nconst styles = {\n container: {\n display: 'flex',\n flexDirection: 'column' as const,\n backgroundColor: '#111827',\n borderRadius: '8px',\n border: '1px solid #374151',\n overflow: 'hidden',\n transition: 'all 0.2s',\n flex: 1,\n },\n collapsed: {\n height: '48px',\n flex: 'none' as const,\n },\n body: {\n flex: 1,\n overflow: 'auto',\n padding: '16px',\n fontFamily: 'monospace',\n fontSize: '14px',\n minHeight: '200px',\n maxHeight: '400px',\n },\n empty: {\n color: '#6b7280',\n fontStyle: 'italic',\n },\n} as const;\n\nexport const Terminal: React.FC<TerminalProps> = ({\n title,\n logs,\n type,\n onClear,\n expanded,\n onToggleExpand,\n}) => {\n const terminalRef = useRef<HTMLDivElement>(null);\n const [autoScroll, setAutoScroll] = useState(true);\n\n useEffect(() => {\n if (autoScroll && terminalRef.current) {\n terminalRef.current.scrollTop = terminalRef.current.scrollHeight;\n }\n }, [logs, autoScroll]);\n\n const handleScroll = () => {\n if (terminalRef.current) {\n const { scrollTop, scrollHeight, clientHeight } = terminalRef.current;\n setAutoScroll(scrollHeight - scrollTop - clientHeight < 50);\n }\n };\n\n return (\n <div\n style={{\n ...styles.container,\n ...(expanded ? {} : styles.collapsed),\n }}\n >\n <TerminalHeader\n title={title}\n count={logs.length}\n expanded={expanded}\n onClear={onClear}\n onToggleExpand={onToggleExpand}\n />\n\n {expanded && (\n <div ref={terminalRef} onScroll={handleScroll} style={styles.body}>\n {logs.length === 0 ? (\n <div style={styles.empty}>Waiting for network requests...</div>\n ) : (\n logs.map((log) => <LogEntry key={log.id} log={log} type={type} />)\n )}\n </div>\n )}\n </div>\n );\n};\n","import React from 'react';\nimport { TerminalHeaderProps } from '../types';\n\nconst styles = {\n header: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '8px 16px',\n backgroundColor: '#1f2937',\n borderBottom: '1px solid #374151',\n },\n left: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n trafficLights: {\n display: 'flex',\n gap: '6px',\n },\n dot: {\n width: '12px',\n height: '12px',\n borderRadius: '50%',\n },\n title: {\n color: '#d1d5db',\n fontFamily: 'monospace',\n fontSize: '14px',\n marginLeft: '8px',\n },\n count: {\n color: '#6b7280',\n fontFamily: 'monospace',\n fontSize: '12px',\n },\n right: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n },\n button: {\n color: '#9ca3af',\n fontSize: '12px',\n fontFamily: 'monospace',\n padding: '4px 8px',\n borderRadius: '4px',\n border: 'none',\n background: 'transparent',\n cursor: 'pointer',\n },\n} as const;\n\nexport const TerminalHeader: React.FC<TerminalHeaderProps> = ({\n title,\n count,\n expanded,\n onClear,\n onToggleExpand,\n}) => {\n return (\n <div style={styles.header}>\n <div style={styles.left}>\n <div style={styles.trafficLights}>\n <div style={{ ...styles.dot, backgroundColor: '#ef4444' }} />\n <div style={{ ...styles.dot, backgroundColor: '#eab308' }} />\n <div style={{ ...styles.dot, backgroundColor: '#22c55e' }} />\n </div>\n <span style={styles.title}>{title}</span>\n <span style={styles.count}>({count} entries)</span>\n </div>\n <div style={styles.right}>\n <button\n onClick={onClear}\n style={styles.button}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n Clear\n </button>\n <button\n onClick={onToggleExpand}\n style={styles.button}\n onMouseEnter={(e) => (e.currentTarget.style.color = '#fff')}\n onMouseLeave={(e) => (e.currentTarget.style.color = '#9ca3af')}\n >\n {expanded ? '\\u25BC' : '\\u25B2'}\n </button>\n </div>\n </div>\n );\n};\n","import React, { useState } from 'react';\nimport { LogEntryProps } from '../types';\nimport { formatJson, formatTime } from '../utils/formatters';\nimport { getStatusColor, getMethodColor } from '../utils/colors';\n\nconst decodeSpecialChars = (str: string): string => {\n if (!str) return str;\n try {\n // Decode Unicode escape sequences like \\u003c to <\n return str.replace(/\\\\u([0-9a-fA-F]{4})/g, (_, code) =>\n String.fromCharCode(parseInt(code, 16))\n );\n } catch {\n return str;\n }\n};\n\nconst styles = {\n container: {\n marginBottom: '16px',\n borderBottom: '1px solid #1f2937',\n paddingBottom: '16px',\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n marginBottom: '4px',\n flexWrap: 'wrap' as const,\n },\n timestamp: {\n color: '#6b7280',\n fontSize: '12px',\n fontFamily: 'monospace',\n },\n method: {\n fontWeight: 'bold',\n fontFamily: 'monospace',\n },\n status: {\n fontWeight: 'bold',\n fontFamily: 'monospace',\n },\n duration: {\n color: '#6b7280',\n fontSize: '12px',\n fontFamily: 'monospace',\n },\n url: {\n color: '#60a5fa',\n wordBreak: 'break-all' as const,\n marginBottom: '8px',\n fontFamily: 'monospace',\n fontSize: '13px',\n },\n bodyContainer: {\n marginTop: '8px',\n },\n bodyLabel: {\n color: '#a78bfa',\n fontSize: '12px',\n marginBottom: '4px',\n fontFamily: 'monospace',\n },\n pre: {\n backgroundColor: '#1f2937',\n padding: '8px',\n borderRadius: '4px',\n color: '#86efac',\n overflowX: 'auto' as const,\n fontSize: '12px',\n whiteSpace: 'pre-wrap' as const,\n fontFamily: 'monospace',\n maxHeight: '192px',\n overflowY: 'auto' as const,\n margin: 0,\n },\n errorPre: {\n backgroundColor: '#1f2937',\n padding: '8px',\n borderRadius: '4px',\n color: '#fca5a5',\n overflowX: 'auto' as const,\n fontSize: '12px',\n whiteSpace: 'pre-wrap' as const,\n fontFamily: 'monospace',\n margin: 0,\n },\n bodyHeader: {\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n marginBottom: '4px',\n },\n copyButton: {\n backgroundColor: 'transparent',\n border: '1px solid #4b5563',\n borderRadius: '4px',\n color: '#9ca3af',\n cursor: 'pointer',\n fontSize: '11px',\n padding: '2px 8px',\n fontFamily: 'monospace',\n transition: 'all 0.2s',\n },\n copyButtonHover: {\n backgroundColor: '#374151',\n color: '#fff',\n },\n copyButtonCopied: {\n backgroundColor: '#065f46',\n borderColor: '#10b981',\n color: '#10b981',\n },\n} as const;\n\nexport const LogEntry: React.FC<LogEntryProps> = ({ log, type }) => {\n const [copiedField, setCopiedField] = useState<string | null>(null);\n const [hoveredButton, setHoveredButton] = useState<string | null>(null);\n\n const handleCopy = async (content: unknown, field: string) => {\n try {\n const text = decodeSpecialChars(formatJson(content));\n await navigator.clipboard.writeText(text);\n setCopiedField(field);\n setTimeout(() => setCopiedField(null), 2000);\n } catch (err) {\n console.error('Failed to copy:', err);\n }\n };\n\n const getButtonStyle = (field: string) => ({\n ...styles.copyButton,\n ...(hoveredButton === field && copiedField !== field ? styles.copyButtonHover : {}),\n ...(copiedField === field ? styles.copyButtonCopied : {}),\n });\n\n const formatContent = (data: unknown): string => {\n return decodeSpecialChars(formatJson(data));\n };\n\n return (\n <div style={styles.container}>\n <div style={styles.header}>\n <span style={styles.timestamp}>[{formatTime(log.timestamp)}]</span>\n <span style={{ ...styles.method, color: getMethodColor(log.method) }}>\n {log.method}\n </span>\n {type === 'response' && log.status && (\n <span style={{ ...styles.status, color: getStatusColor(log.status) }}>\n {log.status} {log.statusText}\n </span>\n )}\n {log.duration !== undefined && type === 'response' && (\n <span style={styles.duration}>({log.duration}ms)</span>\n )}\n </div>\n\n <div style={styles.url}>{log.url}</div>\n\n {type === 'request' ? (\n log.requestBody ? (\n <div style={styles.bodyContainer}>\n <div style={styles.bodyHeader}>\n <div style={styles.bodyLabel}>{'\\u25B8'} Payload:</div>\n <button\n style={getButtonStyle('payload')}\n onClick={() => handleCopy(log.requestBody, 'payload')}\n onMouseEnter={() => setHoveredButton('payload')}\n onMouseLeave={() => setHoveredButton(null)}\n >\n {copiedField === 'payload' ? 'Copied!' : 'Copy'}\n </button>\n </div>\n <pre style={styles.pre}>{formatContent(log.requestBody)}</pre>\n </div>\n ) : null\n ) : log.error ? (\n <div style={styles.bodyContainer}>\n <div style={styles.bodyHeader}>\n <div style={{ ...styles.bodyLabel, color: '#f87171' }}>\n {'\\u25B8'} Error:\n </div>\n <button\n style={getButtonStyle('error')}\n onClick={() => handleCopy(log.error, 'error')}\n onMouseEnter={() => setHoveredButton('error')}\n onMouseLeave={() => setHoveredButton(null)}\n >\n {copiedField === 'error' ? 'Copied!' : 'Copy'}\n </button>\n </div>\n <pre style={styles.errorPre}>{log.error}</pre>\n </div>\n ) : log.responseBody ? (\n <div style={styles.bodyContainer}>\n <div style={styles.bodyHeader}>\n <div style={styles.bodyLabel}>{'\\u25B8'} Response:</div>\n <button\n style={getButtonStyle('response')}\n onClick={() => handleCopy(log.responseBody, 'response')}\n onMouseEnter={() => setHoveredButton('response')}\n onMouseLeave={() => setHoveredButton(null)}\n >\n {copiedField === 'response' ? 'Copied!' : 'Copy'}\n </button>\n </div>\n <pre style={styles.pre}>{formatContent(log.responseBody)}</pre>\n </div>\n ) : null}\n </div>\n );\n};\n","export const formatJson = (data: unknown): string => {\n if (!data) return '';\n try {\n if (typeof data === 'string') {\n const parsed = JSON.parse(data);\n return JSON.stringify(parsed, null, 2);\n }\n return JSON.stringify(data, null, 2);\n } catch {\n return String(data);\n }\n};\n\nexport const truncate = (str: string, maxLength: number): string => {\n if (str.length <= maxLength) return str;\n return str.slice(0, maxLength) + '...';\n};\n\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour12: false,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n};\n","export const getStatusColor = (status?: number): string => {\n if (!status) return '#9ca3af'; // gray-400\n if (status >= 200 && status < 300) return '#4ade80'; // green-400\n if (status >= 300 && status < 400) return '#facc15'; // yellow-400\n if (status >= 400 && status < 500) return '#fb923c'; // orange-400\n return '#f87171'; // red-400\n};\n\nexport const getMethodColor = (method: string): string => {\n const colors: Record<string, string> = {\n GET: '#22d3ee', // cyan-400\n POST: '#4ade80', // green-400\n PUT: '#facc15', // yellow-400\n PATCH: '#fb923c', // orange-400\n DELETE: '#f87171', // red-400\n };\n return colors[method.toUpperCase()] || '#9ca3af';\n};\n","import { useEffect, useRef, useCallback } from 'react';\nimport { NetworkLog, UseNetworkInterceptorProps } from '../types';\n\nexport const useNetworkInterceptor = ({\n enabled,\n onLogAdd,\n onLogUpdate,\n}: UseNetworkInterceptorProps) => {\n const originalFetch = useRef<typeof fetch | null>(null);\n const originalXHROpen = useRef<typeof XMLHttpRequest.prototype.open | null>(null);\n const originalXHRSend = useRef<typeof XMLHttpRequest.prototype.send | null>(null);\n\n const generateId = useCallback((prefix: string) => {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n }, []);\n\n // Intercept Fetch\n useEffect(() => {\n if (!enabled) return;\n\n originalFetch.current = window.fetch;\n\n window.fetch = async function (input, init) {\n const id = generateId('fetch');\n const startTime = performance.now();\n\n const url =\n typeof input === 'string'\n ? input\n : input instanceof URL\n ? input.href\n : input.url;\n\n const method = init?.method || 'GET';\n\n let requestBody: unknown = null;\n if (init?.body) {\n try {\n requestBody =\n typeof init.body === 'string' ? JSON.parse(init.body) : init.body;\n } catch {\n requestBody = init.body;\n }\n }\n\n onLogAdd({\n id,\n timestamp: new Date(),\n method: method.toUpperCase(),\n url,\n requestBody,\n type: 'fetch',\n });\n\n try {\n const response = await originalFetch.current!(input, init);\n const duration = Math.round(performance.now() - startTime);\n\n const clonedResponse = response.clone();\n let responseBody: unknown = null;\n\n try {\n responseBody = await clonedResponse.json();\n } catch {\n try {\n responseBody = await clonedResponse.text();\n } catch {\n responseBody = '[Could not read response body]';\n }\n }\n\n onLogUpdate(id, {\n status: response.status,\n statusText: response.statusText,\n responseBody,\n duration,\n });\n\n return response;\n } catch (error: unknown) {\n const duration = Math.round(performance.now() - startTime);\n const errorMessage =\n error instanceof Error ? error.message : 'Network Error';\n onLogUpdate(id, {\n error: errorMessage,\n duration,\n });\n throw error;\n }\n };\n\n return () => {\n if (originalFetch.current) {\n window.fetch = originalFetch.current;\n }\n };\n }, [enabled, onLogAdd, onLogUpdate, generateId]);\n\n // Intercept XHR\n useEffect(() => {\n if (!enabled) return;\n\n originalXHROpen.current = XMLHttpRequest.prototype.open;\n originalXHRSend.current = XMLHttpRequest.prototype.send;\n\n XMLHttpRequest.prototype.open = function (\n method: string,\n url: string | URL\n ) {\n (this as XMLHttpRequest & { _networkTerminal: NetworkLog & { startTime: number } })._networkTerminal = {\n id: generateId('xhr'),\n method: method.toUpperCase(),\n url: url.toString(),\n startTime: 0,\n timestamp: new Date(),\n type: 'xhr',\n };\n return originalXHROpen.current!.apply(\n this,\n arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.open>\n );\n };\n\n XMLHttpRequest.prototype.send = function (body?: Document | XMLHttpRequestBodyInit | null) {\n const meta = (this as XMLHttpRequest & { _networkTerminal?: NetworkLog & { startTime: number } })._networkTerminal;\n\n if (meta) {\n meta.startTime = performance.now();\n\n let requestBody: unknown = null;\n if (body) {\n try {\n requestBody = typeof body === 'string' ? JSON.parse(body) : body;\n } catch {\n requestBody = body;\n }\n }\n\n onLogAdd({\n id: meta.id,\n timestamp: new Date(),\n method: meta.method,\n url: meta.url,\n requestBody,\n type: 'xhr',\n });\n\n this.addEventListener('load', function () {\n const duration = Math.round(performance.now() - meta.startTime);\n\n let responseBody: unknown = null;\n try {\n responseBody = JSON.parse(this.responseText);\n } catch {\n responseBody = this.responseText;\n }\n\n onLogUpdate(meta.id, {\n status: this.status,\n statusText: this.statusText,\n responseBody,\n duration,\n });\n });\n\n this.addEventListener('error', function () {\n const duration = Math.round(performance.now() - meta.startTime);\n onLogUpdate(meta.id, {\n error: 'Network Error',\n duration,\n });\n });\n }\n\n return originalXHRSend.current!.apply(\n this,\n arguments as unknown as Parameters<typeof XMLHttpRequest.prototype.send>\n );\n };\n\n return () => {\n if (originalXHROpen.current) {\n XMLHttpRequest.prototype.open = originalXHROpen.current;\n }\n if (originalXHRSend.current) {\n XMLHttpRequest.prototype.send = originalXHRSend.current;\n }\n };\n }, [enabled, onLogAdd, onLogUpdate, generateId]);\n};\n","import type { Plugin, ViteDevServer } from 'vite';\nimport { createServer, IncomingMessage, ServerResponse } from 'http';\nimport { exec } from 'child_process';\n\nexport interface NetworkTerminalPluginOptions {\n /** Port for the dashboard (default: 4001) */\n port?: number;\n /** Auto-open dashboard in browser (default: true) */\n open?: boolean;\n}\n\n// Store network logs\nconst networkLogs: any[] = [];\nconst sseClients = new Set<ServerResponse>();\n\nfunction broadcastLog(log: any) {\n const data = JSON.stringify(log);\n sseClients.forEach(client => {\n client.write(`data: ${data}\\n\\n`);\n });\n}\n\nfunction getDashboardHTML(_port: number): string {\n return `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Network Terminal</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body {\n font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;\n background: #0a0e17;\n color: #e2e8f0;\n height: 100vh;\n overflow: hidden;\n }\n .header {\n background: #0f172a;\n padding: 12px 24px;\n border-bottom: 2px solid #4ade80;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .title { color: #4ade80; font-size: 18px; font-weight: bold; }\n .subtitle { color: #64748b; font-size: 12px; margin-top: 4px; }\n .controls { display: flex; gap: 12px; align-items: center; }\n .btn {\n background: #1e293b;\n border: 1px solid #334155;\n color: #94a3b8;\n padding: 8px 16px;\n border-radius: 6px;\n cursor: pointer;\n font-size: 12px;\n font-family: inherit;\n }\n .btn:hover { background: #334155; color: #e2e8f0; }\n .container { display: flex; height: calc(100vh - 80px); }\n .panel {\n flex: 1;\n display: flex;\n flex-direction: column;\n border-right: 1px solid #1e293b;\n }\n .panel:last-child { border-right: none; }\n .panel-header {\n background: #0f172a;\n padding: 12px 16px;\n border-bottom: 1px solid #1e293b;\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n .panel-title { font-weight: bold; font-size: 14px; }\n .panel-title.request { color: #3b82f6; }\n .panel-title.response { color: #22c55e; }\n .panel-count {\n background: #1e293b;\n padding: 2px 8px;\n border-radius: 10px;\n font-size: 11px;\n color: #64748b;\n }\n .logs { flex: 1; overflow-y: auto; padding: 8px; }\n .log-entry {\n background: #0f172a;\n border: 1px solid #1e293b;\n border-radius: 8px;\n margin-bottom: 8px;\n overflow: hidden;\n cursor: pointer;\n transition: border-color 0.2s;\n }\n .log-entry:hover { border-color: #334155; }\n .log-entry.selected { border-color: #4ade80; }\n .log-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 12px;\n background: #1e293b;\n }\n .method {\n font-weight: bold;\n font-size: 11px;\n padding: 3px 8px;\n border-radius: 4px;\n }\n .method.GET { background: #166534; color: #4ade80; }\n .method.POST { background: #1e40af; color: #60a5fa; }\n .method.PUT { background: #a16207; color: #fcd34d; }\n .method.DELETE { background: #991b1b; color: #fca5a5; }\n .method.PATCH { background: #7c3aed; color: #c4b5fd; }\n .status { font-size: 11px; padding: 3px 8px; border-radius: 4px; }\n .status.success { background: #166534; color: #4ade80; }\n .status.error { background: #991b1b; color: #fca5a5; }\n .status.pending { background: #374151; color: #9ca3af; }\n .url {\n flex: 1;\n font-size: 12px;\n color: #94a3b8;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n .duration { font-size: 11px; color: #64748b; }\n .timestamp { font-size: 10px; color: #475569; }\n .log-body { padding: 12px; font-size: 11px; max-height: 300px; overflow: auto; }\n .log-body pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n color: #cbd5e1;\n line-height: 1.5;\n }\n .log-body.empty { color: #475569; font-style: italic; }\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n height: 100%;\n color: #475569;\n text-align: center;\n padding: 20px;\n }\n .empty-state svg { width: 48px; height: 48px; margin-bottom: 16px; opacity: 0.5; }\n .status-dot {\n width: 8px;\n height: 8px;\n border-radius: 50%;\n background: #22c55e;\n animation: pulse 2s infinite;\n }\n @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }\n .status-dot.disconnected { background: #ef4444; animation: none; }\n </style>\n</head>\n<body>\n <div class=\"header\">\n <div>\n <div class=\"title\">>_ Network Terminal</div>\n <div class=\"subtitle\">Vite Plugin - Monitoring fetch/XHR requests</div>\n </div>\n <div class=\"controls\">\n <div class=\"status-dot\" id=\"statusDot\"></div>\n <button class=\"btn\" onclick=\"clearLogs()\">Clear All</button>\n </div>\n </div>\n\n <div class=\"container\">\n <div class=\"panel\">\n <div class=\"panel-header\">\n <span class=\"panel-title request\">⬆ REQUESTS</span>\n <span class=\"panel-count\" id=\"requestCount\">0</span>\n </div>\n <div class=\"logs\" id=\"requestLogs\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 19V5M5 12l7-7 7 7\"/>\n </svg>\n <div>Waiting for requests...</div>\n <div style=\"margin-top: 8px; font-size: 11px;\">Make fetch/XHR requests in your app</div>\n </div>\n </div>\n </div>\n\n <div class=\"panel\">\n <div class=\"panel-header\">\n <span class=\"panel-title response\">⬇ RESPONSES</span>\n <span class=\"panel-count\" id=\"responseCount\">0</span>\n </div>\n <div class=\"logs\" id=\"responseLogs\">\n <div class=\"empty-state\">\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M12 5v14M5 12l7 7 7-7\"/>\n </svg>\n <div>Waiting for responses...</div>\n </div>\n </div>\n </div>\n </div>\n\n <script>\n const logs = new Map();\n let selectedId = null;\n\n function formatJson(data) {\n if (!data) return null;\n if (typeof data === 'string') {\n try { data = JSON.parse(data); }\n catch (e) { return escapeHtml(data.substring(0, 2000)); }\n }\n return escapeHtml(JSON.stringify(data, null, 2));\n }\n\n function escapeHtml(str) {\n if (typeof str !== 'string') str = String(str);\n return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n }\n\n function formatTime(timestamp) {\n const date = new Date(timestamp);\n return date.toLocaleTimeString('en-US', { hour12: false }) + '.' +\n String(date.getMilliseconds()).padStart(3, '0');\n }\n\n function getLogsArray() {\n return Array.from(logs.values()).sort((a, b) =>\n new Date(b.timestamp) - new Date(a.timestamp)\n );\n }\n\n function renderLogs() {\n const logsArray = getLogsArray();\n const requestContainer = document.getElementById('requestLogs');\n const responseContainer = document.getElementById('responseLogs');\n\n document.getElementById('requestCount').textContent = logsArray.length;\n document.getElementById('responseCount').textContent = logsArray.filter(l => l.status).length;\n\n if (logsArray.length === 0) {\n requestContainer.innerHTML = '<div class=\"empty-state\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 19V5M5 12l7-7 7 7\"/></svg><div>Waiting for requests...</div></div>';\n responseContainer.innerHTML = '<div class=\"empty-state\"><svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><path d=\"M12 5v14M5 12l7 7 7-7\"/></svg><div>Waiting for responses...</div></div>';\n return;\n }\n\n requestContainer.innerHTML = logsArray.map(log => {\n const isSelected = selectedId === log.id;\n const bodyContent = formatJson(log.requestBody);\n return '<div class=\"log-entry '+(isSelected ? 'selected' : '')+'\" onclick=\"selectLog(\\\\''+log.id+'\\\\')\"><div class=\"log-header\"><span class=\"method '+log.method+'\">'+log.method+'</span><span class=\"url\" title=\"'+escapeHtml(log.url)+'\">'+log.url+'</span><span class=\"timestamp\">'+formatTime(log.timestamp)+'</span></div>'+(isSelected ? '<div class=\"log-body '+(bodyContent ? '' : 'empty')+'\">'+(bodyContent ? '<pre>'+bodyContent+'</pre>' : 'No request body')+'</div>' : '')+'</div>';\n }).join('');\n\n responseContainer.innerHTML = logsArray.map(log => {\n const isSelected = selectedId === log.id;\n const statusClass = !log.status ? 'pending' : log.status < 400 ? 'success' : 'error';\n const bodyContent = formatJson(log.responseBody);\n return '<div class=\"log-entry '+(isSelected ? 'selected' : '')+'\" onclick=\"selectLog(\\\\''+log.id+'\\\\')\"><div class=\"log-header\"><span class=\"status '+statusClass+'\">'+(log.status || '...')+'</span><span class=\"url\" title=\"'+escapeHtml(log.url)+'\">'+log.url+'</span><span class=\"duration\">'+(log.duration ? log.duration + 'ms' : '')+'</span></div>'+(isSelected ? '<div class=\"log-body '+(bodyContent ? '' : 'empty')+'\">'+(bodyContent ? '<pre>'+bodyContent+'</pre>' : (log.status ? 'No response body' : 'Pending...'))+'</div>' : '')+'</div>';\n }).join('');\n }\n\n function selectLog(id) {\n selectedId = selectedId === id ? null : id;\n renderLogs();\n }\n\n function clearLogs() {\n logs.clear();\n selectedId = null;\n renderLogs();\n fetch('/clear', { method: 'POST' });\n }\n\n function addLog(log) {\n logs.set(log.id, log);\n if (logs.size > 100) {\n const oldest = getLogsArray().pop();\n if (oldest) logs.delete(oldest.id);\n }\n renderLogs();\n }\n\n function connect() {\n const evtSource = new EventSource('/events');\n evtSource.onopen = () => document.getElementById('statusDot').classList.remove('disconnected');\n evtSource.onmessage = (event) => addLog(JSON.parse(event.data));\n evtSource.onerror = () => {\n document.getElementById('statusDot').classList.add('disconnected');\n evtSource.close();\n setTimeout(connect, 2000);\n };\n }\n\n connect();\n renderLogs();\n </script>\n</body>\n</html>\n`;\n}\n\nfunction getMonitorScript(port: number): string {\n return `\n(function() {\n if (window.__networkTerminalActive) return;\n window.__networkTerminalActive = true;\n\n var DASHBOARD_URL = 'http://localhost:${port}';\n\n function sendLog(log) {\n var xhr = new XMLHttpRequest();\n xhr.open('POST', DASHBOARD_URL + '/log', true);\n xhr.setRequestHeader('Content-Type', 'application/json');\n xhr.send(JSON.stringify(log));\n }\n\n function tryParse(data) {\n if (!data) return null;\n if (typeof data === 'object') return data;\n try { return JSON.parse(data); } catch (e) { return data; }\n }\n\n var originalFetch = window.fetch;\n window.fetch = function() {\n var args = arguments;\n var startTime = Date.now();\n var input = args[0];\n var options = args[1] || {};\n var url = typeof input === 'string' ? input : (input.url || input.toString());\n var method = (options.method || 'GET').toUpperCase();\n\n if (url.includes('localhost:${port}')) {\n return originalFetch.apply(this, args);\n }\n\n var log = {\n id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n method: method,\n url: url,\n timestamp: new Date().toISOString(),\n requestBody: options.body ? tryParse(options.body) : null,\n status: null,\n responseBody: null,\n duration: null,\n };\n\n sendLog(log);\n\n return originalFetch.apply(this, args).then(function(response) {\n log.status = response.status;\n log.duration = Date.now() - startTime;\n var cloned = response.clone();\n cloned.text().then(function(text) {\n log.responseBody = tryParse(text);\n sendLog(log);\n }).catch(function() { sendLog(log); });\n return response;\n }).catch(function(error) {\n log.status = 0;\n log.duration = Date.now() - startTime;\n log.error = error.message;\n sendLog(log);\n throw error;\n });\n };\n\n var OriginalXHR = window.XMLHttpRequest;\n window.XMLHttpRequest = function() {\n var xhr = new OriginalXHR();\n var method, url, requestBody, startTime;\n\n var originalOpen = xhr.open;\n xhr.open = function(m, u) {\n method = m;\n url = u;\n return originalOpen.apply(this, arguments);\n };\n\n var originalSend = xhr.send;\n xhr.send = function(body) {\n if (url && url.includes('localhost:${port}')) {\n return originalSend.apply(this, arguments);\n }\n\n startTime = Date.now();\n requestBody = body;\n\n var log = {\n id: Date.now().toString() + Math.random().toString(36).substr(2, 9),\n method: (method || 'GET').toUpperCase(),\n url: url,\n timestamp: new Date().toISOString(),\n requestBody: tryParse(requestBody),\n status: null,\n responseBody: null,\n duration: null,\n };\n\n sendLog(log);\n\n xhr.addEventListener('loadend', function() {\n log.status = xhr.status;\n log.duration = Date.now() - startTime;\n log.responseBody = tryParse(xhr.responseText);\n sendLog(log);\n });\n\n return originalSend.apply(this, arguments);\n };\n\n return xhr;\n };\n\n console.log('[Network Terminal] ✓ Active - Dashboard: http://localhost:${port}');\n})();\n`;\n}\n\nexport function networkTerminal(options: NetworkTerminalPluginOptions = {}): Plugin {\n const { port = 4001, open = true } = options;\n let dashboardServer: ReturnType<typeof createServer> | null = null;\n\n return {\n name: 'vite-plugin-network-terminal',\n apply: 'serve',\n\n configureServer(_server: ViteDevServer) {\n // Start dashboard server\n dashboardServer = createServer((req: IncomingMessage, res: ServerResponse) => {\n res.setHeader('Access-Control-Allow-Origin', '*');\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type');\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204);\n res.end();\n return;\n }\n\n if (req.url === '/events') {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n });\n sseClients.add(res);\n networkLogs.forEach(log => {\n res.write(`data: ${JSON.stringify(log)}\\n\\n`);\n });\n req.on('close', () => sseClients.delete(res));\n return;\n }\n\n if (req.url === '/log' && req.method === 'POST') {\n let body = '';\n req.on('data', (chunk: Buffer) => body += chunk);\n req.on('end', () => {\n try {\n const log = JSON.parse(body);\n const existingIndex = networkLogs.findIndex(l => l.id === log.id);\n if (existingIndex >= 0) {\n networkLogs[existingIndex] = log;\n } else {\n networkLogs.unshift(log);\n if (networkLogs.length > 100) networkLogs.pop();\n }\n broadcastLog(log);\n } catch (e) {}\n res.writeHead(200);\n res.end('OK');\n });\n return;\n }\n\n if (req.url === '/clear' && req.method === 'POST') {\n networkLogs.length = 0;\n res.writeHead(200);\n res.end('OK');\n return;\n }\n\n res.writeHead(200, { 'Content-Type': 'text/html' });\n res.end(getDashboardHTML(port));\n });\n\n dashboardServer.listen(port, () => {\n console.log(`\\n \\x1b[32m>_ Network Terminal\\x1b[0m`);\n console.log(` Dashboard: \\x1b[36mhttp://localhost:${port}\\x1b[0m\\n`);\n\n if (open) {\n const openCmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';\n exec(`${openCmd} http://localhost:${port}`);\n }\n });\n\n dashboardServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n console.log(`\\n \\x1b[33m[Network Terminal]\\x1b[0m Port ${port} in use, dashboard disabled\\n`);\n }\n });\n },\n\n transformIndexHtml(html: string) {\n const script = `<script>${getMonitorScript(port)}</script>`;\n if (html.includes('</head>')) {\n return html.replace('</head>', script + '</head>');\n }\n return script + html;\n },\n\n buildEnd() {\n if (dashboardServer) {\n dashboardServer.close();\n }\n },\n };\n}\n\nexport default networkTerminal;\n"],"mappings":"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","names":["useState","useCallback","useEffect","useState","jsx","jsxs","styles","jsx","jsxs","styles","useState","useEffect","useRef","jsx","jsxs","styles","useState","useCallback","useEffect"]}
@@ -25,6 +25,7 @@ __export(vite_plugin_exports, {
25
25
  });
26
26
  module.exports = __toCommonJS(vite_plugin_exports);
27
27
  var import_http = require("http");
28
+ var import_child_process = require("child_process");
28
29
  var networkLogs = [];
29
30
  var sseClients = /* @__PURE__ */ new Set();
30
31
  function broadcastLog(log) {
@@ -501,7 +502,7 @@ function networkTerminal(options = {}) {
501
502
  `);
502
503
  if (open) {
503
504
  const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
504
- require("child_process").exec(`${openCmd} http://localhost:${port}`);
505
+ (0, import_child_process.exec)(`${openCmd} http://localhost:${port}`);
505
506
  }
506
507
  });
507
508
  dashboardServer.on("error", (err) => {