devtunnel-cli 3.0.24 → 3.0.26

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "devtunnel-cli",
3
- "version": "3.0.24",
3
+ "version": "3.0.26",
4
4
  "type": "module",
5
5
  "description": "DevTunnel - Share local dev servers worldwide. Zero configuration tunnel for any framework. Install via npm: npm install -g devtunnel-cli. Works with Vite, React, Next.js, Express, NestJS, Laravel (PHP), HTML, and more.",
6
6
  "main": "src/core/start.js",
@@ -8,13 +8,14 @@ process.emitWarning = function (warning, ...args) {
8
8
  };
9
9
  const { default: httpProxy } = await import("http-proxy");
10
10
 
11
- // Get ports from command line
11
+ // Get ports and optional base path from command line
12
12
  const TARGET_PORT = parseInt(process.argv[2]); // Your dev server port
13
13
  const PROXY_PORT = parseInt(process.argv[3]); // Port for tunnel to connect to
14
14
  const PROJECT_NAME = process.argv[4] || "Project";
15
+ const BASE_PATH = process.argv[5] || ""; // e.g. /PeopleQ for XAMPP htdocs/PeopleQ
15
16
 
16
17
  if (!TARGET_PORT || !PROXY_PORT) {
17
- console.error("Usage: node proxy-server.js <target-port> <proxy-port> [project-name]");
18
+ console.error("Usage: node proxy-server.js <target-port> <proxy-port> [project-name] [base-path]");
18
19
  process.exit(1);
19
20
  }
20
21
 
@@ -63,12 +64,22 @@ const server = http.createServer((req, res) => {
63
64
  return;
64
65
  }
65
66
 
67
+ // XAMPP subfolder: rewrite path so / → /PeopleQ/, /style.css → /PeopleQ/style.css
68
+ if (BASE_PATH) {
69
+ const prefix = BASE_PATH.replace(/\/$/, "");
70
+ req.url = prefix + (req.url === "/" ? "/" : req.url);
71
+ }
72
+
66
73
  // Proxy the request
67
74
  proxy.web(req, res);
68
75
  });
69
76
 
70
77
  // Handle WebSocket upgrade (for Vite HMR)
71
78
  server.on("upgrade", (req, socket, head) => {
79
+ if (BASE_PATH) {
80
+ const prefix = BASE_PATH.replace(/\/$/, "");
81
+ req.url = prefix + (req.url === "/" ? "/" : req.url);
82
+ }
72
83
  proxy.ws(req, socket, head);
73
84
  });
74
85
 
