devportal-tunnel 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -0
- package/dist/commands/list.d.ts +2 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +40 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +58 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/replay.d.ts +7 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +52 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/start.d.ts +10 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +147 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/stop.d.ts +6 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +55 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/device.d.ts +3 -0
- package/dist/utils/device.d.ts.map +1 -0
- package/dist/utils/device.js +75 -0
- package/dist/utils/device.js.map +1 -0
- package/dist/utils/tunnels.d.ts +17 -0
- package/dist/utils/tunnels.d.ts.map +1 -0
- package/dist/utils/tunnels.js +86 -0
- package/dist/utils/tunnels.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
# DevPortal Tunnel CLI
|
|
2
|
+
|
|
3
|
+
Expose your localhost to the internet with a single command.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g devportal
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Start a tunnel
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Expose port 3000
|
|
17
|
+
devportal 3000
|
|
18
|
+
|
|
19
|
+
# With custom subdomain
|
|
20
|
+
devportal 3000 --subdomain my-api
|
|
21
|
+
|
|
22
|
+
# Password protected
|
|
23
|
+
devportal 3000 --password secret123
|
|
24
|
+
|
|
25
|
+
# Show QR code for mobile
|
|
26
|
+
devportal 3000 --qr
|
|
27
|
+
|
|
28
|
+
# Temporary demo link (expires in 2 hours)
|
|
29
|
+
devportal 3000 --demo
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### List active tunnels
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
devportal ls
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Stop a tunnel
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Stop specific tunnel
|
|
42
|
+
devportal stop <tunnel-id>
|
|
43
|
+
|
|
44
|
+
# Stop all tunnels
|
|
45
|
+
devportal stop --all
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Replay requests
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Replay a captured request
|
|
52
|
+
devportal replay <request-id>
|
|
53
|
+
|
|
54
|
+
# With modified headers
|
|
55
|
+
devportal replay <request-id> --header "X-Debug: true"
|
|
56
|
+
|
|
57
|
+
# With modified body
|
|
58
|
+
devportal replay <request-id> --body '{"test": true}'
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Stream logs
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
devportal logs <tunnel-id>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Device info
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
devportal whoami
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Configuration
|
|
74
|
+
|
|
75
|
+
DevPortal stores configuration in `~/.devportal/`:
|
|
76
|
+
|
|
77
|
+
- `device.json` - Your unique device ID
|
|
78
|
+
- `tunnels.json` - Active tunnel information
|
|
79
|
+
|
|
80
|
+
## Publishing to npm
|
|
81
|
+
|
|
82
|
+
1. Create an npm account at https://www.npmjs.com
|
|
83
|
+
2. Login: `npm login`
|
|
84
|
+
3. Build: `npm run build`
|
|
85
|
+
4. Publish: `npm publish`
|
|
86
|
+
|
|
87
|
+
## Development
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
# Install dependencies
|
|
91
|
+
npm install
|
|
92
|
+
|
|
93
|
+
# Run in development
|
|
94
|
+
npm run dev 3000
|
|
95
|
+
|
|
96
|
+
# Build
|
|
97
|
+
npm run build
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## License
|
|
101
|
+
|
|
102
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAGA,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAmCjD"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.listTunnels = listTunnels;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const tunnels_1 = require("../utils/tunnels");
|
|
9
|
+
async function listTunnels() {
|
|
10
|
+
const tunnels = (0, tunnels_1.getTunnels)().filter((t) => t.status === 'live');
|
|
11
|
+
if (tunnels.length === 0) {
|
|
12
|
+
console.log(chalk_1.default.yellow('No active tunnels'));
|
|
13
|
+
console.log(chalk_1.default.gray('Start one with: devportal <port>'));
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
console.log(chalk_1.default.bold('Active Tunnels'));
|
|
17
|
+
console.log();
|
|
18
|
+
// Table header
|
|
19
|
+
const header = [
|
|
20
|
+
chalk_1.default.gray('ID'.padEnd(15)),
|
|
21
|
+
chalk_1.default.gray('Name'.padEnd(22)),
|
|
22
|
+
chalk_1.default.gray('Port'.padEnd(6)),
|
|
23
|
+
chalk_1.default.gray('URL'),
|
|
24
|
+
].join(' ');
|
|
25
|
+
console.log(header);
|
|
26
|
+
console.log(chalk_1.default.gray('─'.repeat(80)));
|
|
27
|
+
// Table rows
|
|
28
|
+
for (const tunnel of tunnels) {
|
|
29
|
+
const row = [
|
|
30
|
+
chalk_1.default.white(tunnel.id.padEnd(15)),
|
|
31
|
+
chalk_1.default.cyan(tunnel.name.padEnd(22)),
|
|
32
|
+
chalk_1.default.white(tunnel.localPort.toString().padEnd(6)),
|
|
33
|
+
chalk_1.default.underline(tunnel.url),
|
|
34
|
+
].join(' ');
|
|
35
|
+
console.log(row);
|
|
36
|
+
}
|
|
37
|
+
console.log();
|
|
38
|
+
console.log(chalk_1.default.gray(`${tunnels.length} tunnel(s) active`));
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":";;;;;AAGA,kCAmCC;AAtCD,kDAA0B;AAC1B,8CAA8C;AAEvC,KAAK,UAAU,WAAW;IAC/B,MAAM,OAAO,GAAG,IAAA,oBAAU,GAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAEhE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;QAC5D,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,eAAe;IACf,MAAM,MAAM,GAAG;QACb,eAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC7B,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC5B,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC;KAClB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACZ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAExC,aAAa;IACb,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG;YACV,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACjC,eAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAClC,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAClD,eAAK,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC;SAC5B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,mBAAmB,CAAC,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAGA,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmE9D"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.showLogs = showLogs;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const tunnels_1 = require("../utils/tunnels");
|
|
9
|
+
async function showLogs(tunnelId) {
|
|
10
|
+
const tunnel = (0, tunnels_1.getTunnel)(tunnelId);
|
|
11
|
+
if (!tunnel) {
|
|
12
|
+
console.log(chalk_1.default.red(`Tunnel not found: ${tunnelId}`));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
if (tunnel.status !== 'live') {
|
|
16
|
+
console.log(chalk_1.default.yellow(`Tunnel ${tunnel.name} is not active`));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
console.log(chalk_1.default.gray(`Streaming logs for ${tunnel.name}...`));
|
|
20
|
+
console.log(chalk_1.default.gray(`URL: ${tunnel.url}`));
|
|
21
|
+
console.log(chalk_1.default.gray('Press Ctrl+C to stop'));
|
|
22
|
+
console.log();
|
|
23
|
+
console.log(chalk_1.default.gray('─'.repeat(70)));
|
|
24
|
+
console.log();
|
|
25
|
+
// Simulate log streaming
|
|
26
|
+
const methods = ['GET', 'POST', 'PUT', 'DELETE'];
|
|
27
|
+
const paths = ['/api/users', '/api/auth', '/api/data', '/webhook', '/health'];
|
|
28
|
+
const statuses = [200, 200, 200, 201, 400, 401, 404];
|
|
29
|
+
const logEntry = () => {
|
|
30
|
+
const method = methods[Math.floor(Math.random() * methods.length)];
|
|
31
|
+
const path = paths[Math.floor(Math.random() * paths.length)];
|
|
32
|
+
const status = statuses[Math.floor(Math.random() * statuses.length)];
|
|
33
|
+
const duration = Math.floor(Math.random() * 200) + 20;
|
|
34
|
+
const ip = `${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`;
|
|
35
|
+
const methodColor = {
|
|
36
|
+
GET: chalk_1.default.green,
|
|
37
|
+
POST: chalk_1.default.blue,
|
|
38
|
+
PUT: chalk_1.default.yellow,
|
|
39
|
+
DELETE: chalk_1.default.red,
|
|
40
|
+
}[method] || chalk_1.default.white;
|
|
41
|
+
const statusColor = status < 300 ? chalk_1.default.green : status < 400 ? chalk_1.default.yellow : chalk_1.default.red;
|
|
42
|
+
const timestamp = new Date().toISOString();
|
|
43
|
+
console.log(chalk_1.default.gray(timestamp), chalk_1.default.gray(ip.padEnd(15)), methodColor(method.padEnd(6)), chalk_1.default.white(path.padEnd(20)), statusColor(status.toString()), chalk_1.default.gray(`${duration}ms`));
|
|
44
|
+
const nextInterval = Math.floor(Math.random() * 5000) + 1000;
|
|
45
|
+
setTimeout(logEntry, nextInterval);
|
|
46
|
+
};
|
|
47
|
+
// Handle shutdown
|
|
48
|
+
process.on('SIGINT', () => {
|
|
49
|
+
console.log();
|
|
50
|
+
console.log(chalk_1.default.gray('Log streaming stopped'));
|
|
51
|
+
process.exit(0);
|
|
52
|
+
});
|
|
53
|
+
// Start logging
|
|
54
|
+
logEntry();
|
|
55
|
+
// Keep process alive
|
|
56
|
+
await new Promise(() => { });
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.d.ts","sourceRoot":"","sources":["../../src/commands/replay.ts"],"names":[],"mappings":"AAGA,UAAU,aAAa;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA+C5F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.replayRequest = replayRequest;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
async function replayRequest(requestId, options) {
|
|
10
|
+
const spinner = (0, ora_1.default)(`Replaying request ${requestId}...`).start();
|
|
11
|
+
// Simulate replay delay
|
|
12
|
+
await sleep(800);
|
|
13
|
+
// Mock request data
|
|
14
|
+
const mockRequest = {
|
|
15
|
+
id: requestId,
|
|
16
|
+
method: 'POST',
|
|
17
|
+
path: '/api/webhook',
|
|
18
|
+
headers: {
|
|
19
|
+
'Content-Type': 'application/json',
|
|
20
|
+
'X-Webhook-Event': 'payment.completed',
|
|
21
|
+
},
|
|
22
|
+
body: { event: 'payment.completed', amount: 99.99 },
|
|
23
|
+
};
|
|
24
|
+
spinner.succeed(chalk_1.default.green('Request replayed'));
|
|
25
|
+
console.log();
|
|
26
|
+
// Display request info
|
|
27
|
+
console.log(chalk_1.default.gray('Request:'));
|
|
28
|
+
console.log(chalk_1.default.blue(` ${mockRequest.method}`), chalk_1.default.white(mockRequest.path));
|
|
29
|
+
console.log();
|
|
30
|
+
if (options.header) {
|
|
31
|
+
console.log(chalk_1.default.gray('Modified headers:'));
|
|
32
|
+
console.log(chalk_1.default.yellow(` ${options.header}`));
|
|
33
|
+
console.log();
|
|
34
|
+
}
|
|
35
|
+
if (options.body) {
|
|
36
|
+
console.log(chalk_1.default.gray('Modified body:'));
|
|
37
|
+
console.log(chalk_1.default.yellow(` ${options.body}`));
|
|
38
|
+
console.log();
|
|
39
|
+
}
|
|
40
|
+
// Simulate response
|
|
41
|
+
const status = 200;
|
|
42
|
+
const duration = Math.floor(Math.random() * 100) + 30;
|
|
43
|
+
console.log(chalk_1.default.gray('Response:'));
|
|
44
|
+
console.log(chalk_1.default.green(` ${status} OK`), chalk_1.default.gray(`(${duration}ms)`));
|
|
45
|
+
console.log();
|
|
46
|
+
console.log(chalk_1.default.gray('Body:'));
|
|
47
|
+
console.log(chalk_1.default.white(' { "success": true, "message": "Webhook processed" }'));
|
|
48
|
+
}
|
|
49
|
+
function sleep(ms) {
|
|
50
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=replay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay.js","sourceRoot":"","sources":["../../src/commands/replay.ts"],"names":[],"mappings":";;;;;AAQA,sCA+CC;AAvDD,kDAA0B;AAC1B,8CAAsB;AAOf,KAAK,UAAU,aAAa,CAAC,SAAiB,EAAE,OAAsB;IAC3E,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,qBAAqB,SAAS,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAEjE,wBAAwB;IACxB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAEjB,oBAAoB;IACpB,MAAM,WAAW,GAAG;QAClB,EAAE,EAAE,SAAS;QACb,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE;YACP,cAAc,EAAE,kBAAkB;YAClC,iBAAiB,EAAE,mBAAmB;SACvC;QACD,IAAI,EAAE,EAAE,KAAK,EAAE,mBAAmB,EAAE,MAAM,EAAE,KAAK,EAAE;KACpD,CAAC;IAEF,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,uBAAuB;IACvB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,eAAK,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC;IAClF,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,EAAE,CAAC;IAChB,CAAC;IAED,oBAAoB;IACpB,MAAM,MAAM,GAAG,GAAG,CAAC;IACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,EAAE,CAAC;IAEtD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,KAAK,MAAM,KAAK,CAAC,EAAE,eAAK,CAAC,IAAI,CAAC,IAAI,QAAQ,KAAK,CAAC,CAAC,CAAC;IAC1E,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IACjC,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC,CAAC;AACpF,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface StartOptions {
|
|
2
|
+
subdomain?: string;
|
|
3
|
+
password?: string;
|
|
4
|
+
demo?: boolean;
|
|
5
|
+
qr?: boolean;
|
|
6
|
+
authHeader?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function startTunnel(port: number, options: StartOptions): Promise<void>;
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AASA,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA4EpF"}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.startTunnel = startTunnel;
|
|
40
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
41
|
+
const ora_1 = __importDefault(require("ora"));
|
|
42
|
+
const http = __importStar(require("http"));
|
|
43
|
+
const tunnels_1 = require("../utils/tunnels");
|
|
44
|
+
const device_1 = require("../utils/device");
|
|
45
|
+
// @ts-ignore - qrcode-terminal doesn't have types
|
|
46
|
+
const qrcode = __importStar(require("qrcode-terminal"));
|
|
47
|
+
async function startTunnel(port, options) {
|
|
48
|
+
const spinner = (0, ora_1.default)('Establishing tunnel...').start();
|
|
49
|
+
// Check if local server is running
|
|
50
|
+
const isPortOpen = await checkPort(port);
|
|
51
|
+
if (!isPortOpen) {
|
|
52
|
+
spinner.warn(chalk_1.default.yellow(`No server detected on port ${port}`));
|
|
53
|
+
console.log(chalk_1.default.gray(` Make sure your local server is running first`));
|
|
54
|
+
console.log(chalk_1.default.gray(` Example: npm run dev`));
|
|
55
|
+
console.log();
|
|
56
|
+
}
|
|
57
|
+
// Generate tunnel info
|
|
58
|
+
const name = options.subdomain || (0, tunnels_1.generateTunnelName)();
|
|
59
|
+
const tunnelId = `t-${Date.now().toString(36)}`;
|
|
60
|
+
const url = `https://${name}.devportal.live`;
|
|
61
|
+
// Simulate connection delay
|
|
62
|
+
await sleep(1500);
|
|
63
|
+
const tunnel = {
|
|
64
|
+
id: tunnelId,
|
|
65
|
+
name,
|
|
66
|
+
url,
|
|
67
|
+
localPort: port,
|
|
68
|
+
status: 'live',
|
|
69
|
+
createdAt: new Date().toISOString(),
|
|
70
|
+
pid: process.pid,
|
|
71
|
+
};
|
|
72
|
+
(0, tunnels_1.addTunnel)(tunnel);
|
|
73
|
+
spinner.succeed(chalk_1.default.green('Tunnel established'));
|
|
74
|
+
console.log();
|
|
75
|
+
// Display tunnel info
|
|
76
|
+
console.log(chalk_1.default.gray(' Local server: '), chalk_1.default.white(`http://localhost:${port}`));
|
|
77
|
+
console.log(chalk_1.default.gray(' Public URL: '), chalk_1.default.cyan.underline(url));
|
|
78
|
+
console.log(chalk_1.default.gray(' Tunnel ID: '), chalk_1.default.white(tunnelId));
|
|
79
|
+
if (options.password) {
|
|
80
|
+
console.log(chalk_1.default.gray(' Password: '), chalk_1.default.yellow('Protected'));
|
|
81
|
+
}
|
|
82
|
+
if (options.demo) {
|
|
83
|
+
console.log(chalk_1.default.gray(' Expires: '), chalk_1.default.yellow('2 hours'));
|
|
84
|
+
}
|
|
85
|
+
console.log();
|
|
86
|
+
console.log(chalk_1.default.gray(' Dashboard: '), chalk_1.default.underline(`https://devportal.live/dashboard/${(0, device_1.getDeviceId)()}`));
|
|
87
|
+
console.log();
|
|
88
|
+
// Show QR code if requested
|
|
89
|
+
if (options.qr) {
|
|
90
|
+
console.log(chalk_1.default.gray(' Scan to open on mobile:'));
|
|
91
|
+
console.log();
|
|
92
|
+
qrcode.generate(url, { small: true });
|
|
93
|
+
console.log();
|
|
94
|
+
}
|
|
95
|
+
// Start mock request logging
|
|
96
|
+
console.log(chalk_1.default.gray(' Waiting for requests... (Press Ctrl+C to stop)'));
|
|
97
|
+
console.log();
|
|
98
|
+
// Simulate incoming requests
|
|
99
|
+
simulateRequests();
|
|
100
|
+
// Handle shutdown
|
|
101
|
+
process.on('SIGINT', () => {
|
|
102
|
+
console.log();
|
|
103
|
+
console.log(chalk_1.default.yellow('Tunnel stopped'));
|
|
104
|
+
process.exit(0);
|
|
105
|
+
});
|
|
106
|
+
// Keep process alive
|
|
107
|
+
await new Promise(() => { });
|
|
108
|
+
}
|
|
109
|
+
async function checkPort(port) {
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
const req = http.request({ host: 'localhost', port, timeout: 1000 }, () => {
|
|
112
|
+
resolve(true);
|
|
113
|
+
});
|
|
114
|
+
req.on('error', () => resolve(false));
|
|
115
|
+
req.on('timeout', () => resolve(false));
|
|
116
|
+
req.end();
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
function sleep(ms) {
|
|
120
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
121
|
+
}
|
|
122
|
+
function simulateRequests() {
|
|
123
|
+
const methods = ['GET', 'POST', 'PUT', 'DELETE'];
|
|
124
|
+
const paths = ['/api/users', '/api/auth', '/api/data', '/webhook', '/health', '/api/items'];
|
|
125
|
+
const statuses = [200, 200, 200, 201, 400, 401, 404, 500];
|
|
126
|
+
const logRequest = () => {
|
|
127
|
+
const method = methods[Math.floor(Math.random() * methods.length)];
|
|
128
|
+
const path = paths[Math.floor(Math.random() * paths.length)];
|
|
129
|
+
const status = statuses[Math.floor(Math.random() * statuses.length)];
|
|
130
|
+
const duration = Math.floor(Math.random() * 200) + 20;
|
|
131
|
+
const methodColor = {
|
|
132
|
+
GET: chalk_1.default.green,
|
|
133
|
+
POST: chalk_1.default.blue,
|
|
134
|
+
PUT: chalk_1.default.yellow,
|
|
135
|
+
DELETE: chalk_1.default.red,
|
|
136
|
+
}[method] || chalk_1.default.white;
|
|
137
|
+
const statusColor = status < 300 ? chalk_1.default.green : status < 400 ? chalk_1.default.yellow : chalk_1.default.red;
|
|
138
|
+
const timestamp = new Date().toLocaleTimeString();
|
|
139
|
+
console.log(chalk_1.default.gray(timestamp), methodColor(method.padEnd(6)), chalk_1.default.white(path.padEnd(20)), statusColor(status.toString()), chalk_1.default.gray(`${duration}ms`));
|
|
140
|
+
// Schedule next request (random interval 2-8 seconds)
|
|
141
|
+
const nextInterval = Math.floor(Math.random() * 6000) + 2000;
|
|
142
|
+
setTimeout(logRequest, nextInterval);
|
|
143
|
+
};
|
|
144
|
+
// Start after initial delay
|
|
145
|
+
setTimeout(logRequest, 3000);
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDlG"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.stopTunnel = stopTunnel;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const tunnels_1 = require("../utils/tunnels");
|
|
10
|
+
async function stopTunnel(tunnelId, options) {
|
|
11
|
+
const tunnels = (0, tunnels_1.getTunnels)();
|
|
12
|
+
const liveTunnels = tunnels.filter((t) => t.status === 'live');
|
|
13
|
+
if (liveTunnels.length === 0) {
|
|
14
|
+
console.log(chalk_1.default.yellow('No active tunnels to stop'));
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
if (options.all) {
|
|
18
|
+
const spinner = (0, ora_1.default)('Stopping all tunnels...').start();
|
|
19
|
+
// Mark all as stopped
|
|
20
|
+
const updated = tunnels.map((t) => ({ ...t, status: 'stopped' }));
|
|
21
|
+
(0, tunnels_1.saveTunnels)(updated);
|
|
22
|
+
await sleep(500);
|
|
23
|
+
spinner.succeed(chalk_1.default.green(`Stopped ${liveTunnels.length} tunnel(s)`));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (!tunnelId) {
|
|
27
|
+
console.log(chalk_1.default.red('Please specify a tunnel ID or use --all'));
|
|
28
|
+
console.log(chalk_1.default.gray('Usage: devportal stop <tunnel-id>'));
|
|
29
|
+
console.log(chalk_1.default.gray(' devportal stop --all'));
|
|
30
|
+
console.log();
|
|
31
|
+
console.log(chalk_1.default.gray('Active tunnels:'));
|
|
32
|
+
for (const t of liveTunnels) {
|
|
33
|
+
console.log(chalk_1.default.gray(` ${t.id} (${t.name})`));
|
|
34
|
+
}
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
// Find tunnel by ID or name
|
|
38
|
+
const tunnel = liveTunnels.find((t) => t.id === tunnelId || t.name === tunnelId);
|
|
39
|
+
if (!tunnel) {
|
|
40
|
+
console.log(chalk_1.default.red(`Tunnel not found: ${tunnelId}`));
|
|
41
|
+
console.log(chalk_1.default.gray('Active tunnels:'));
|
|
42
|
+
for (const t of liveTunnels) {
|
|
43
|
+
console.log(chalk_1.default.gray(` ${t.id} (${t.name})`));
|
|
44
|
+
}
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const spinner = (0, ora_1.default)(`Stopping tunnel ${tunnel.name}...`).start();
|
|
48
|
+
(0, tunnels_1.updateTunnel)(tunnel.id, { status: 'stopped' });
|
|
49
|
+
await sleep(500);
|
|
50
|
+
spinner.succeed(chalk_1.default.green(`Tunnel ${tunnel.name} stopped`));
|
|
51
|
+
}
|
|
52
|
+
function sleep(ms) {
|
|
53
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":";;;;;AAQA,gCAmDC;AA3DD,kDAA0B;AAC1B,8CAAsB;AACtB,8CAAyE;AAMlE,KAAK,UAAU,UAAU,CAAC,QAA4B,EAAE,OAAoB;IACjF,MAAM,OAAO,GAAG,IAAA,oBAAU,GAAE,CAAC;IAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC;IAE/D,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACvD,OAAO;IACT,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,yBAAyB,CAAC,CAAC,KAAK,EAAE,CAAC;QAEvD,sBAAsB;QACtB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,MAAM,EAAE,SAAkB,EAAE,CAAC,CAAC,CAAC;QAC3E,IAAA,qBAAW,EAAC,OAAO,CAAC,CAAC;QAErB,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;QACjB,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,WAAW,WAAW,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC,CAAC;QAC7D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO;IACT,CAAC;IAED,4BAA4B;IAC5B,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IAEjF,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,qBAAqB,QAAQ,EAAE,CAAC,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC3C,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;YAC5B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACnD,CAAC;QACD,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,mBAAmB,MAAM,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC;IAEjE,IAAA,sBAAY,EAAC,MAAM,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IAE/C,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,UAAU,MAAM,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const commander_1 = require("commander");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const start_1 = require("./commands/start");
|
|
10
|
+
const list_1 = require("./commands/list");
|
|
11
|
+
const stop_1 = require("./commands/stop");
|
|
12
|
+
const replay_1 = require("./commands/replay");
|
|
13
|
+
const logs_1 = require("./commands/logs");
|
|
14
|
+
const device_1 = require("./utils/device");
|
|
15
|
+
const program = new commander_1.Command();
|
|
16
|
+
// ASCII art logo
|
|
17
|
+
const logo = `
|
|
18
|
+
${chalk_1.default.cyan('╔═══════════════════════════════════════╗')}
|
|
19
|
+
${chalk_1.default.cyan('║')} ${chalk_1.default.bold.white('DevPortal')} - Share localhost instantly ${chalk_1.default.cyan('║')}
|
|
20
|
+
${chalk_1.default.cyan('╚═══════════════════════════════════════╝')}
|
|
21
|
+
`;
|
|
22
|
+
program
|
|
23
|
+
.name('devportal')
|
|
24
|
+
.description('Expose your localhost to the internet with a single command')
|
|
25
|
+
.version('1.0.0')
|
|
26
|
+
.hook('preAction', () => {
|
|
27
|
+
console.log(logo);
|
|
28
|
+
});
|
|
29
|
+
// Main command: devportal <port>
|
|
30
|
+
program
|
|
31
|
+
.argument('[port]', 'Local port to expose', '3000')
|
|
32
|
+
.option('-s, --subdomain <name>', 'Custom subdomain for your URL')
|
|
33
|
+
.option('-p, --password <pass>', 'Password protect the tunnel')
|
|
34
|
+
.option('--demo', 'Create a temporary link that expires in 2 hours')
|
|
35
|
+
.option('--qr', 'Display QR code in terminal')
|
|
36
|
+
.option('--auth-header <header>', 'Add authorization header to requests')
|
|
37
|
+
.action(async (port, options) => {
|
|
38
|
+
if (port && !isNaN(parseInt(port))) {
|
|
39
|
+
await (0, start_1.startTunnel)(parseInt(port), options);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
program.help();
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
// List tunnels: devportal ls
|
|
46
|
+
program
|
|
47
|
+
.command('ls')
|
|
48
|
+
.alias('list')
|
|
49
|
+
.description('List all active tunnels')
|
|
50
|
+
.action(async () => {
|
|
51
|
+
await (0, list_1.listTunnels)();
|
|
52
|
+
});
|
|
53
|
+
// Stop tunnel: devportal stop <id>
|
|
54
|
+
program
|
|
55
|
+
.command('stop [tunnelId]')
|
|
56
|
+
.description('Stop a tunnel by ID')
|
|
57
|
+
.option('-a, --all', 'Stop all active tunnels')
|
|
58
|
+
.action(async (tunnelId, options) => {
|
|
59
|
+
await (0, stop_1.stopTunnel)(tunnelId, options);
|
|
60
|
+
});
|
|
61
|
+
// Replay request: devportal replay <requestId>
|
|
62
|
+
program
|
|
63
|
+
.command('replay <requestId>')
|
|
64
|
+
.description('Replay a captured request')
|
|
65
|
+
.option('-H, --header <header>', 'Add or override a header')
|
|
66
|
+
.option('-b, --body <body>', 'Override request body')
|
|
67
|
+
.action(async (requestId, options) => {
|
|
68
|
+
await (0, replay_1.replayRequest)(requestId, options);
|
|
69
|
+
});
|
|
70
|
+
// Stream logs: devportal logs <tunnelId>
|
|
71
|
+
program
|
|
72
|
+
.command('logs <tunnelId>')
|
|
73
|
+
.description('Stream live request logs from a tunnel')
|
|
74
|
+
.action(async (tunnelId) => {
|
|
75
|
+
await (0, logs_1.showLogs)(tunnelId);
|
|
76
|
+
});
|
|
77
|
+
// Device info command
|
|
78
|
+
program
|
|
79
|
+
.command('whoami')
|
|
80
|
+
.description('Show current device ID')
|
|
81
|
+
.action(() => {
|
|
82
|
+
const deviceId = (0, device_1.getDeviceId)();
|
|
83
|
+
console.log(chalk_1.default.gray('Device ID:'), chalk_1.default.cyan(deviceId));
|
|
84
|
+
console.log(chalk_1.default.gray('Dashboard:'), chalk_1.default.underline(`https://devportal.live/dashboard/${deviceId}`));
|
|
85
|
+
});
|
|
86
|
+
program.parse();
|
|
87
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../src/utils/device.ts"],"names":[],"mappings":"AAaA,wBAAgB,WAAW,IAAI,MAAM,CAwBpC;AAQD,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getDeviceId = getDeviceId;
|
|
37
|
+
exports.getConfigDir = getConfigDir;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
41
|
+
const crypto = __importStar(require("crypto"));
|
|
42
|
+
const CONFIG_DIR = path.join(os.homedir(), '.devportal');
|
|
43
|
+
const DEVICE_FILE = path.join(CONFIG_DIR, 'device.json');
|
|
44
|
+
function getDeviceId() {
|
|
45
|
+
ensureConfigDir();
|
|
46
|
+
if (fs.existsSync(DEVICE_FILE)) {
|
|
47
|
+
try {
|
|
48
|
+
const config = JSON.parse(fs.readFileSync(DEVICE_FILE, 'utf-8'));
|
|
49
|
+
return config.deviceId;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Corrupted file, regenerate
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Generate new device ID
|
|
56
|
+
const timestamp = Date.now().toString(36);
|
|
57
|
+
const random = crypto.randomBytes(4).toString('hex');
|
|
58
|
+
const deviceId = `dev_${timestamp}_${random}`;
|
|
59
|
+
const config = {
|
|
60
|
+
deviceId,
|
|
61
|
+
createdAt: new Date().toISOString(),
|
|
62
|
+
};
|
|
63
|
+
fs.writeFileSync(DEVICE_FILE, JSON.stringify(config, null, 2));
|
|
64
|
+
return deviceId;
|
|
65
|
+
}
|
|
66
|
+
function ensureConfigDir() {
|
|
67
|
+
if (!fs.existsSync(CONFIG_DIR)) {
|
|
68
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function getConfigDir() {
|
|
72
|
+
ensureConfigDir();
|
|
73
|
+
return CONFIG_DIR;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../src/utils/device.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAaA,kCAwBC;AAQD,oCAGC;AAhDD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAC7B,+CAAiC;AAEjC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AACzD,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAOzD,SAAgB,WAAW;IACzB,eAAe,EAAE,CAAC;IAElB,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAiB,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;YAC/E,OAAO,MAAM,CAAC,QAAQ,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,6BAA6B;QAC/B,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,OAAO,SAAS,IAAI,MAAM,EAAE,CAAC;IAE9C,MAAM,MAAM,GAAiB;QAC3B,QAAQ;QACR,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChD,CAAC;AACH,CAAC;AAED,SAAgB,YAAY;IAC1B,eAAe,EAAE,CAAC;IAClB,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface TunnelInfo {
|
|
2
|
+
id: string;
|
|
3
|
+
name: string;
|
|
4
|
+
url: string;
|
|
5
|
+
localPort: number;
|
|
6
|
+
status: 'live' | 'stopped';
|
|
7
|
+
createdAt: string;
|
|
8
|
+
pid?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function getTunnels(): TunnelInfo[];
|
|
11
|
+
export declare function saveTunnels(tunnels: TunnelInfo[]): void;
|
|
12
|
+
export declare function addTunnel(tunnel: TunnelInfo): void;
|
|
13
|
+
export declare function removeTunnel(id: string): void;
|
|
14
|
+
export declare function updateTunnel(id: string, updates: Partial<TunnelInfo>): void;
|
|
15
|
+
export declare function getTunnel(id: string): TunnelInfo | undefined;
|
|
16
|
+
export declare function generateTunnelName(): string;
|
|
17
|
+
//# sourceMappingURL=tunnels.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnels.d.ts","sourceRoot":"","sources":["../../src/utils/tunnels.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAID,wBAAgB,UAAU,IAAI,UAAU,EAAE,CASzC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,IAAI,CAEvD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAIlD;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAK3E;AAED,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAE5D;AAMD,wBAAgB,kBAAkB,IAAI,MAAM,CAK3C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getTunnels = getTunnels;
|
|
37
|
+
exports.saveTunnels = saveTunnels;
|
|
38
|
+
exports.addTunnel = addTunnel;
|
|
39
|
+
exports.removeTunnel = removeTunnel;
|
|
40
|
+
exports.updateTunnel = updateTunnel;
|
|
41
|
+
exports.getTunnel = getTunnel;
|
|
42
|
+
exports.generateTunnelName = generateTunnelName;
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const path = __importStar(require("path"));
|
|
45
|
+
const device_1 = require("./device");
|
|
46
|
+
const TUNNELS_FILE = path.join((0, device_1.getConfigDir)(), 'tunnels.json');
|
|
47
|
+
function getTunnels() {
|
|
48
|
+
if (!fs.existsSync(TUNNELS_FILE)) {
|
|
49
|
+
return [];
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
return JSON.parse(fs.readFileSync(TUNNELS_FILE, 'utf-8'));
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
return [];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function saveTunnels(tunnels) {
|
|
59
|
+
fs.writeFileSync(TUNNELS_FILE, JSON.stringify(tunnels, null, 2));
|
|
60
|
+
}
|
|
61
|
+
function addTunnel(tunnel) {
|
|
62
|
+
const tunnels = getTunnels();
|
|
63
|
+
tunnels.push(tunnel);
|
|
64
|
+
saveTunnels(tunnels);
|
|
65
|
+
}
|
|
66
|
+
function removeTunnel(id) {
|
|
67
|
+
const tunnels = getTunnels().filter((t) => t.id !== id);
|
|
68
|
+
saveTunnels(tunnels);
|
|
69
|
+
}
|
|
70
|
+
function updateTunnel(id, updates) {
|
|
71
|
+
const tunnels = getTunnels().map((t) => t.id === id ? { ...t, ...updates } : t);
|
|
72
|
+
saveTunnels(tunnels);
|
|
73
|
+
}
|
|
74
|
+
function getTunnel(id) {
|
|
75
|
+
return getTunnels().find((t) => t.id === id || t.name === id);
|
|
76
|
+
}
|
|
77
|
+
// Generate random tunnel name
|
|
78
|
+
const adjectives = ['purple', 'cosmic', 'hidden', 'crystal', 'silent', 'golden', 'frozen', 'blazing', 'lunar', 'neon'];
|
|
79
|
+
const nouns = ['horizon', 'lake', 'forest', 'ocean', 'canyon', 'river', 'meadow', 'summit', 'valley', 'storm'];
|
|
80
|
+
function generateTunnelName() {
|
|
81
|
+
const adj = adjectives[Math.floor(Math.random() * adjectives.length)];
|
|
82
|
+
const noun = nouns[Math.floor(Math.random() * nouns.length)];
|
|
83
|
+
const num = Math.floor(Math.random() * 900) + 100;
|
|
84
|
+
return `${adj}-${noun}-${num}`;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=tunnels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tunnels.js","sourceRoot":"","sources":["../../src/utils/tunnels.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "devportal-tunnel",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Expose your localhost to the internet with a single command",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"devportal-tunnel": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc",
|
|
11
|
+
"dev": "ts-node src/index.ts",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"tunnel",
|
|
17
|
+
"localhost",
|
|
18
|
+
"ngrok",
|
|
19
|
+
"dev",
|
|
20
|
+
"webhook",
|
|
21
|
+
"api",
|
|
22
|
+
"debugging"
|
|
23
|
+
],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"chalk": "^4.1.2",
|
|
28
|
+
"commander": "^11.1.0",
|
|
29
|
+
"ora": "^5.4.1",
|
|
30
|
+
"qrcode-terminal": "^0.12.0",
|
|
31
|
+
"ws": "^8.16.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.10.0",
|
|
35
|
+
"@types/ws": "^8.5.10",
|
|
36
|
+
"ts-node": "^10.9.2",
|
|
37
|
+
"typescript": "^5.3.0"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=16.0.0"
|
|
41
|
+
},
|
|
42
|
+
"repository": {
|
|
43
|
+
"type": "git",
|
|
44
|
+
"url": ""
|
|
45
|
+
},
|
|
46
|
+
"files": [
|
|
47
|
+
"dist"
|
|
48
|
+
]
|
|
49
|
+
}
|