network-terminal 1.0.5 → 1.0.7
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/bin/cli.js +69 -23
- package/package.json +4 -4
- package/standalone-dist/assets/index-DNYlGkS8.js +40 -0
- package/{standalone → standalone-dist}/index.html +1 -1
- package/src/components/LogEntry.tsx +0 -121
- package/src/components/NetworkTerminal.tsx +0 -219
- package/src/components/Terminal.tsx +0 -86
- package/src/components/TerminalHeader.tsx +0 -93
- package/src/hooks/useNetworkInterceptor.ts +0 -190
- package/src/index.ts +0 -17
- package/src/types.ts +0 -50
- package/src/utils/colors.ts +0 -18
- package/src/utils/formatters.ts +0 -26
- package/src/vite-plugin.ts +0 -88
- package/standalone/main.tsx +0 -216
- package/standalone/vite.config.js +0 -19
package/src/index.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export { NetworkTerminal } from './components/NetworkTerminal';
|
|
2
|
-
export { Terminal } from './components/Terminal';
|
|
3
|
-
export { TerminalHeader } from './components/TerminalHeader';
|
|
4
|
-
export { LogEntry } from './components/LogEntry';
|
|
5
|
-
export { useNetworkInterceptor } from './hooks/useNetworkInterceptor';
|
|
6
|
-
export { formatJson, truncate, formatTime } from './utils/formatters';
|
|
7
|
-
export { getStatusColor, getMethodColor } from './utils/colors';
|
|
8
|
-
export { networkTerminal } from './vite-plugin';
|
|
9
|
-
export type {
|
|
10
|
-
NetworkLog,
|
|
11
|
-
NetworkTerminalProps,
|
|
12
|
-
TerminalProps,
|
|
13
|
-
TerminalHeaderProps,
|
|
14
|
-
LogEntryProps,
|
|
15
|
-
UseNetworkInterceptorProps,
|
|
16
|
-
} from './types';
|
|
17
|
-
export type { NetworkTerminalPluginOptions } from './vite-plugin';
|
package/src/types.ts
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
export interface NetworkLog {
|
|
2
|
-
id: string;
|
|
3
|
-
timestamp: Date;
|
|
4
|
-
method: string;
|
|
5
|
-
url: string;
|
|
6
|
-
status?: number;
|
|
7
|
-
statusText?: string;
|
|
8
|
-
requestHeaders?: Record<string, string>;
|
|
9
|
-
requestBody?: unknown;
|
|
10
|
-
responseBody?: unknown;
|
|
11
|
-
duration?: number;
|
|
12
|
-
error?: string;
|
|
13
|
-
type: 'fetch' | 'xhr';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export interface TerminalProps {
|
|
17
|
-
title: string;
|
|
18
|
-
logs: NetworkLog[];
|
|
19
|
-
type: 'request' | 'response';
|
|
20
|
-
onClear: () => void;
|
|
21
|
-
expanded: boolean;
|
|
22
|
-
onToggleExpand: () => void;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface LogEntryProps {
|
|
26
|
-
log: NetworkLog;
|
|
27
|
-
type: 'request' | 'response';
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface TerminalHeaderProps {
|
|
31
|
-
title: string;
|
|
32
|
-
count: number;
|
|
33
|
-
expanded: boolean;
|
|
34
|
-
onClear: () => void;
|
|
35
|
-
onToggleExpand: () => void;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export interface UseNetworkInterceptorProps {
|
|
39
|
-
enabled: boolean;
|
|
40
|
-
onLogAdd: (log: NetworkLog) => void;
|
|
41
|
-
onLogUpdate: (id: string, updates: Partial<NetworkLog>) => void;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export interface NetworkTerminalProps {
|
|
45
|
-
maxLogs?: number;
|
|
46
|
-
defaultVisible?: boolean;
|
|
47
|
-
position?: 'bottom' | 'top';
|
|
48
|
-
height?: string;
|
|
49
|
-
zIndex?: number;
|
|
50
|
-
}
|
package/src/utils/colors.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export const getStatusColor = (status?: number): string => {
|
|
2
|
-
if (!status) return '#9ca3af'; // gray-400
|
|
3
|
-
if (status >= 200 && status < 300) return '#4ade80'; // green-400
|
|
4
|
-
if (status >= 300 && status < 400) return '#facc15'; // yellow-400
|
|
5
|
-
if (status >= 400 && status < 500) return '#fb923c'; // orange-400
|
|
6
|
-
return '#f87171'; // red-400
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
export const getMethodColor = (method: string): string => {
|
|
10
|
-
const colors: Record<string, string> = {
|
|
11
|
-
GET: '#22d3ee', // cyan-400
|
|
12
|
-
POST: '#4ade80', // green-400
|
|
13
|
-
PUT: '#facc15', // yellow-400
|
|
14
|
-
PATCH: '#fb923c', // orange-400
|
|
15
|
-
DELETE: '#f87171', // red-400
|
|
16
|
-
};
|
|
17
|
-
return colors[method.toUpperCase()] || '#9ca3af';
|
|
18
|
-
};
|
package/src/utils/formatters.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
export const formatJson = (data: unknown): string => {
|
|
2
|
-
if (!data) return '';
|
|
3
|
-
try {
|
|
4
|
-
if (typeof data === 'string') {
|
|
5
|
-
const parsed = JSON.parse(data);
|
|
6
|
-
return JSON.stringify(parsed, null, 2);
|
|
7
|
-
}
|
|
8
|
-
return JSON.stringify(data, null, 2);
|
|
9
|
-
} catch {
|
|
10
|
-
return String(data);
|
|
11
|
-
}
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
export const truncate = (str: string, maxLength: number): string => {
|
|
15
|
-
if (str.length <= maxLength) return str;
|
|
16
|
-
return str.slice(0, maxLength) + '...';
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
export const formatTime = (date: Date): string => {
|
|
20
|
-
return date.toLocaleTimeString('en-US', {
|
|
21
|
-
hour12: false,
|
|
22
|
-
hour: '2-digit',
|
|
23
|
-
minute: '2-digit',
|
|
24
|
-
second: '2-digit',
|
|
25
|
-
});
|
|
26
|
-
};
|
package/src/vite-plugin.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from 'vite';
|
|
2
|
-
|
|
3
|
-
export interface NetworkTerminalPluginOptions {
|
|
4
|
-
/** Position of the terminal: 'top' or 'bottom' (default: 'bottom') */
|
|
5
|
-
position?: 'top' | 'bottom';
|
|
6
|
-
/** Maximum number of logs to keep (default: 100) */
|
|
7
|
-
maxLogs?: number;
|
|
8
|
-
/** Terminal height (default: '450px') */
|
|
9
|
-
height?: string;
|
|
10
|
-
/** CSS z-index (default: 9999) */
|
|
11
|
-
zIndex?: number;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const VIRTUAL_MODULE_ID = 'virtual:network-terminal';
|
|
15
|
-
const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
|
|
16
|
-
|
|
17
|
-
export function networkTerminal(options: NetworkTerminalPluginOptions = {}): Plugin {
|
|
18
|
-
const {
|
|
19
|
-
position = 'bottom',
|
|
20
|
-
maxLogs = 100,
|
|
21
|
-
height = '450px',
|
|
22
|
-
zIndex = 9999,
|
|
23
|
-
} = options;
|
|
24
|
-
|
|
25
|
-
return {
|
|
26
|
-
name: 'vite-plugin-network-terminal',
|
|
27
|
-
apply: 'serve', // Only apply during development
|
|
28
|
-
|
|
29
|
-
resolveId(id) {
|
|
30
|
-
if (id === VIRTUAL_MODULE_ID) {
|
|
31
|
-
return RESOLVED_VIRTUAL_MODULE_ID;
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
load(id) {
|
|
36
|
-
if (id === RESOLVED_VIRTUAL_MODULE_ID) {
|
|
37
|
-
return `
|
|
38
|
-
import React from 'react';
|
|
39
|
-
import ReactDOM from 'react-dom/client';
|
|
40
|
-
import { NetworkTerminal } from 'network-terminal';
|
|
41
|
-
|
|
42
|
-
function initNetworkTerminal() {
|
|
43
|
-
const containerId = '__network-terminal-root__';
|
|
44
|
-
let container = document.getElementById(containerId);
|
|
45
|
-
|
|
46
|
-
if (!container) {
|
|
47
|
-
container = document.createElement('div');
|
|
48
|
-
container.id = containerId;
|
|
49
|
-
document.body.appendChild(container);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const root = ReactDOM.createRoot(container);
|
|
53
|
-
root.render(
|
|
54
|
-
React.createElement(NetworkTerminal, {
|
|
55
|
-
position: '${position}',
|
|
56
|
-
maxLogs: ${maxLogs},
|
|
57
|
-
height: '${height}',
|
|
58
|
-
zIndex: ${zIndex},
|
|
59
|
-
defaultVisible: false,
|
|
60
|
-
})
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
if (document.readyState === 'loading') {
|
|
65
|
-
document.addEventListener('DOMContentLoaded', initNetworkTerminal);
|
|
66
|
-
} else {
|
|
67
|
-
initNetworkTerminal();
|
|
68
|
-
}
|
|
69
|
-
`;
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
|
|
73
|
-
transformIndexHtml(html) {
|
|
74
|
-
return {
|
|
75
|
-
html,
|
|
76
|
-
tags: [
|
|
77
|
-
{
|
|
78
|
-
tag: 'script',
|
|
79
|
-
attrs: { type: 'module', src: '/@id/__x00__virtual:network-terminal' },
|
|
80
|
-
injectTo: 'body',
|
|
81
|
-
},
|
|
82
|
-
],
|
|
83
|
-
};
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export default networkTerminal;
|
package/standalone/main.tsx
DELETED
|
@@ -1,216 +0,0 @@
|
|
|
1
|
-
import React, { useState } from 'react';
|
|
2
|
-
import ReactDOM from 'react-dom/client';
|
|
3
|
-
import { NetworkTerminal } from '../dist/index.mjs';
|
|
4
|
-
|
|
5
|
-
const styles = {
|
|
6
|
-
container: {
|
|
7
|
-
padding: '40px',
|
|
8
|
-
maxWidth: '800px',
|
|
9
|
-
margin: '0 auto',
|
|
10
|
-
},
|
|
11
|
-
header: {
|
|
12
|
-
marginBottom: '40px',
|
|
13
|
-
},
|
|
14
|
-
title: {
|
|
15
|
-
fontSize: '32px',
|
|
16
|
-
fontWeight: 'bold',
|
|
17
|
-
color: '#4ade80',
|
|
18
|
-
fontFamily: 'monospace',
|
|
19
|
-
marginBottom: '8px',
|
|
20
|
-
},
|
|
21
|
-
subtitle: {
|
|
22
|
-
color: '#94a3b8',
|
|
23
|
-
fontSize: '16px',
|
|
24
|
-
},
|
|
25
|
-
section: {
|
|
26
|
-
background: '#1e293b',
|
|
27
|
-
borderRadius: '12px',
|
|
28
|
-
padding: '24px',
|
|
29
|
-
marginBottom: '24px',
|
|
30
|
-
},
|
|
31
|
-
sectionTitle: {
|
|
32
|
-
fontSize: '18px',
|
|
33
|
-
fontWeight: '600',
|
|
34
|
-
marginBottom: '16px',
|
|
35
|
-
color: '#f1f5f9',
|
|
36
|
-
},
|
|
37
|
-
buttonGroup: {
|
|
38
|
-
display: 'flex',
|
|
39
|
-
gap: '12px',
|
|
40
|
-
flexWrap: 'wrap' as const,
|
|
41
|
-
},
|
|
42
|
-
button: {
|
|
43
|
-
padding: '10px 20px',
|
|
44
|
-
borderRadius: '8px',
|
|
45
|
-
border: 'none',
|
|
46
|
-
cursor: 'pointer',
|
|
47
|
-
fontWeight: '500',
|
|
48
|
-
fontSize: '14px',
|
|
49
|
-
transition: 'all 0.2s',
|
|
50
|
-
},
|
|
51
|
-
getButton: {
|
|
52
|
-
background: '#22c55e',
|
|
53
|
-
color: '#000',
|
|
54
|
-
},
|
|
55
|
-
postButton: {
|
|
56
|
-
background: '#3b82f6',
|
|
57
|
-
color: '#fff',
|
|
58
|
-
},
|
|
59
|
-
putButton: {
|
|
60
|
-
background: '#f59e0b',
|
|
61
|
-
color: '#000',
|
|
62
|
-
},
|
|
63
|
-
deleteButton: {
|
|
64
|
-
background: '#ef4444',
|
|
65
|
-
color: '#fff',
|
|
66
|
-
},
|
|
67
|
-
errorButton: {
|
|
68
|
-
background: '#6b7280',
|
|
69
|
-
color: '#fff',
|
|
70
|
-
},
|
|
71
|
-
inputGroup: {
|
|
72
|
-
display: 'flex',
|
|
73
|
-
gap: '12px',
|
|
74
|
-
marginBottom: '16px',
|
|
75
|
-
},
|
|
76
|
-
input: {
|
|
77
|
-
flex: 1,
|
|
78
|
-
padding: '10px 16px',
|
|
79
|
-
borderRadius: '8px',
|
|
80
|
-
border: '1px solid #374151',
|
|
81
|
-
background: '#0f172a',
|
|
82
|
-
color: '#e2e8f0',
|
|
83
|
-
fontSize: '14px',
|
|
84
|
-
},
|
|
85
|
-
hint: {
|
|
86
|
-
marginTop: '24px',
|
|
87
|
-
padding: '16px',
|
|
88
|
-
background: '#0f172a',
|
|
89
|
-
borderRadius: '8px',
|
|
90
|
-
borderLeft: '4px solid #4ade80',
|
|
91
|
-
},
|
|
92
|
-
hintText: {
|
|
93
|
-
color: '#94a3b8',
|
|
94
|
-
fontSize: '14px',
|
|
95
|
-
fontFamily: 'monospace',
|
|
96
|
-
},
|
|
97
|
-
kbd: {
|
|
98
|
-
background: '#374151',
|
|
99
|
-
padding: '2px 8px',
|
|
100
|
-
borderRadius: '4px',
|
|
101
|
-
fontSize: '12px',
|
|
102
|
-
color: '#4ade80',
|
|
103
|
-
},
|
|
104
|
-
};
|
|
105
|
-
|
|
106
|
-
function App() {
|
|
107
|
-
const [customUrl, setCustomUrl] = useState('https://jsonplaceholder.typicode.com/posts/1');
|
|
108
|
-
|
|
109
|
-
const makeRequest = async (method: string, url: string, body?: object) => {
|
|
110
|
-
try {
|
|
111
|
-
const options: RequestInit = {
|
|
112
|
-
method,
|
|
113
|
-
headers: {
|
|
114
|
-
'Content-Type': 'application/json',
|
|
115
|
-
},
|
|
116
|
-
};
|
|
117
|
-
if (body) {
|
|
118
|
-
options.body = JSON.stringify(body);
|
|
119
|
-
}
|
|
120
|
-
await fetch(url, options);
|
|
121
|
-
} catch (error) {
|
|
122
|
-
console.error('Request failed:', error);
|
|
123
|
-
}
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<div style={styles.container}>
|
|
128
|
-
<div style={styles.header}>
|
|
129
|
-
<h1 style={styles.title}>>_ Network Terminal</h1>
|
|
130
|
-
<p style={styles.subtitle}>Monitor your Fetch/XHR requests in real-time</p>
|
|
131
|
-
</div>
|
|
132
|
-
|
|
133
|
-
<div style={styles.section}>
|
|
134
|
-
<h2 style={styles.sectionTitle}>Quick Actions</h2>
|
|
135
|
-
<div style={styles.buttonGroup}>
|
|
136
|
-
<button
|
|
137
|
-
style={{ ...styles.button, ...styles.getButton }}
|
|
138
|
-
onClick={() => makeRequest('GET', 'https://jsonplaceholder.typicode.com/posts/1')}
|
|
139
|
-
>
|
|
140
|
-
GET Request
|
|
141
|
-
</button>
|
|
142
|
-
<button
|
|
143
|
-
style={{ ...styles.button, ...styles.postButton }}
|
|
144
|
-
onClick={() =>
|
|
145
|
-
makeRequest('POST', 'https://jsonplaceholder.typicode.com/posts', {
|
|
146
|
-
title: 'Test Post',
|
|
147
|
-
body: 'This is a test post body',
|
|
148
|
-
userId: 1,
|
|
149
|
-
})
|
|
150
|
-
}
|
|
151
|
-
>
|
|
152
|
-
POST Request
|
|
153
|
-
</button>
|
|
154
|
-
<button
|
|
155
|
-
style={{ ...styles.button, ...styles.putButton }}
|
|
156
|
-
onClick={() =>
|
|
157
|
-
makeRequest('PUT', 'https://jsonplaceholder.typicode.com/posts/1', {
|
|
158
|
-
id: 1,
|
|
159
|
-
title: 'Updated Title',
|
|
160
|
-
body: 'Updated body content',
|
|
161
|
-
userId: 1,
|
|
162
|
-
})
|
|
163
|
-
}
|
|
164
|
-
>
|
|
165
|
-
PUT Request
|
|
166
|
-
</button>
|
|
167
|
-
<button
|
|
168
|
-
style={{ ...styles.button, ...styles.deleteButton }}
|
|
169
|
-
onClick={() => makeRequest('DELETE', 'https://jsonplaceholder.typicode.com/posts/1')}
|
|
170
|
-
>
|
|
171
|
-
DELETE Request
|
|
172
|
-
</button>
|
|
173
|
-
<button
|
|
174
|
-
style={{ ...styles.button, ...styles.errorButton }}
|
|
175
|
-
onClick={() => makeRequest('GET', 'https://jsonplaceholder.typicode.com/invalid-endpoint')}
|
|
176
|
-
>
|
|
177
|
-
404 Error
|
|
178
|
-
</button>
|
|
179
|
-
</div>
|
|
180
|
-
</div>
|
|
181
|
-
|
|
182
|
-
<div style={styles.section}>
|
|
183
|
-
<h2 style={styles.sectionTitle}>Custom Request</h2>
|
|
184
|
-
<div style={styles.inputGroup}>
|
|
185
|
-
<input
|
|
186
|
-
type="text"
|
|
187
|
-
value={customUrl}
|
|
188
|
-
onChange={(e) => setCustomUrl(e.target.value)}
|
|
189
|
-
placeholder="Enter URL..."
|
|
190
|
-
style={styles.input}
|
|
191
|
-
/>
|
|
192
|
-
<button
|
|
193
|
-
style={{ ...styles.button, ...styles.getButton }}
|
|
194
|
-
onClick={() => makeRequest('GET', customUrl)}
|
|
195
|
-
>
|
|
196
|
-
Send GET
|
|
197
|
-
</button>
|
|
198
|
-
</div>
|
|
199
|
-
</div>
|
|
200
|
-
|
|
201
|
-
<div style={styles.hint}>
|
|
202
|
-
<p style={styles.hintText}>
|
|
203
|
-
Press <span style={styles.kbd}>Ctrl+Shift+N</span> to toggle the Network Terminal
|
|
204
|
-
</p>
|
|
205
|
-
</div>
|
|
206
|
-
|
|
207
|
-
<NetworkTerminal defaultVisible={true} position="bottom" maxLogs={50} />
|
|
208
|
-
</div>
|
|
209
|
-
);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
213
|
-
<React.StrictMode>
|
|
214
|
-
<App />
|
|
215
|
-
</React.StrictMode>
|
|
216
|
-
);
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import react from '@vitejs/plugin-react';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { fileURLToPath } from 'url';
|
|
5
|
-
|
|
6
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
-
|
|
8
|
-
export default defineConfig({
|
|
9
|
-
plugins: [react()],
|
|
10
|
-
resolve: {
|
|
11
|
-
alias: {
|
|
12
|
-
'react': path.resolve(__dirname, '../node_modules/react'),
|
|
13
|
-
'react-dom': path.resolve(__dirname, '../node_modules/react-dom'),
|
|
14
|
-
},
|
|
15
|
-
},
|
|
16
|
-
optimizeDeps: {
|
|
17
|
-
include: ['react', 'react-dom', 'react-dom/client'],
|
|
18
|
-
},
|
|
19
|
-
});
|