@@ -78,7 +89,7 @@ server.listen(PROXY_PORT, () => {
78
89
  console.log("DevTunnel Proxy Server");
79
90
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
80
91
  console.log(`Project: ${PROJECT_NAME}`);
81
- console.log(`Dev Server: http://localhost:${TARGET_PORT}`);
92
+ console.log(`Dev Server: http://localhost:${TARGET_PORT}${BASE_PATH || ""}`);
82
93
  console.log(`Proxy Port: ${PROXY_PORT}`);
83
94
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
84
95
  console.log("Ready! Tunnel will connect to proxy");
package/src/core/start.js CHANGED
@@ -17,10 +17,10 @@ function getPackageVersion() {
17
17
  const pkgPath = join(PROJECT_ROOT, "package.json");
18
18
  if (existsSync(pkgPath)) {
19
19
  const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
20
- return pkg.version || "3.0.24";
20
+ return pkg.version || "3.0.26";
21
21
  }
22
22
  } catch (err) {}
23
- return "3.0.24";
23
+ return "3.0.26";
24
24
  }
25
25
 
26
26
  // Helper to run command
@@ -136,9 +136,17 @@ function detectHtmlProject(currentDir) {
136
136
  return { name: basename(currentDir), defaultPort: 5500 }; // Live Server default; matches VS Code
137
137
  }
138
138
 
139
+ // Detect PHP/XAMPP project (index.php in root, not Laravel)
140
+ function detectPhpProject(currentDir) {
141
+ if (detectLaravelProject(currentDir)) return null; // Laravel has its own flow
142
+ const indexPhp = join(currentDir, "index.php");
143
+ if (!existsSync(indexPhp)) return null;
144
+ return { name: basename(currentDir), defaultPort: 80 }; // XAMPP/Apache default
145
+ }
146
+
139
147
  // Check common ports for running dev servers (includes Laravel 8000, XAMPP/Live Server 8080/5500)
140
148
  async function detectRunningDevServer() {
141
- const commonPorts = [3000, 5173, 5500, 8080, 8000, 5000, 4000, 3001, 5174]; // 5500 before 8080 for Live Server
149
+ const commonPorts = [3000, 5173, 5500, 8080, 8000, 80, 5000, 4000, 3001, 5174]; // 80 for XAMPP
142
150
  const detected = [];
143
151
 
144
152
  for (const port of commonPorts) {
@@ -218,6 +226,18 @@ async function autoDetectProject() {
218
226
  };
219
227
  }
220
228
 
229
+ // 4) PHP/XAMPP (index.php) — default port 80 (Apache), e.g. http://localhost/PeopleQ/
230
+ const php = detectPhpProject(currentDir);
231
+ if (php) {
232
+ const detectedPort = runningPorts.length > 0 ? runningPorts[0] : php.defaultPort;
233
+ return {
234
+ path: currentDir,
235
+ name: php.name,
236
+ port: detectedPort,
237
+ projectType: "php"
238
+ };
239
+ }
240
+
221
241
  return null;
222
242
  }
223
243
 
@@ -355,7 +375,9 @@ async function main() {
355
375
  ? "Laravel (php artisan serve)"
356
376
  : autoDetected.projectType === "html"
357
377
  ? "HTML project"
358
- : "package.json";
378
+ : autoDetected.projectType === "php"
379
+ ? "PHP/XAMPP"
380
+ : "package.json";
359
381
  console.log(`Detected port ${autoDetected.port} (${portSource}), but no server running on that port`);
360
382
  console.log("Checking for running dev servers...");
361
383
 
@@ -418,12 +440,15 @@ async function main() {
418
440
  projectPath = selectedPath;
419
441
  projectName = basename(selectedPath);
420
442
 
421
- // Try to detect port for selected project (Laravel → 8000, Node from package.json, else 5173)
443
+ // Try to detect port for selected project (Laravel → 8000, HTML → 5500, Node from package.json)
422
444
  const selectedPackagePath = join(selectedPath, "package.json");
423
445
  const laravelSelected = detectLaravelProject(selectedPath);
446
+ const htmlSelected = detectHtmlProject(selectedPath);
424
447
  const detectedPort = laravelSelected
425
448
  ? laravelSelected.defaultPort
426
- : detectPortFromPackage(selectedPackagePath);
449
+ : htmlSelected
450
+ ? htmlSelected.defaultPort
451
+ : detectPortFromPackage(selectedPackagePath);
427
452
 
428
453
  const portResponse = await prompts({
429
454
  type: "number",
@@ -438,6 +463,17 @@ async function main() {
438
463
  }
439
464
 
440
465
  devPort = portResponse.port;
466
+ } else {
467
+ // User confirmed – let them keep default port or type another (e.g. HTML default 5500, can change)
468
+ const portPrompt = await prompts({
469
+ type: "number",
470
+ name: "port",
471
+ message: "Dev server port (press Enter for default):",
472
+ initial: devPort
473
+ });
474
+ if (portPrompt.port != null && portPrompt.port > 0) {
475
+ devPort = portPrompt.port;
476
+ }
441
477
  }
442
478
  } else if (autoDetected && !autoDetected.port) {
443
479
  // Project detected but no port
@@ -507,15 +543,18 @@ async function main() {
507
543
  console.log(`Selected: ${projectPath}`);
508
544
  console.log("");
509
545
 
510
- // Try to detect port for selected project (Laravel → 8000, HTML → 8080, Node from package.json)
546
+ // Try to detect port for selected project (Laravel → 8000, HTML → 5500, PHP → 80, Node from package.json)
511
547
  const selectedPackagePath = join(projectPath, "package.json");
512
548
  const laravelSelected = detectLaravelProject(projectPath);
513
549
  const htmlSelected = detectHtmlProject(projectPath);
550
+ const phpSelected = detectPhpProject(projectPath);
514
551
  let detectedPort = laravelSelected
515
552
  ? laravelSelected.defaultPort
516
553
  : htmlSelected
517
554
  ? htmlSelected.defaultPort // 5500
518
- : detectPortFromPackage(selectedPackagePath);
555
+ : phpSelected
556
+ ? phpSelected.defaultPort // 80
557
+ : detectPortFromPackage(selectedPackagePath);
519
558
 
520
559
  // Check for running servers
521
560
  const runningPorts = await detectRunningDevServer();
@@ -543,11 +582,17 @@ async function main() {
543
582
  console.log("");
544
583
  const proxyPort = devPort + 1000; // Use port 1000 higher for proxy
545
584
 
585
+ // XAMPP subfolder (e.g. htdocs/PeopleQ → http://localhost/PeopleQ/) — proxy rewrites path
586
+ const isPhpXamppSubfolder =
587
+ devPort === 80 &&
588
+ (projectPath.toLowerCase().includes("htdocs") || projectPath.toLowerCase().includes("www"));
589
+ const basePath = isPhpXamppSubfolder ? "/" + basename(projectPath) : "";
590
+
546
591
  console.log("");
547
592
  console.log("Configuration:");
548
593
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
549
594
  console.log(`Project: ${projectName}`);
550
- console.log(`Dev Server: localhost:${devPort}`);
595
+ console.log(`Dev Server: localhost:${devPort}${basePath || ""}`);
551
596
  console.log(`Proxy Port: ${proxyPort}`);
552
597
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
553
598
  console.log("");
@@ -579,7 +624,9 @@ async function main() {
579
624
  console.log("Starting services...");
580
625
  console.log("");
581
626
  const proxyPath = join(__dirname, "proxy-server.js");
582
- const proxyProcess = spawn("node", [proxyPath, devPort.toString(), proxyPort.toString(), projectName], {
627
+ const proxyArgs = [proxyPath, devPort.toString(), proxyPort.toString(), projectName];
628
+ if (basePath) proxyArgs.push(basePath);
629
+ const proxyProcess = spawn("node", proxyArgs, {
583
630
  stdio: "inherit",
584
631
  shell: false
585
632
  });