devportal-tunnel 1.0.0 → 1.0.2

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 CHANGED
@@ -1,16 +1,26 @@
1
- # DevPortal Tunnel CLI
1
+ # DevPortal CLI
2
2
 
3
3
  Expose your localhost to the internet with a single command.
4
4
 
5
5
  ## Installation
6
6
 
7
+ ### From npm (after publishing)
8
+
7
9
  ```bash
8
10
  npm install -g devportal
9
11
  ```
10
12
 
11
- ## Usage
13
+ ### From source
12
14
 
13
- ### Start a tunnel
15
+ ```bash
16
+ git clone <repo>
17
+ cd cli
18
+ npm install
19
+ npm run build
20
+ npm link
21
+ ```
22
+
23
+ ## Quick Start
14
24
 
15
25
  ```bash
16
26
  # Expose port 3000
@@ -22,11 +32,26 @@ devportal 3000 --subdomain my-api
22
32
  # Password protected
23
33
  devportal 3000 --password secret123
24
34
 
25
- # Show QR code for mobile
26
- devportal 3000 --qr
27
-
28
35
  # Temporary demo link (expires in 2 hours)
29
36
  devportal 3000 --demo
37
+
38
+ # Run in local simulation mode (no server needed)
39
+ devportal 3000 --local
40
+ ```
41
+
42
+ ## Commands
43
+
44
+ ### Start a tunnel
45
+
46
+ ```bash
47
+ devportal <port> [options]
48
+
49
+ Options:
50
+ -s, --subdomain <name> Custom subdomain for your URL
51
+ -p, --password <pass> Password protect the tunnel
52
+ --demo Create a temporary link (2 hours)
53
+ --auth-header <header> Add authorization header to forwarded requests
54
+ --local Run in simulation mode (no server required)
30
55
  ```
31
56
 
32
57
  ### List active tunnels
@@ -64,6 +89,19 @@ devportal replay <request-id> --body '{"test": true}'
64
89
  devportal logs <tunnel-id>
65
90
  ```
66
91
 
92
+ ### Configuration
93
+
94
+ ```bash
95
+ # View current config
96
+ devportal config
97
+
98
+ # Set server URL (for self-hosted)
99
+ devportal config server https://your-server.com
100
+
101
+ # Reset to defaults
102
+ devportal config reset
103
+ ```
104
+
67
105
  ### Device info
68
106
 
69
107
  ```bash
@@ -74,15 +112,76 @@ devportal whoami
74
112
 
75
113
  DevPortal stores configuration in `~/.devportal/`:
76
114
 
77
- - `device.json` - Your unique device ID
78
- - `tunnels.json` - Active tunnel information
115
+ ```
116
+ ~/.devportal/
117
+ ├── config.json # Server URL, WebSocket URL
118
+ ├── device.json # Unique device ID
119
+ └── tunnels.json # Active tunnel information
120
+ ```
121
+
122
+ ### Self-Hosted Server
123
+
124
+ To use your own DevPortal server:
125
+
126
+ ```bash
127
+ # Set your server URL
128
+ devportal config server https://tunnel.your-domain.com
129
+
130
+ # Now tunnels will use your server
131
+ devportal 3000
132
+ ```
133
+
134
+ ## How It Works
135
+
136
+ 1. **CLI connects** to the DevPortal server via WebSocket
137
+ 2. **Server assigns** a public URL (e.g., `https://my-app.devportal.live`)
138
+ 3. **Requests arrive** at the public URL
139
+ 4. **Server forwards** requests through the WebSocket to CLI
140
+ 5. **CLI proxies** requests to your local server
141
+ 6. **Response travels** back through the tunnel
142
+
143
+ ```
144
+ Internet Request
145
+ │
146
+ ▼
147
+ [DevPortal Server] ◄──WSS──► [CLI Client] ──► [localhost:3000]
148
+ │ │
149
+ └──────── Response ◄─────────┘
150
+ ```
79
151
 
80
152
  ## Publishing to npm
