@dpkrn/nodetunnel 1.0.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -0
- package/README.md +34 -11
- package/cmd/test-lib/main.js +15 -0
- package/internal/inspector/index.js +1012 -0
- package/internal/inspector/inspector.css +1085 -0
- package/internal/inspector/inspector.html +263 -0
- package/internal/inspector/inspector.js +601 -0
- package/internal/{tunnel → inspector}/logstore.js +13 -0
- package/internal/inspector/theme-postman.css +38 -0
- package/internal/inspector/theme-terminal.css +38 -0
- package/internal/tunnel/tunnel.js +15 -12
- package/package.json +3 -1
- package/pkg/tunnel/tunnel.js +1 -1
- package/internal/tunnel/inspector-page.html +0 -482
- package/internal/tunnel/inspector.js +0 -266
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en" data-theme="postman">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>Inspector</title>
|
|
7
|
+
<link rel="stylesheet" href="inspector.css">
|
|
8
|
+
<link rel="stylesheet" href="theme-postman.css">
|
|
9
|
+
<link rel="stylesheet" href="theme-terminal.css">
|
|
10
|
+
<script>window.__LOCAL_APP_PORT__='__NT_PORT_VALUE__'</script>
|
|
11
|
+
<script>window.__NT_INSPECTOR_THEME_SEED__='__THEME_SEED__'</script>
|
|
12
|
+
<script src="index.js" defer></script>
|
|
13
|
+
</head>
|
|
14
|
+
<body>
|
|
15
|
+
<div class="app">
|
|
16
|
+
<div id="origin-hint"></div>
|
|
17
|
+
<header class="topbar">
|
|
18
|
+
<h1>Traffic inspector</h1>
|
|
19
|
+
<span id="wsStatus" class="status-dot" title="WebSocket"></span>
|
|
20
|
+
<span class="hint">Live · history · reset · replay targets your local app (not this UI port)</span>
|
|
21
|
+
<div class="theme-row">
|
|
22
|
+
<label for="themeSelect">Theme</label>
|
|
23
|
+
<select id="themeSelect" title="UI theme">
|
|
24
|
+
<option value="postman">Postman</option>
|
|
25
|
+
<option value="terminal">Terminal</option>
|
|
26
|
+
</select>
|
|
27
|
+
</div>
|
|
28
|
+
<div class="target-row">
|
|
29
|
+
<label for="targetBase">Replay base</label>
|
|
30
|
+
<input id="targetBase" type="text" placeholder="http://localhost:__NT_PORT_VALUE__" autocomplete="off" />
|
|
31
|
+
</div>
|
|
32
|
+
</header>
|
|
33
|
+
<div class="main">
|
|
34
|
+
<aside class="sidebar" id="sidebar">
|
|
35
|
+
<div class="sidebar-head sidebar-head-row">
|
|
36
|
+
<span class="sidebar-title">Requests</span>
|
|
37
|
+
<div class="sidebar-head-tools">
|
|
38
|
+
<button
|
|
39
|
+
type="button"
|
|
40
|
+
id="sidebarOrderBtn"
|
|
41
|
+
class="sidebar-order-btn"
|
|
42
|
+
data-order="newest"
|
|
43
|
+
title="Newest first — click for oldest first"
|
|
44
|
+
aria-label="Newest first. Click to show oldest first."
|
|
45
|
+
>
|
|
46
|
+
<svg class="sidebar-order-icon" viewBox="0 0 24 24" width="16" height="16" aria-hidden="true">
|
|
47
|
+
<path
|
|
48
|
+
fill="currentColor"
|
|
49
|
+
d="M4 4h16v2.25H4V4zm0 6.875h12v2.25H4v-2.25zm0 6.875h8v2.25H4v-2.25z"
|
|
50
|
+
/>
|
|
51
|
+
</svg>
|
|
52
|
+
</button>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
<div class="sidebar-search">
|
|
56
|
+
<input type="search" id="sidebarSearch" placeholder="Filter history (path, method, status, id…)" autocomplete="off" />
|
|
57
|
+
</div>
|
|
58
|
+
<ul id="logList"></ul>
|
|
59
|
+
</aside>
|
|
60
|
+
<div class="resizer-h" id="resizerH" title="Drag to resize"></div>
|
|
61
|
+
<section class="workspace">
|
|
62
|
+
<div class="url-bar">
|
|
63
|
+
<select id="method">
|
|
64
|
+
<option>GET</option>
|
|
65
|
+
<option>POST</option>
|
|
66
|
+
<option>PUT</option>
|
|
67
|
+
<option>PATCH</option>
|
|
68
|
+
<option>DELETE</option>
|
|
69
|
+
<option>HEAD</option>
|
|
70
|
+
<option>OPTIONS</option>
|
|
71
|
+
</select>
|
|
72
|
+
<input id="url" type="text" placeholder="Path and query (e.g. /api/foo?x=1)" />
|
|
73
|
+
<label class="log-replay-toggle" title="When on, inspector stores this replay in history and notifies viewers (header X-Inspector-Log-Replay)">
|
|
74
|
+
<input type="checkbox" id="logReplayToHistory" />
|
|
75
|
+
<span>Log replay</span>
|
|
76
|
+
</label>
|
|
77
|
+
<button type="button" class="btn btn-replay" id="btnReplay" title="Send this request to your local server">Replay</button>
|
|
78
|
+
<button type="button" class="btn btn-modify" id="btnReset" title="Reload captured request into editors">Reset</button>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
<div class="split-v-wrap" id="splitVWrap">
|
|
82
|
+
<div class="pane-req" id="paneReq">
|
|
83
|
+
<div class="request-config">
|
|
84
|
+
<div class="config-tabs" role="tablist">
|
|
85
|
+
<button type="button" class="config-tab" data-panel="params" role="tab">Params <span class="badge" id="params-badge">0</span></button>
|
|
86
|
+
<button type="button" class="config-tab" data-panel="auth" role="tab">Authorization</button>
|
|
87
|
+
<button type="button" class="config-tab active" data-panel="headers" role="tab">Headers <span class="badge" id="headers-badge">0</span></button>
|
|
88
|
+
<button type="button" class="config-tab" data-panel="body" role="tab">Body</button>
|
|
89
|
+
<button type="button" class="config-tab" data-panel="scripts" role="tab">Scripts</button>
|
|
90
|
+
<button type="button" class="config-tab" data-panel="settings" role="tab">Settings</button>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
|
|
94
|
+
<div class="config-panels">
|
|
95
|
+
<div id="panel-params" class="config-panel params-area" hidden>
|
|
96
|
+
<div class="params-hint">Query params (merged into URL on Replay)</div>
|
|
97
|
+
<table class="params-table">
|
|
98
|
+
<thead>
|
|
99
|
+
<tr>
|
|
100
|
+
<th class="th-check"></th>
|
|
101
|
+
<th>Key</th>
|
|
102
|
+
<th>Value</th>
|
|
103
|
+
<th>Description</th>
|
|
104
|
+
<th class="th-del"></th>
|
|
105
|
+
</tr>
|
|
106
|
+
</thead>
|
|
107
|
+
<tbody id="params-tbody"></tbody>
|
|
108
|
+
</table>
|
|
109
|
+
<button type="button" class="add-row-btn" id="add-param-row">+ Add parameter</button>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<div id="panel-auth" class="config-panel params-area" hidden>
|
|
113
|
+
<div class="auth-row">
|
|
114
|
+
<span class="auth-label">Auth type</span>
|
|
115
|
+
<select id="authType" class="auth-select">
|
|
116
|
+
<option value="none">No Auth</option>
|
|
117
|
+
<option value="bearer">Bearer Token</option>
|
|
118
|
+
<option value="basic">Basic Auth</option>
|
|
119
|
+
<option value="apikey">API Key</option>
|
|
120
|
+
</select>
|
|
121
|
+
</div>
|
|
122
|
+
<div id="auth-bearer-block" class="auth-block">
|
|
123
|
+
<span class="auth-label">Token</span>
|
|
124
|
+
<input type="text" id="authToken" class="auth-input" placeholder="Bearer token" autocomplete="off" />
|
|
125
|
+
</div>
|
|
126
|
+
<div id="auth-basic-block" class="auth-block" hidden>
|
|
127
|
+
<span class="auth-label">Username</span>
|
|
128
|
+
<input type="text" id="authBasicUser" class="auth-input" autocomplete="off" />
|
|
129
|
+
<span class="auth-label">Password</span>
|
|
130
|
+
<input type="password" id="authBasicPass" class="auth-input" autocomplete="off" />
|
|
131
|
+
</div>
|
|
132
|
+
<div id="auth-apikey-block" class="auth-block" hidden>
|
|
133
|
+
<span class="auth-label">Key / Value</span>
|
|
134
|
+
<input type="text" id="authApiKeyName" class="auth-input" placeholder="X-Api-Key" />
|
|
135
|
+
<input type="text" id="authApiKeyValue" class="auth-input" placeholder="secret" />
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
|
|
139
|
+
<div id="panel-headers" class="config-panel params-area">
|
|
140
|
+
<table class="params-table">
|
|
141
|
+
<thead>
|
|
142
|
+
<tr>
|
|
143
|
+
<th class="th-check"></th>
|
|
144
|
+
<th>Key</th>
|
|
145
|
+
<th>Value</th>
|
|
146
|
+
<th>Description</th>
|
|
147
|
+
<th class="th-del"></th>
|
|
148
|
+
</tr>
|
|
149
|
+
</thead>
|
|
150
|
+
<tbody id="headers-tbody"></tbody>
|
|
151
|
+
</table>
|
|
152
|
+
<button type="button" class="add-row-btn" id="add-header-row">+ Add header</button>
|
|
153
|
+
</div>
|
|
154
|
+
|
|
155
|
+
<div id="panel-body" class="config-panel config-panel--body" hidden>
|
|
156
|
+
<div class="body-type-row">
|
|
157
|
+
<label class="body-type-label"><input type="radio" name="body-type" value="none" /> none</label>
|
|
158
|
+
<label class="body-type-label"><input type="radio" name="body-type" value="raw" checked /> raw</label>
|
|
159
|
+
<select id="bodyRawType" class="body-raw-select" title="Hint only (sent as-is)">
|
|
160
|
+
<option>JSON</option>
|
|
161
|
+
<option>Text</option>
|
|
162
|
+
<option>XML</option>
|
|
163
|
+
</select>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="body-editor-wrap">
|
|
166
|
+
<textarea id="reqBody" class="body-textarea" spellcheck="false" placeholder="Request body (raw)"></textarea>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
<div id="panel-scripts" class="config-panel params-area" hidden>
|
|
171
|
+
<div class="scripts-subtabs">
|
|
172
|
+
<button type="button" class="script-subtab active" data-script="pre">Pre-request</button>
|
|
173
|
+
<button type="button" class="script-subtab" data-script="post">Post-response</button>
|
|
174
|
+
</div>
|
|
175
|
+
<textarea id="scriptsPre" class="scripts-textarea" spellcheck="false" placeholder="// Pre-request (not executed — inspector UI only)"></textarea>
|
|
176
|
+
<textarea id="scriptsPost" class="scripts-textarea" spellcheck="false" placeholder="// Post-response (not executed)" hidden></textarea>
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<div id="panel-settings" class="config-panel params-area" hidden>
|
|
180
|
+
<div class="settings-list">
|
|
181
|
+
<label class="settings-row"><span>Follow redirects</span><input type="checkbox" id="setFollowRedirects" checked /></label>
|
|
182
|
+
<label class="settings-row"><span>SSL certificate verification</span><input type="checkbox" id="setSSLVerify" checked /></label>
|
|
183
|
+
<label class="settings-row settings-row-num">
|
|
184
|
+
<span>Request timeout (ms)</span>
|
|
185
|
+
<input type="number" id="setTimeoutMs" class="settings-num" value="120000" min="1000" step="1000" />
|
|
186
|
+
</label>
|
|
187
|
+
<p class="settings-note">Replay uses the local inspector proxy; these options are for display / future use.</p>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
|
|
193
|
+
<div class="resizer-v" id="resizerV" title="Drag to resize"></div>
|
|
194
|
+
|
|
195
|
+
<div class="pane-resp" id="paneResp">
|
|
196
|
+
<div class="response-area">
|
|
197
|
+
<div class="response-header">
|
|
198
|
+
<span class="response-label">Response</span>
|
|
199
|
+
<div id="responseStatus" class="response-status" hidden>
|
|
200
|
+
<span class="status-badge" id="statusBadge">—</span>
|
|
201
|
+
<span class="status-info"><span id="respTime">—</span></span>
|
|
202
|
+
<span class="status-info"><span id="respSize">—</span></span>
|
|
203
|
+
</div>
|
|
204
|
+
<div class="resp-tabs" role="tablist">
|
|
205
|
+
<button type="button" class="resp-tab active" data-resp="body" role="tab">Body</button>
|
|
206
|
+
<button type="button" class="resp-tab" data-resp="headers" role="tab">Headers</button>
|
|
207
|
+
<button type="button" class="resp-tab" data-resp="cookies" role="tab">Cookies</button>
|
|
208
|
+
<button type="button" class="resp-tab" data-resp="console" role="tab">Console</button>
|
|
209
|
+
</div>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="response-meta-line" id="respMeta"></div>
|
|
212
|
+
<div class="response-body">
|
|
213
|
+
<div id="emptyResponse" class="empty-response">
|
|
214
|
+
<svg class="empty-ico" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" aria-hidden="true">
|
|
215
|
+
<path d="M20 12V22H4V12"/><path d="M22 7H2v5h20V7z"/><path d="M12 22V7"/><path d="M12 7H7.5a2.5 2.5 0 0 1 0-5C11 2 12 7 12 7z"/><path d="M12 7h4.5a2.5 2.5 0 0 0 0-5C13 2 12 7 12 7z"/>
|
|
216
|
+
</svg>
|
|
217
|
+
<span>Select a request or hit Replay to see a response</span>
|
|
218
|
+
</div>
|
|
219
|
+
|
|
220
|
+
<div id="resp-panel-body" class="resp-panel">
|
|
221
|
+
<div class="resp-toolbar">
|
|
222
|
+
<div class="resp-format-btns">
|
|
223
|
+
<button type="button" class="fmt-btn active" data-fmt="pretty" id="fmtPretty">Pretty</button>
|
|
224
|
+
<button type="button" class="fmt-btn" data-fmt="raw" id="fmtRaw">Raw</button>
|
|
225
|
+
</div>
|
|
226
|
+
<select id="respBodyKind" class="resp-kind-select">
|
|
227
|
+
<option>JSON</option>
|
|
228
|
+
<option>Text</option>
|
|
229
|
+
<option>HTML</option>
|
|
230
|
+
</select>
|
|
231
|
+
<button type="button" class="btn-copy" id="btnCopyResp" title="Copy body">Copy</button>
|
|
232
|
+
</div>
|
|
233
|
+
<textarea id="respBody" readonly class="resp-body-text" spellcheck="false"></textarea>
|
|
234
|
+
</div>
|
|
235
|
+
|
|
236
|
+
<div id="resp-panel-headers" class="resp-panel" hidden>
|
|
237
|
+
<table class="kv-table">
|
|
238
|
+
<thead>
|
|
239
|
+
<tr>
|
|
240
|
+
<th class="kv-key">Key</th>
|
|
241
|
+
<th class="kv-val">Value</th>
|
|
242
|
+
</tr>
|
|
243
|
+
</thead>
|
|
244
|
+
<tbody id="respHeadersTable"></tbody>
|
|
245
|
+
</table>
|
|
246
|
+
</div>
|
|
247
|
+
|
|
248
|
+
<div id="resp-panel-cookies" class="resp-panel" hidden>
|
|
249
|
+
<div id="respCookies" class="cookies-placeholder">No cookies parsed (Set-Cookie appears in Headers).</div>
|
|
250
|
+
</div>
|
|
251
|
+
|
|
252
|
+
<div id="resp-panel-console" class="resp-panel resp-console" hidden>
|
|
253
|
+
<pre id="respConsole" class="resp-console-pre"></pre>
|
|
254
|
+
</div>
|
|
255
|
+
</div>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</section>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</body>
|
|
263
|
+
</html>
|