devtunnel-cli 3.0.25 → 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.25",
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.25";
20
+ return pkg.version || "3.0.26";
21
21
  }
22
22
  } catch (err) {}
23
- return "3.0.25";
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
 
@@ -521,15 +543,18 @@ async function main() {
521
543
  console.log(`Selected: ${projectPath}`);
522
544
  console.log("");
523
545
 
524
- // 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)
525
547
  const selectedPackagePath = join(projectPath, "package.json");
526
548
  const laravelSelected = detectLaravelProject(projectPath);
527
549
  const htmlSelected = detectHtmlProject(projectPath);
550
+ const phpSelected = detectPhpProject(projectPath);
528
551
  let detectedPort = laravelSelected
529
552
  ? laravelSelected.defaultPort
530
553
  : htmlSelected
531
554
  ? htmlSelected.defaultPort // 5500
532
- : detectPortFromPackage(selectedPackagePath);
555
+ : phpSelected
556
+ ? phpSelected.defaultPort // 80
557
+ : detectPortFromPackage(selectedPackagePath);
533
558
 
534
559
  // Check for running servers
535
560
  const runningPorts = await detectRunningDevServer();
@@ -557,11 +582,17 @@ async function main() {
557
582
  console.log("");
558
583
  const proxyPort = devPort + 1000; // Use port 1000 higher for proxy
559
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
+
560
591
  console.log("");
561
592
  console.log("Configuration:");
562
593
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
563
594
  console.log(`Project: ${projectName}`);
564
- console.log(`Dev Server: localhost:${devPort}`);
595
+ console.log(`Dev Server: localhost:${devPort}${basePath || ""}`);
565
596
  console.log(`Proxy Port: ${proxyPort}`);
566
597
  console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
567
598
  console.log("");
@@ -593,7 +624,9 @@ async function main() {
593
624
  console.log("Starting services...");
594
625
  console.log("");
595
626
  const proxyPath = join(__dirname, "proxy-server.js");
596
- 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, {
597
630
  stdio: "inherit",
598
631
  shell: false
599
632
  });