@rvanbaalen/roxyproxy 0.1.2 → 0.1.4
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/README.md +176 -8
- package/dist/cli/commands/requests.js +150 -4
- package/dist/cli/commands/requests.js.map +1 -1
- package/dist/cli/format.d.ts +10 -0
- package/dist/cli/format.js +55 -12
- package/dist/cli/format.js.map +1 -1
- package/dist/cli/interactive.js +16 -8
- package/dist/cli/interactive.js.map +1 -1
- package/dist/cli/tail-ui.d.ts +3 -0
- package/dist/cli/tail-ui.js +322 -0
- package/dist/cli/tail-ui.js.map +1 -0
- package/dist/server/api.d.ts +2 -1
- package/dist/server/api.js +17 -1
- package/dist/server/api.js.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,9 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="RoxyProxy" width="600" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<p align="center">
|
|
6
|
+
HTTP/HTTPS intercepting proxy with a CLI and web UI.<br>
|
|
7
|
+
Captures traffic, stores it in SQLite, and makes it queryable -- by humans and LLMs alike.<br>
|
|
8
|
+
<strong>Developed and tested on macOS.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/@rvanbaalen/roxyproxy"><img src="https://img.shields.io/npm/v/@rvanbaalen/roxyproxy" alt="npm version" /></a>
|
|
13
|
+
</p>
|
|
4
14
|
|
|
5
15
|
## Table of Contents
|
|
6
16
|
|
|
17
|
+
- [Platform](#platform)
|
|
7
18
|
- [Installation](#installation)
|
|
8
19
|
- [Claude Code Plugin](#claude-code-plugin)
|
|
9
20
|
- [Quick Start](#quick-start)
|
|
@@ -21,6 +32,7 @@ HTTP/HTTPS intercepting proxy with a CLI and web UI. Captures traffic, stores it
|
|
|
21
32
|
- [proxy-off](#proxy-off-macos)
|
|
22
33
|
- [Web UI](#web-ui)
|
|
23
34
|
- [HTTPS Interception](#https-interception)
|
|
35
|
+
- [iOS Device Inspection](#ios-device-inspection)
|
|
24
36
|
- [System Proxy](#system-proxy-macos)
|
|
25
37
|
- [Configuration](#configuration)
|
|
26
38
|
- [REST API](#rest-api)
|
|
@@ -29,6 +41,14 @@ HTTP/HTTPS intercepting proxy with a CLI and web UI. Captures traffic, stores it
|
|
|
29
41
|
|
|
30
42
|
---
|
|
31
43
|
|
|
44
|
+
## Platform
|
|
45
|
+
|
|
46
|
+
RoxyProxy is developed and tested on **macOS**. Core proxy and query functionality works on Linux, but the following features are macOS-only:
|
|
47
|
+
|
|
48
|
+
- **System proxy** (`proxy-on` / `proxy-off`) -- uses `networksetup`
|
|
49
|
+
- **Auto-enable system proxy** with `--tail` -- routes all macOS traffic through the proxy automatically
|
|
50
|
+
- **CA trust** (`trust-ca`) -- uses macOS Keychain; Linux support exists but is less tested
|
|
51
|
+
|
|
32
52
|
## Installation
|
|
33
53
|
|
|
34
54
|
Run directly without installing:
|
|
@@ -84,6 +104,20 @@ Just ask Claude anything about intercepting or inspecting HTTP traffic and it wi
|
|
|
84
104
|
|
|
85
105
|
## Quick Start
|
|
86
106
|
|
|
107
|
+
The fastest way to start capturing traffic:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
# One command: starts proxy, enables system proxy, opens interactive TUI
|
|
111
|
+
roxyproxy requests --tail
|
|
112
|
+
|
|
113
|
+
# Filter for a specific host
|
|
114
|
+
roxyproxy requests --host api.example.com --tail
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
This auto-starts the proxy, routes macOS system traffic through it, and opens a live terminal UI. Press Ctrl+C to quit -- the system proxy is automatically disabled.
|
|
118
|
+
|
|
119
|
+
### Manual setup
|
|
120
|
+
|
|
87
121
|
```bash
|
|
88
122
|
# Start the proxy (default: proxy on :8080, web UI on :8081)
|
|
89
123
|
roxyproxy start
|
|
@@ -92,7 +126,7 @@ roxyproxy start
|
|
|
92
126
|
curl -x http://127.0.0.1:8080 http://httpbin.org/get
|
|
93
127
|
|
|
94
128
|
# View captured traffic
|
|
95
|
-
roxyproxy requests
|
|
129
|
+
roxyproxy requests
|
|
96
130
|
|
|
97
131
|
# Open the web UI
|
|
98
132
|
open http://127.0.0.1:8081
|
|
@@ -117,6 +151,8 @@ Running `roxyproxy` with no arguments launches an interactive terminal menu:
|
|
|
117
151
|
roxyproxy
|
|
118
152
|
```
|
|
119
153
|
|
|
154
|
+

|
|
155
|
+
|
|
120
156
|
The interactive menu provides access to all features:
|
|
121
157
|
|
|
122
158
|
- **Start/Stop proxy** -- toggle the proxy server on and off
|
|
@@ -224,10 +260,12 @@ roxyproxy requests [options]
|
|
|
224
260
|
| `--since <time>` | | After this time (Unix ms or ISO date) |
|
|
225
261
|
| `--until <time>` | | Before this time (Unix ms or ISO date) |
|
|
226
262
|
| `--limit <n>` | `100` | Maximum number of results |
|
|
227
|
-
| `--format <format>` | `
|
|
263
|
+
| `--format <format>` | `table` | Output format: `table` (default) or `json` |
|
|
264
|
+
| `--tail` | | Stream new requests in real-time (interactive TUI) |
|
|
265
|
+
| `--ui-port <number>` | `8081` | UI/API port (used with `--tail`) |
|
|
228
266
|
| `--db-path <path>` | `~/.roxyproxy/data.db` | Database location |
|
|
229
267
|
|
|
230
|
-
The default
|
|
268
|
+
The default output is a human-readable table. Use `--format json` for piping to `jq` or feeding to LLMs:
|
|
231
269
|
|
|
232
270
|
```bash
|
|
233
271
|
# All 500 errors
|
|
@@ -239,16 +277,51 @@ roxyproxy requests --host api.example.com --method POST
|
|
|
239
277
|
# Search URLs
|
|
240
278
|
roxyproxy requests --search "/api/v2"
|
|
241
279
|
|
|
242
|
-
#
|
|
280
|
+
# Limit results
|
|
243
281
|
roxyproxy requests --format table --limit 20
|
|
244
282
|
|
|
245
283
|
# Time-bounded query
|
|
246
284
|
roxyproxy requests --since "2024-01-15T00:00:00Z" --until "2024-01-16T00:00:00Z"
|
|
247
285
|
|
|
248
|
-
#
|
|
249
|
-
roxyproxy requests --host stripe.com | jq '.data[].url'
|
|
286
|
+
# JSON for piping to jq
|
|
287
|
+
roxyproxy requests --format json --host stripe.com | jq '.data[].url'
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### Real-time tailing
|
|
291
|
+
|
|
292
|
+
The `--tail` flag launches an interactive terminal UI that streams new requests as they arrive:
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
# Tail all traffic (auto-starts proxy + system proxy if needed)
|
|
296
|
+
roxyproxy requests --tail
|
|
297
|
+
|
|
298
|
+
# Tail with filters
|
|
299
|
+
roxyproxy requests --host todoist.com --tail
|
|
300
|
+
roxyproxy requests --status 500 --tail
|
|
301
|
+
roxyproxy requests --method POST --host api.example.com --tail
|
|
250
302
|
```
|
|
251
303
|
|
|
304
|
+
**What `--tail` does automatically:**
|
|
305
|
+
|
|
306
|
+
1. **Starts the proxy** if it isn't already running
|
|
307
|
+
2. **Enables the macOS system proxy** so all traffic routes through RoxyProxy
|
|
308
|
+
3. Opens an interactive TUI with arrow-key navigation
|
|
309
|
+
4. On quit (Ctrl+C), **disables the system proxy** and stops the proxy it started
|
|
310
|
+
|
|
311
|
+
**TUI keyboard shortcuts:**
|
|
312
|
+
|
|
313
|
+
| Key | Action |
|
|
314
|
+
|---|---|
|
|
315
|
+
| `↑` / `↓` | Navigate requests |
|
|
316
|
+
| `Enter` | View full request detail (headers, body) |
|
|
317
|
+
| `Esc` | Back to list from detail view |
|
|
318
|
+
| `g` / `G` | Jump to top (newest) / bottom (oldest) |
|
|
319
|
+
| `Ctrl+C` | Quit (cleans up proxy and system proxy) |
|
|
320
|
+
|
|
321
|
+
New requests auto-scroll to the top. Scrolling down disables auto-scroll; pressing `g` re-enables it.
|
|
322
|
+
|
|
323
|
+
To get raw JSON streaming instead of the TUI, use `--format json --tail`.
|
|
324
|
+
|
|
252
325
|
### request
|
|
253
326
|
|
|
254
327
|
Show full details of a single captured request, including headers and bodies.
|
|
@@ -444,6 +517,91 @@ roxyproxy proxy-on
|
|
|
444
517
|
|
|
445
518
|
---
|
|
446
519
|
|
|
520
|
+
## iOS Device Inspection
|
|
521
|
+
|
|
522
|
+
RoxyProxy can inspect HTTP/HTTPS traffic from an iOS device. Your computer and iOS device must be on the same Wi-Fi network.
|
|
523
|
+
|
|
524
|
+
### Setup
|
|
525
|
+
|
|
526
|
+
**Step 1: Start RoxyProxy on your computer**
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
roxyproxy start
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
**Step 2: Find your computer's local IP address**
|
|
533
|
+
|
|
534
|
+
```bash
|
|
535
|
+
# macOS
|
|
536
|
+
ipconfig getifaddr en0
|
|
537
|
+
|
|
538
|
+
# Linux
|
|
539
|
+
hostname -I | awk '{print $1}'
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
Note the IP (e.g., `192.168.1.42`).
|
|
543
|
+
|
|
544
|
+
**Step 3: Configure the iOS device to use the proxy**
|
|
545
|
+
|
|
546
|
+
1. Open **Settings > Wi-Fi**
|
|
547
|
+
2. Tap the **(i)** icon next to your connected network
|
|
548
|
+
3. Scroll down and tap **Configure Proxy**
|
|
549
|
+
4. Select **Manual**
|
|
550
|
+
5. Set **Server** to your computer's IP (e.g., `192.168.1.42`)
|
|
551
|
+
6. Set **Port** to `8080`
|
|
552
|
+
7. Tap **Save**
|
|
553
|
+
|
|
554
|
+
HTTP traffic is now being captured. For HTTPS inspection, continue below.
|
|
555
|
+
|
|
556
|
+
**Step 4: Install the CA certificate on iOS**
|
|
557
|
+
|
|
558
|
+
Open Safari on your iOS device and navigate to:
|
|
559
|
+
|
|
560
|
+
```
|
|
561
|
+
http://<your-computer-ip>:8081/api/ca.crt
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
For example: `http://192.168.1.42:8081/api/ca.crt`
|
|
565
|
+
|
|
566
|
+
Safari will prompt you to download a configuration profile. Tap **Allow**.
|
|
567
|
+
|
|
568
|
+
**Step 5: Install the profile**
|
|
569
|
+
|
|
570
|
+
1. Open **Settings > General > VPN & Device Management** (or **Profiles & Device Management** on older iOS)
|
|
571
|
+
2. Tap the **RoxyProxy CA** profile
|
|
572
|
+
3. Tap **Install** and enter your passcode
|
|
573
|
+
|
|
574
|
+
**Step 6: Enable full trust for the certificate**
|
|
575
|
+
|
|
576
|
+
1. Open **Settings > General > About > Certificate Trust Settings**
|
|
577
|
+
2. Toggle **Enable Full Trust** for **RoxyProxy CA**
|
|
578
|
+
3. Tap **Continue** on the warning dialog
|
|
579
|
+
|
|
580
|
+
HTTPS traffic from the iOS device is now fully inspectable through RoxyProxy.
|
|
581
|
+
|
|
582
|
+
### Viewing traffic
|
|
583
|
+
|
|
584
|
+
Open the web UI from any browser:
|
|
585
|
+
|
|
586
|
+
```
|
|
587
|
+
http://<your-computer-ip>:8081
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
Or use the CLI:
|
|
591
|
+
|
|
592
|
+
```bash
|
|
593
|
+
roxyproxy requests --tail
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
### Cleanup
|
|
597
|
+
|
|
598
|
+
When you're done inspecting, remove the proxy from iOS:
|
|
599
|
+
|
|
600
|
+
1. **Settings > Wi-Fi > (i) > Configure Proxy > Off**
|
|
601
|
+
2. Optionally remove the CA profile: **Settings > General > VPN & Device Management > RoxyProxy CA > Remove Profile**
|
|
602
|
+
|
|
603
|
+
---
|
|
604
|
+
|
|
447
605
|
## System Proxy (macOS)
|
|
448
606
|
|
|
449
607
|
On macOS, RoxyProxy can configure itself as the system-wide HTTP/HTTPS proxy. This routes all traffic from most applications through the proxy without needing per-app configuration.
|
|
@@ -578,6 +736,14 @@ Response:
|
|
|
578
736
|
}
|
|
579
737
|
```
|
|
580
738
|
|
|
739
|
+
#### `GET /api/ca.crt`
|
|
740
|
+
|
|
741
|
+
Download the RoxyProxy CA certificate. Useful for installing on mobile devices -- open this URL in the device's browser to trigger a certificate install prompt.
|
|
742
|
+
|
|
743
|
+
```bash
|
|
744
|
+
curl -O http://127.0.0.1:8081/api/ca.crt
|
|
745
|
+
```
|
|
746
|
+
|
|
581
747
|
#### `POST /api/proxy/start`
|
|
582
748
|
|
|
583
749
|
Start the proxy server.
|
|
@@ -699,6 +865,8 @@ src/
|
|
|
699
865
|
├── cli/ # CLI entry point, commands, interactive mode
|
|
700
866
|
│ ├── index.ts # Command registration (Commander.js)
|
|
701
867
|
│ ├── interactive.tsx # Interactive terminal menu (Ink/React)
|
|
868
|
+
│ ├── tail-ui.tsx # Real-time tail TUI (Ink/React)
|
|
869
|
+
│ ├── format.ts # Table/JSON output formatting
|
|
702
870
|
│ ├── commands/ # Individual CLI commands
|
|
703
871
|
│ └── system-proxy.ts # macOS system proxy & CA management
|
|
704
872
|
├── server/ # Proxy server, API, SSL, events
|
|
@@ -1,6 +1,50 @@
|
|
|
1
|
+
import http from 'node:http';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import os from 'node:os';
|
|
1
5
|
import { Database } from '../../storage/db.js';
|
|
2
6
|
import { loadConfig } from '../../server/config.js';
|
|
3
|
-
import {
|
|
7
|
+
import { RoxyProxyServer } from '../../server/index.js';
|
|
8
|
+
import { formatRequests, formatTailLine } from '../format.js';
|
|
9
|
+
import { enableSystemProxy, disableSystemProxy, checkSystemProxyStatus } from '../system-proxy.js';
|
|
10
|
+
/** Try to reach the API; resolves true if proxy is reachable. */
|
|
11
|
+
function isProxyRunning(port) {
|
|
12
|
+
return new Promise((resolve) => {
|
|
13
|
+
const req = http.request({ host: '127.0.0.1', port, path: '/api/status', method: 'GET', timeout: 1000 }, (res) => { res.resume(); resolve(res.statusCode === 200); });
|
|
14
|
+
req.on('error', () => resolve(false));
|
|
15
|
+
req.on('timeout', () => { req.destroy(); resolve(false); });
|
|
16
|
+
req.end();
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/** Start a proxy server, enable system proxy, return instance and ports. */
|
|
20
|
+
async function autoStartProxy(requestedUiPort) {
|
|
21
|
+
const config = loadConfig({ uiPort: requestedUiPort });
|
|
22
|
+
const pidPath = path.join(os.homedir(), '.roxyproxy', 'pid');
|
|
23
|
+
fs.mkdirSync(path.dirname(pidPath), { recursive: true });
|
|
24
|
+
fs.writeFileSync(pidPath, process.pid.toString());
|
|
25
|
+
const server = new RoxyProxyServer(config);
|
|
26
|
+
const ports = await server.start();
|
|
27
|
+
// Enable system proxy so traffic flows through automatically
|
|
28
|
+
let systemProxyEnabled = false;
|
|
29
|
+
const alreadyEnabled = await checkSystemProxyStatus();
|
|
30
|
+
if (!alreadyEnabled) {
|
|
31
|
+
const proxyResult = await enableSystemProxy(String(ports.proxyPort));
|
|
32
|
+
systemProxyEnabled = proxyResult.ok;
|
|
33
|
+
}
|
|
34
|
+
const shutdown = async () => {
|
|
35
|
+
if (systemProxyEnabled)
|
|
36
|
+
await disableSystemProxy();
|
|
37
|
+
await server.stop();
|
|
38
|
+
try {
|
|
39
|
+
fs.unlinkSync(pidPath);
|
|
40
|
+
}
|
|
41
|
+
catch { }
|
|
42
|
+
process.exit(0);
|
|
43
|
+
};
|
|
44
|
+
process.on('SIGINT', shutdown);
|
|
45
|
+
process.on('SIGTERM', shutdown);
|
|
46
|
+
return { server, uiPort: ports.uiPort, systemProxyEnabled };
|
|
47
|
+
}
|
|
4
48
|
export function registerRequests(program) {
|
|
5
49
|
program
|
|
6
50
|
.command('requests')
|
|
@@ -12,9 +56,51 @@ export function registerRequests(program) {
|
|
|
12
56
|
.option('--since <time>', 'Requests after this time')
|
|
13
57
|
.option('--until <time>', 'Requests before this time')
|
|
14
58
|
.option('--limit <n>', 'Max results', '100')
|
|
15
|
-
.option('--format <format>', 'Output format (json|table)'
|
|
59
|
+
.option('--format <format>', 'Output format (json|table)')
|
|
60
|
+
.option('--tail', 'Stream new requests in real-time')
|
|
61
|
+
.option('--ui-port <number>', 'UI/API port for --tail', '8081')
|
|
16
62
|
.option('--db-path <path>', 'Database path')
|
|
17
|
-
.action((opts) => {
|
|
63
|
+
.action(async (opts) => {
|
|
64
|
+
if (opts.tail) {
|
|
65
|
+
const filter = {};
|
|
66
|
+
if (opts.host)
|
|
67
|
+
filter.host = opts.host;
|
|
68
|
+
if (opts.status)
|
|
69
|
+
filter.status = parseInt(opts.status, 10);
|
|
70
|
+
if (opts.method)
|
|
71
|
+
filter.method = opts.method;
|
|
72
|
+
if (opts.search)
|
|
73
|
+
filter.search = opts.search;
|
|
74
|
+
// Default to table (interactive TUI) when tailing
|
|
75
|
+
const format = opts.format ?? 'table';
|
|
76
|
+
let uiPort = parseInt(opts.uiPort, 10);
|
|
77
|
+
let server = null;
|
|
78
|
+
// Auto-start proxy if not running
|
|
79
|
+
let didEnableSystemProxy = false;
|
|
80
|
+
const running = await isProxyRunning(uiPort);
|
|
81
|
+
if (!running) {
|
|
82
|
+
try {
|
|
83
|
+
const result = await autoStartProxy(uiPort);
|
|
84
|
+
server = result.server;
|
|
85
|
+
uiPort = result.uiPort;
|
|
86
|
+
didEnableSystemProxy = result.systemProxyEnabled;
|
|
87
|
+
console.error(`Proxy started (UI on :${uiPort})${didEnableSystemProxy ? ' — system proxy enabled' : ''}`);
|
|
88
|
+
}
|
|
89
|
+
catch (e) {
|
|
90
|
+
console.error(`Failed to start proxy: ${e.message}`);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
if (format === 'table') {
|
|
95
|
+
// Launch interactive Ink TUI
|
|
96
|
+
const { launchTailUi } = await import('../tail-ui.js');
|
|
97
|
+
launchTailUi(uiPort, filter, server, didEnableSystemProxy);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
// JSON streaming mode (plain stdout)
|
|
101
|
+
tailRequests(uiPort, filter, format);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
18
104
|
const config = loadConfig(opts.dbPath ? { dbPath: opts.dbPath } : {});
|
|
19
105
|
const db = new Database(config.dbPath);
|
|
20
106
|
const filter = {
|
|
@@ -33,10 +119,70 @@ export function registerRequests(program) {
|
|
|
33
119
|
if (opts.until)
|
|
34
120
|
filter.until = parseTime(opts.until);
|
|
35
121
|
const result = db.query(filter);
|
|
36
|
-
console.log(formatRequests(result, opts.format));
|
|
122
|
+
console.log(formatRequests(result, opts.format ?? 'table'));
|
|
37
123
|
db.close();
|
|
38
124
|
});
|
|
39
125
|
}
|
|
126
|
+
function matchesFilter(record, filter) {
|
|
127
|
+
if (filter.host && !record.host?.toLowerCase().includes(filter.host.toLowerCase()))
|
|
128
|
+
return false;
|
|
129
|
+
if (filter.status && record.status !== filter.status)
|
|
130
|
+
return false;
|
|
131
|
+
if (filter.method && record.method?.toUpperCase() !== filter.method.toUpperCase())
|
|
132
|
+
return false;
|
|
133
|
+
if (filter.search && !record.url?.toLowerCase().includes(filter.search.toLowerCase()))
|
|
134
|
+
return false;
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
function tailRequests(port, filter, format) {
|
|
138
|
+
const req = http.request({ host: '127.0.0.1', port, path: '/api/events', method: 'GET' }, (res) => {
|
|
139
|
+
if (res.statusCode !== 200) {
|
|
140
|
+
console.error(`Failed to connect to event stream (status ${res.statusCode}). Is the proxy running?`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
if (format === 'table') {
|
|
144
|
+
console.log(`\n Tailing requests${filter.host ? ` (host: ${filter.host})` : ''}... (Ctrl+C to stop)\n`);
|
|
145
|
+
}
|
|
146
|
+
let buffer = '';
|
|
147
|
+
res.on('data', (chunk) => {
|
|
148
|
+
buffer += chunk.toString();
|
|
149
|
+
// Parse SSE events from the buffer
|
|
150
|
+
const parts = buffer.split('\n\n');
|
|
151
|
+
buffer = parts.pop() || '';
|
|
152
|
+
for (const part of parts) {
|
|
153
|
+
const lines = part.split('\n');
|
|
154
|
+
let eventType = '';
|
|
155
|
+
let data = '';
|
|
156
|
+
for (const line of lines) {
|
|
157
|
+
if (line.startsWith('event: '))
|
|
158
|
+
eventType = line.slice(7);
|
|
159
|
+
else if (line.startsWith('data: '))
|
|
160
|
+
data = line.slice(6);
|
|
161
|
+
}
|
|
162
|
+
if (eventType !== 'request' || !data)
|
|
163
|
+
continue;
|
|
164
|
+
try {
|
|
165
|
+
const record = JSON.parse(data);
|
|
166
|
+
if (matchesFilter(record, filter)) {
|
|
167
|
+
console.log(formatTailLine(record, format));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// Ignore malformed events
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
res.on('end', () => {
|
|
176
|
+
console.error('Event stream closed.');
|
|
177
|
+
process.exit(0);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
req.on('error', () => {
|
|
181
|
+
console.error('Could not connect to proxy. Is it running?');
|
|
182
|
+
process.exit(1);
|
|
183
|
+
});
|
|
184
|
+
req.end();
|
|
185
|
+
}
|
|
40
186
|
function parseTime(value) {
|
|
41
187
|
const num = Number(value);
|
|
42
188
|
if (!isNaN(num))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/cli/commands/requests.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/cli/commands/requests.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/format.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
1
|
import type { RequestRecord, PaginatedResponse } from '../shared/types.js';
|
|
2
|
+
export declare const COL: {
|
|
3
|
+
readonly time: 12;
|
|
4
|
+
readonly method: 8;
|
|
5
|
+
readonly status: 8;
|
|
6
|
+
readonly host: 30;
|
|
7
|
+
readonly path: 30;
|
|
8
|
+
readonly duration: 10;
|
|
9
|
+
readonly size: 10;
|
|
10
|
+
};
|
|
2
11
|
export declare function formatRequests(result: PaginatedResponse<RequestRecord>, format: string): string;
|
|
3
12
|
export declare function formatRequest(record: RequestRecord, format: string): string;
|
|
13
|
+
export declare function formatTailLine(r: RequestRecord, format: string): string;
|
package/dist/cli/format.js
CHANGED
|
@@ -1,4 +1,24 @@
|
|
|
1
1
|
import pc from 'picocolors';
|
|
2
|
+
// ── Shared column widths ──
|
|
3
|
+
export const COL = {
|
|
4
|
+
time: 12,
|
|
5
|
+
method: 8,
|
|
6
|
+
status: 8,
|
|
7
|
+
host: 30,
|
|
8
|
+
path: 30,
|
|
9
|
+
duration: 10,
|
|
10
|
+
size: 10,
|
|
11
|
+
};
|
|
12
|
+
// ── ANSI-safe padding ──
|
|
13
|
+
const ANSI_RE = /\x1b\[[0-9;]*m/g;
|
|
14
|
+
function visibleLength(str) {
|
|
15
|
+
return str.replace(ANSI_RE, '').length;
|
|
16
|
+
}
|
|
17
|
+
function padAnsi(str, width) {
|
|
18
|
+
const pad = width - visibleLength(str);
|
|
19
|
+
return pad > 0 ? str + ' '.repeat(pad) : str;
|
|
20
|
+
}
|
|
21
|
+
// ── Colors ──
|
|
2
22
|
const methodColor = (method) => {
|
|
3
23
|
switch (method) {
|
|
4
24
|
case 'GET': return pc.blue(method);
|
|
@@ -21,6 +41,7 @@ const statusColor = (status) => {
|
|
|
21
41
|
return pc.magenta(s);
|
|
22
42
|
return pc.red(s);
|
|
23
43
|
};
|
|
44
|
+
// ── Table formatters ──
|
|
24
45
|
export function formatRequests(result, format) {
|
|
25
46
|
if (format === 'json') {
|
|
26
47
|
return JSON.stringify(result, null, 2);
|
|
@@ -28,21 +49,22 @@ export function formatRequests(result, format) {
|
|
|
28
49
|
if (result.data.length === 0) {
|
|
29
50
|
return `\n ${pc.dim('No requests found.')}\n`;
|
|
30
51
|
}
|
|
52
|
+
const totalWidth = COL.method + COL.status + COL.host + COL.path + COL.duration + COL.size;
|
|
31
53
|
const header = pc.dim(' ' +
|
|
32
|
-
'METHOD'.padEnd(
|
|
33
|
-
'STATUS'.padEnd(
|
|
34
|
-
'HOST'.padEnd(
|
|
35
|
-
'PATH'.padEnd(
|
|
36
|
-
'TIME'.padEnd(
|
|
37
|
-
'SIZE'.padEnd(
|
|
38
|
-
const divider = pc.dim(' ' + '─'.repeat(
|
|
54
|
+
'METHOD'.padEnd(COL.method) +
|
|
55
|
+
'STATUS'.padEnd(COL.status) +
|
|
56
|
+
'HOST'.padEnd(COL.host) +
|
|
57
|
+
'PATH'.padEnd(COL.path) +
|
|
58
|
+
'TIME'.padEnd(COL.duration) +
|
|
59
|
+
'SIZE'.padEnd(COL.size));
|
|
60
|
+
const divider = pc.dim(' ' + '─'.repeat(totalWidth));
|
|
39
61
|
const rows = result.data.map((r) => {
|
|
40
62
|
return ' ' +
|
|
41
|
-
methodColor(r.method || '').
|
|
42
|
-
statusColor(r.status).
|
|
43
|
-
(r.host || '').slice(0,
|
|
44
|
-
pc.dim((r.path || '').slice(0,
|
|
45
|
-
pc.dim(r.duration ? `${r.duration}ms` : '-').
|
|
63
|
+
padAnsi(methodColor(r.method || ''), COL.method) +
|
|
64
|
+
padAnsi(statusColor(r.status), COL.status) +
|
|
65
|
+
(r.host || '').slice(0, COL.host - 2).padEnd(COL.host) +
|
|
66
|
+
padAnsi(pc.dim((r.path || '').slice(0, COL.path - 2)), COL.path) +
|
|
67
|
+
padAnsi(pc.dim(r.duration ? `${r.duration}ms` : '-'), COL.duration) +
|
|
46
68
|
pc.dim(formatBytes(r.response_size || 0));
|
|
47
69
|
});
|
|
48
70
|
const footer = `\n ${pc.dim(`${result.total} total (showing ${result.data.length}, offset ${result.offset})`)}`;
|
|
@@ -102,6 +124,27 @@ function formatBody(body, contentType) {
|
|
|
102
124
|
}
|
|
103
125
|
return ` ${str}`;
|
|
104
126
|
}
|
|
127
|
+
export function formatTailLine(r, format) {
|
|
128
|
+
if (format === 'json') {
|
|
129
|
+
return JSON.stringify({
|
|
130
|
+
id: r.id,
|
|
131
|
+
timestamp: r.timestamp,
|
|
132
|
+
method: r.method,
|
|
133
|
+
status: r.status,
|
|
134
|
+
host: r.host,
|
|
135
|
+
path: r.path,
|
|
136
|
+
url: r.url,
|
|
137
|
+
duration: r.duration,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
return ' ' +
|
|
141
|
+
padAnsi(pc.dim(new Date(r.timestamp).toLocaleTimeString()), COL.time) +
|
|
142
|
+
padAnsi(methodColor(r.method || ''), COL.method) +
|
|
143
|
+
padAnsi(statusColor(r.status), COL.status) +
|
|
144
|
+
(r.host || '').slice(0, COL.host - 2).padEnd(COL.host) +
|
|
145
|
+
padAnsi(pc.dim((r.path || '').slice(0, COL.path - 2)), COL.path) +
|
|
146
|
+
pc.dim(r.duration ? `${r.duration}ms` : '-');
|
|
147
|
+
}
|
|
105
148
|
function formatBytes(bytes) {
|
|
106
149
|
if (bytes < 1024)
|
|
107
150
|
return `${bytes}B`;
|
package/dist/cli/format.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAG5B,MAAM,WAAW,GAAG,CAAC,MAAc,EAAU,EAAE;IAC7C,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACnC,KAAK,MAAM,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACrC,KAAK,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACrC,KAAK,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACxC,KAAK,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,CAAC,MAAqB,EAAU,EAAE;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC;IAChC,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrC,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IACtC,IAAI,MAAM,GAAG,GAAG;QAAE,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,MAAwC,EAAE,MAAc;IACrF,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,OAAO,EAAE,CAAC,GAAG,CAAC,oBAAoB,CAAC,IAAI,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,EAAE,CAAC,GAAG,CACnB,IAAI;QACJ,QAAQ,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/cli/format.ts"],"names":[],"mappings":"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"}
|