81
153
 
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`
154
+ 1. **Update package.json** with your details:
155
+
156
+ ```json
157
+ {
158
+ "name": "devportal",
159
+ "author": "Your Name",
160
+ "repository": {
161
+ "type": "git",
162
+ "url": "https://github.com/yourusername/devportal"
163
+ }
164
+ }
165
+ ```
166
+
167
+ 2. **Login and publish**:
168
+
169
+ ```bash
170
+ npm login
171
+ npm publish
172
+ ```
173
+
174
+ 3. **For scoped package** (if name is taken):
175
+
176
+ ```json
177
+ {
178
+ "name": "@yourusername/devportal"
179
+ }
180
+ ```
181
+
182
+ ```bash
183
+ npm publish --access public
184
+ ```
86
185
 
87
186
  ## Development
88
187
 
@@ -95,6 +194,9 @@ npm run dev 3000
95
194
 
96
195
  # Build
97
196
  npm run build
197
+
198
+ # Link globally for testing
199
+ npm link
98
200
  ```
99
201
 
100
202
  ## License
@@ -0,0 +1,2 @@
1
+ export declare function configCommand(action?: string, value?: string): Promise<void>;
2
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":"AAGA,wBAAsB,aAAa,CACjC,MAAM,CAAC,EAAE,MAAM,EACf,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAkCf"}
@@ -0,0 +1,41 @@
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.configCommand = configCommand;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const config_1 = require("../utils/config");
9
+ async function configCommand(action, value) {
10
+ if (!action) {
11
+ // Show current config
12
+ const config = (0, config_1.getConfig)();
13
+ console.log(chalk_1.default.bold("Current Configuration"));
14
+ console.log();
15
+ console.log(chalk_1.default.gray("Server URL: "), chalk_1.default.white(config.serverUrl));
16
+ console.log(chalk_1.default.gray("WebSocket URL: "), chalk_1.default.white(config.wsUrl));
17
+ console.log();
18
+ console.log(chalk_1.default.gray("Config file: ~/.devportal/config.json"));
19
+ return;
20
+ }
21
+ switch (action) {
22
+ case "server":
23
+ if (!value) {
24
+ console.log(chalk_1.default.red("Please provide a server URL"));
25
+ console.log(chalk_1.default.gray("Usage: devportal config server <url>"));
26
+ return;
27
+ }
28
+ (0, config_1.setServerUrl)(value);
29
+ console.log(chalk_1.default.green("Server URL updated"));
30
+ console.log(chalk_1.default.gray("Server: "), chalk_1.default.white(value));
31
+ break;
32
+ case "reset":
33
+ (0, config_1.setServerUrl)("https://devportal.stylnode.in");
34
+ console.log(chalk_1.default.green("Config reset to defaults"));
35
+ break;
36
+ default:
37
+ console.log(chalk_1.default.red(`Unknown config action: ${action}`));
38
+ console.log(chalk_1.default.gray("Available actions: server, reset"));
39
+ }
40
+ }
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/commands/config.ts"],"names":[],"mappings":";;;;;AAGA,sCAqCC;AAxCD,kDAA0B;AAC1B,4CAA0D;AAEnD,KAAK,UAAU,aAAa,CACjC,MAAe,EACf,KAAc;IAEd,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,sBAAsB;QACtB,MAAM,MAAM,GAAG,IAAA,kBAAS,GAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,CAAC;QACjD,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC;QAC1E,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,EAAE,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACtE,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,QAAQ,MAAM,EAAE,CAAC;QACf,KAAK,QAAQ;YACX,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC,CAAC;gBAChE,OAAO;YACT,CAAC;YACD,IAAA,qBAAY,EAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,eAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAC3D,MAAM;QAER,KAAK,OAAO;YACV,IAAA,qBAAY,EAAC,+BAA+B,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAC,CAAC;YACrD,MAAM;QAER;YACE,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,CAAC;IAChE,CAAC;AACH,CAAC"}
@@ -19,17 +19,17 @@ async function listTunnels() {
19
19
  const header = [
20
20
  chalk_1.default.gray('ID'.padEnd(15)),
21
21
  chalk_1.default.gray('Name'.padEnd(22)),
22
- chalk_1.default.gray('Port'.padEnd(6)),
22
+ chalk_1.default.gray('Local Port'.padEnd(12)),
23
23
  chalk_1.default.gray('URL'),
24
24
  ].join(' ');
25
25
  console.log(header);
26
- console.log(chalk_1.default.gray('─'.repeat(80)));
26
+ console.log(chalk_1.default.gray('─'.repeat(85)));
27
27
  // Table rows
28
28
  for (const tunnel of tunnels) {
29
29
  const row = [
30
30
  chalk_1.default.white(tunnel.id.padEnd(15)),
31
31
  chalk_1.default.cyan(tunnel.name.padEnd(22)),
32
- chalk_1.default.white(tunnel.localPort.toString().padEnd(6)),
32
+ chalk_1.default.white(tunnel.localPort.toString().padEnd(12)),
33
33
  chalk_1.default.underline(tunnel.url),
34
34
  ].join(' ');
35
35
  console.log(row);
@@ -1 +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"}
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,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACnC,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,EAAE,CAAC,CAAC;YACnD,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,2 @@
1
+ export declare function portCommand(action?: string, port?: number): Promise<void>;
2
+ //# sourceMappingURL=port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../src/commands/port.ts"],"names":[],"mappings":"AAWA,wBAAsB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CA6B/E"}
@@ -0,0 +1,192 @@
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.portCommand = portCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const tunnels_1 = require("../utils/tunnels");
42
+ const http = __importStar(require("http"));
43
+ async function portCommand(action, port) {
44
+ if (!action) {
45
+ await showPortUsage();
46
+ return;
47
+ }
48
+ switch (action.toLowerCase()) {
49
+ case 'check':
50
+ if (!port) {
51
+ console.log(chalk_1.default.red('Please specify a port to check'));
52
+ console.log(chalk_1.default.gray('Usage: devportal-tunnel port check <port>'));
53
+ return;
54
+ }
55
+ await checkPort(port);
56
+ break;
57
+ case 'scan':
58
+ const startPort = port || 3000;
59
+ await scanPorts(startPort, startPort + 9);
60
+ break;
61
+ case 'list':
62
+ await showPortUsage();
63
+ break;
64
+ default:
65
+ console.log(chalk_1.default.red(`Unknown port action: ${action}`));
66
+ console.log(chalk_1.default.gray('Available actions: check, scan, list'));
67
+ }
68
+ }
69
+ async function showPortUsage() {
70
+ const tunnels = (0, tunnels_1.getTunnels)().filter(t => t.status === 'live');
71
+ console.log(chalk_1.default.bold('Port Usage'));
72
+ console.log();
73
+ if (tunnels.length === 0) {
74
+ console.log(chalk_1.default.yellow('No ports currently tunneled'));
75
+ console.log(chalk_1.default.gray('Start a tunnel to see port usage'));
76
+ return;
77
+ }
78
+ // Header
79
+ const header = [
80
+ chalk_1.default.gray('Port'.padEnd(8)),
81
+ chalk_1.default.gray('Status'.padEnd(12)),
82
+ chalk_1.default.gray('Tunnel ID'.padEnd(15)),
83
+ chalk_1.default.gray('Tunnel Name'),
84
+ ].join(' ');
85
+ console.log(header);
86
+ console.log(chalk_1.default.gray('─'.repeat(70)));
87
+ // Show tunneled ports
88
+ for (const tunnel of tunnels) {
89
+ const row = [
90
+ chalk_1.default.white(tunnel.localPort.toString().padEnd(8)),
91
+ chalk_1.default.green('TUNNELED'.padEnd(12)),
92
+ chalk_1.default.cyan(tunnel.id.padEnd(15)),
93
+ chalk_1.default.white(tunnel.name),
94
+ ].join(' ');
95
+ console.log(row);
96
+ }
97
+ console.log();
98
+ console.log(chalk_1.default.gray(`${tunnels.length} port(s) currently tunneled`));
99
+ console.log();
100
+ console.log(chalk_1.default.gray('Commands:'));
101
+ console.log(chalk_1.default.gray(' devportal-tunnel port check <port> - Check if a port is available'));
102
+ console.log(chalk_1.default.gray(' devportal-tunnel port scan [start] - Scan for available ports'));
103
+ }
104
+ async function checkPort(port) {
105
+ console.log(chalk_1.default.gray(`Checking port ${port}...`));
106
+ // Check if port is tunneled
107
+ const tunnels = (0, tunnels_1.getTunnels)().filter(t => t.status === 'live' && t.localPort === port);
108
+ if (tunnels.length > 0) {
109
+ const tunnel = tunnels[0];
110
+ console.log(chalk_1.default.yellow(`Port ${port} is currently tunneled`));
111
+ console.log(chalk_1.default.gray(` Tunnel ID: ${tunnel.id}`));
112
+ console.log(chalk_1.default.gray(` Tunnel Name: ${tunnel.name}`));
113
+ console.log(chalk_1.default.gray(` Public URL: ${tunnel.url}`));
114
+ return;
115
+ }
116
+ // Check if port is occupied
117
+ const isOccupied = await isPortOccupied(port);
118
+ if (isOccupied) {
119
+ console.log(chalk_1.default.green(`✓ Port ${port} is available (server running)`));
120
+ console.log(chalk_1.default.gray(' Ready to be tunneled'));
121
+ }
122
+ else {
123
+ console.log(chalk_1.default.red(`✗ Port ${port} is not available (no server running)`));
124
+ console.log(chalk_1.default.gray(' Start your local server first'));
125
+ }
126
+ }
127
+ async function scanPorts(startPort, endPort) {
128
+ console.log(chalk_1.default.gray(`Scanning ports ${startPort}-${endPort}...`));
129
+ console.log();
130
+ const results = [];
131
+ const tunnels = (0, tunnels_1.getTunnels)().filter(t => t.status === 'live');
132
+ for (let port = startPort; port <= endPort; port++) {
133
+ const tunnel = tunnels.find(t => t.localPort === port);
134
+ if (tunnel) {
135
+ results.push({
136
+ port,
137
+ status: 'tunneled',
138
+ tunnelId: tunnel.id,
139
+ tunnelName: tunnel.name,
140
+ });
141
+ }
142
+ else {
143
+ const isOccupied = await isPortOccupied(port);
144
+ results.push({
145
+ port,
146
+ status: isOccupied ? 'occupied' : 'available',
147
+ });
148
+ }
149
+ }
150
+ // Header
151
+ const header = [
152
+ chalk_1.default.gray('Port'.padEnd(8)),
153
+ chalk_1.default.gray('Status'.padEnd(12)),
154
+ chalk_1.default.gray('Details'),
155
+ ].join(' ');
156
+ console.log(header);
157
+ console.log(chalk_1.default.gray('─'.repeat(60)));
158
+ // Results
159
+ for (const result of results) {
160
+ const statusColor = result.status === 'available' ? chalk_1.default.red('AVAILABLE') :
161
+ result.status === 'occupied' ? chalk_1.default.green('OCCUPIED') :
162
+ chalk_1.default.yellow('TUNNELED');
163
+ const details = result.status === 'tunneled' ? `Tunnel: ${result.tunnelName}` :
164
+ result.status === 'occupied' ? 'Server running' :
165
+ 'No server';
166
+ const row = [
167
+ chalk_1.default.white(result.port.toString().padEnd(8)),
168
+ statusColor.padEnd(12),
169
+ chalk_1.default.gray(details),
170
+ ].join(' ');
171
+ console.log(row);
172
+ }
173
+ console.log();
174
+ const availableCount = results.filter(r => r.status === 'occupied').length;
175
+ const tunneledCount = results.filter(r => r.status === 'tunneled').length;
176
+ console.log(chalk_1.default.gray('Summary:'));
177
+ console.log(chalk_1.default.gray(` ${availableCount} port(s) available for tunneling`));
178
+ if (tunneledCount > 0) {
179
+ console.log(chalk_1.default.gray(` ${tunneledCount} port(s) already tunneled`));
180
+ }
181
+ }
182
+ async function isPortOccupied(port) {
183
+ return new Promise((resolve) => {
184
+ const req = http.request({ host: 'localhost', port, timeout: 1000 }, () => {
185
+ resolve(true);
186
+ });
187
+ req.on('error', () => resolve(false));
188
+ req.on('timeout', () => resolve(false));
189
+ req.end();
190
+ });
191
+ }
192
+ //# sourceMappingURL=port.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"port.js","sourceRoot":"","sources":["../../src/commands/port.ts"],"names":[],"mappings":"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"}
@@ -2,8 +2,9 @@ interface StartOptions {
2
2
  subdomain?: string;
3
3
  password?: string;
4
4
  demo?: boolean;
5
- qr?: boolean;
6
5
  authHeader?: string;
6
+ local?: boolean;
7
+ forward?: string;
7
8
  }
8
9
  export declare function startTunnel(port: number, options: StartOptions): Promise<void>;
9
10
  export {};
@@ -1 +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"}
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAYA,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,IAAI,CAAC,CAuNf"}