portless 0.15.0 → 0.15.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 +17 -6
- package/dist/{chunk-PCBKLZK2.js → chunk-T7CGCIRO.js} +64 -18
- package/dist/cli.js +341 -168
- package/dist/index.d.ts +21 -1
- package/dist/index.js +5 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -34,7 +34,7 @@ HTTPS with HTTP/2 is enabled by default. On first run, portless generates a loca
|
|
|
34
34
|
|
|
35
35
|
The proxy auto-starts when you run an app. A random port (4000-4999) is assigned via the `PORT` environment variable. Most frameworks (Next.js, Express, Nuxt, etc.) respect this automatically. For frameworks that ignore `PORT` (Vite, VitePlus, Astro, React Router, Angular, Expo, React Native), portless auto-injects the right `--port` flag and, when needed, a matching `--host` flag.
|
|
36
36
|
|
|
37
|
-
When auto-starting, portless reuses the configuration (port, TLS,
|
|
37
|
+
When auto-starting, portless reuses the configuration (port, TLS, TLDs) from the most recent proxy run, so a restart or reboot does not silently revert to defaults. Explicit env vars (`PORTLESS_PORT`, `PORTLESS_HTTPS`, etc.) always take priority.
|
|
38
38
|
|
|
39
39
|
In non-interactive environments (no TTY, or `CI=1`), portless exits with a descriptive error instead of prompting, so task runners like turborepo and CI scripts fail early with a clear message.
|
|
40
40
|
|
|
@@ -210,6 +210,17 @@ portless myapp next dev
|
|
|
210
210
|
|
|
211
211
|
The proxy auto-syncs `/etc/hosts` for route hostnames (including `.test`), so those domains resolve on your machine.
|
|
212
212
|
|
|
213
|
+
Repeat `--tld` to serve the same app names under multiple TLDs from one proxy:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
portless proxy start --tld localhost --tld test
|
|
217
|
+
portless myapp next dev
|
|
218
|
+
# -> https://myapp.localhost
|
|
219
|
+
# -> https://myapp.test
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
When multiple TLDs are configured, `PORTLESS_URL` uses the first TLD. `PORTLESS_TLD` also accepts a comma separated list, e.g. `PORTLESS_TLD=localhost,test`.
|
|
223
|
+
|
|
213
224
|
Recommended: `.test` (IANA-reserved, no collision risk). Avoid `.local` (conflicts with mDNS/Bonjour) and `.dev` (Google-owned, forces HTTPS via HSTS).
|
|
214
225
|
|
|
215
226
|
## How it works
|
|
@@ -264,7 +275,7 @@ portless service uninstall
|
|
|
264
275
|
|
|
265
276
|
The service uses portless defaults unless install options or `PORTLESS_*` environment variables are provided: HTTPS on port 443 with `.localhost` names. `service install` accepts the proxy options you would use with `proxy start`, including `--port`, `--no-tls`, `--lan`, `--ip`, `--tld`, `--wildcard`, `--cert`, and `--key`. Use `--state-dir <path>` or `PORTLESS_STATE_DIR=<path>` to choose where service state and logs are written.
|
|
266
277
|
|
|
267
|
-
The chosen service configuration is written into launchd, systemd, or Task Scheduler and reused after reboot. `portless service status` reports the installed port, HTTPS mode,
|
|
278
|
+
The chosen service configuration is written into launchd, systemd, or Task Scheduler and reused after reboot. `portless service status` reports the installed port, HTTPS mode, TLDs, LAN mode, wildcard mode, and state directory. macOS and Linux install a root-owned service so port 443 can bind at boot. Windows installs a Task Scheduler startup task that runs as SYSTEM. Installation and removal may require administrator privileges. `portless clean` automatically removes the service.
|
|
268
279
|
|
|
269
280
|
## LAN mode
|
|
270
281
|
|
|
@@ -276,7 +287,7 @@ portless proxy start --lan --ip 192.168.1.42
|
|
|
276
287
|
|
|
277
288
|
`--lan` switches the proxy to mDNS discovery: services are advertised as `<name>.local` and reachable from any device on the same network. Portless auto-detects your LAN IP and follows Wi-Fi/IP changes automatically, but you can pin another address with `--ip <address>` or by exporting `PORTLESS_LAN_IP`. Set `PORTLESS_LAN=1` in your shell (0/1 boolean) to make LAN mode the default whenever the proxy starts.
|
|
278
289
|
|
|
279
|
-
Portless remembers LAN mode via `proxy.lan`, so if you stop a LAN proxy and start it again, it stays in LAN mode. All proxy settings (port, TLS,
|
|
290
|
+
Portless remembers LAN mode via `proxy.lan`, so if you stop a LAN proxy and start it again, it stays in LAN mode. All proxy settings (port, TLS, TLDs, LAN) are persisted and reused on auto-start unless overridden by explicit flags or env vars. Use `PORTLESS_LAN=0` for one start to switch back to `.localhost` mode. If a proxy is already running with different explicit LAN/TLS/TLD settings, portless warns and asks you to stop it first.
|
|
280
291
|
|
|
281
292
|
LAN mode depends on the system mDNS tools that portless already spawns: macOS ships with `dns-sd`, while Linux uses `avahi-publish-address` from `avahi-utils` (install via `sudo apt install avahi-utils` or your distro’s equivalent). If the command is missing or your network isn’t reachable, `portless proxy start --lan` prints the relevant error and exits.
|
|
282
293
|
|
|
@@ -386,7 +397,7 @@ portless service uninstall # Remove the startup service
|
|
|
386
397
|
--cert <path> Use a custom TLS certificate
|
|
387
398
|
--key <path> Use a custom TLS private key
|
|
388
399
|
--foreground Run proxy in foreground instead of daemon
|
|
389
|
-
--tld <tld> Use a custom TLD instead of .localhost
|
|
400
|
+
--tld <tld> Use a custom TLD instead of .localhost; repeat for more
|
|
390
401
|
--wildcard Allow unregistered subdomains to fall back to parent route
|
|
391
402
|
--state-dir <path> Use a custom state directory with service install
|
|
392
403
|
--script <name> Run a specific package.json script (default: dev)
|
|
@@ -407,7 +418,7 @@ PORTLESS_APP_PORT=<number> Use a fixed port for the app (same as --app-por
|
|
|
407
418
|
PORTLESS_HTTPS=0 Disable HTTPS (same as --no-tls)
|
|
408
419
|
PORTLESS_LAN=1 Enable LAN mode when set to 1 (auto-detects LAN IP)
|
|
409
420
|
PORTLESS_LAN_IP=<address> Pin a specific LAN IP for LAN mode
|
|
410
|
-
PORTLESS_TLD=<tld>
|
|
421
|
+
PORTLESS_TLD=<tld>[,<tld>] Use one or more TLDs (e.g. localhost,test)
|
|
411
422
|
PORTLESS_WILDCARD=1 Allow unregistered subdomains to fall back to parent route
|
|
412
423
|
PORTLESS_SYNC_HOSTS=0 Disable auto-sync of /etc/hosts (on by default)
|
|
413
424
|
PORTLESS_TAILSCALE=1 Share apps on your Tailscale network (same as --tailscale)
|
|
@@ -418,7 +429,7 @@ PORTLESS_STATE_DIR=<path> Override the state directory
|
|
|
418
429
|
# Injected into child processes
|
|
419
430
|
PORT Ephemeral port the child should listen on
|
|
420
431
|
HOST Usually 127.0.0.1 (omitted for Expo in LAN mode)
|
|
421
|
-
PORTLESS_URL
|
|
432
|
+
PORTLESS_URL Primary public URL (e.g. https://myapp.localhost)
|
|
422
433
|
PORTLESS_TAILSCALE_URL Tailscale URL of the app (when --tailscale is active)
|
|
423
434
|
PORTLESS_NGROK_URL ngrok URL of the app (when --ngrok is active)
|
|
424
435
|
NODE_EXTRA_CA_CERTS Path to the portless CA (when HTTPS is active)
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
// src/utils.ts
|
|
2
2
|
import * as fs from "fs";
|
|
3
|
+
import * as net from "net";
|
|
4
|
+
function loopbackLookup(_hostname, _options, callback) {
|
|
5
|
+
callback(null, [
|
|
6
|
+
{ address: "127.0.0.1", family: 4 },
|
|
7
|
+
{ address: "::1", family: 6 }
|
|
8
|
+
]);
|
|
9
|
+
}
|
|
10
|
+
function createLoopbackConnection(port) {
|
|
11
|
+
return net.connect({
|
|
12
|
+
host: "localhost",
|
|
13
|
+
port,
|
|
14
|
+
autoSelectFamily: true,
|
|
15
|
+
lookup: loopbackLookup
|
|
16
|
+
});
|
|
17
|
+
}
|
|
3
18
|
function fixOwnership(...paths) {
|
|
4
19
|
if (process.platform === "win32") return;
|
|
5
20
|
const uid = process.env.SUDO_UID;
|
|
@@ -65,11 +80,23 @@ function parseHostname(input, tld = "localhost") {
|
|
|
65
80
|
}
|
|
66
81
|
return hostname;
|
|
67
82
|
}
|
|
83
|
+
function parseHostnames(input, tlds = ["localhost"]) {
|
|
84
|
+
const uniqueTlds = [...new Set(tlds)];
|
|
85
|
+
let baseInput = input.trim().replace(/^https?:\/\//, "").split("/")[0].toLowerCase();
|
|
86
|
+
for (const tld of uniqueTlds) {
|
|
87
|
+
const suffix = `.${tld}`;
|
|
88
|
+
if (baseInput.endsWith(suffix)) {
|
|
89
|
+
baseInput = baseInput.slice(0, -suffix.length);
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return uniqueTlds.map((tld) => parseHostname(baseInput, tld));
|
|
94
|
+
}
|
|
68
95
|
|
|
69
96
|
// src/proxy.ts
|
|
70
97
|
import * as http from "http";
|
|
71
98
|
import * as http2 from "http2";
|
|
72
|
-
import * as
|
|
99
|
+
import * as net2 from "net";
|
|
73
100
|
|
|
74
101
|
// src/fonts.ts
|
|
75
102
|
var GEIST_SANS_400 = "data:font/woff2;base64,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";
|
|
@@ -314,24 +341,41 @@ function buildForwardedHeaders(req, tls) {
|
|
|
314
341
|
}
|
|
315
342
|
var PORTLESS_HOPS_HEADER = "x-portless-hops";
|
|
316
343
|
var MAX_PROXY_HOPS = 5;
|
|
344
|
+
function tailscaleAuthority(tailscaleUrl) {
|
|
345
|
+
if (!tailscaleUrl) return void 0;
|
|
346
|
+
try {
|
|
347
|
+
return new URL(tailscaleUrl).host;
|
|
348
|
+
} catch {
|
|
349
|
+
return void 0;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
function normalizeAuthority(host) {
|
|
353
|
+
const lower = host.toLowerCase();
|
|
354
|
+
return lower.endsWith(":443") ? lower.slice(0, -":443".length) : lower;
|
|
355
|
+
}
|
|
317
356
|
function findRoute(routes, host, strict) {
|
|
318
|
-
|
|
357
|
+
const authority = normalizeAuthority(host);
|
|
358
|
+
const hostname = authority.split(":")[0];
|
|
359
|
+
return routes.find((r) => r.hostname.toLowerCase() === hostname) || routes.find((r) => tailscaleAuthority(r.tailscaleUrl) === authority) || routes.find((r) => tailscaleAuthority(r.tailscaleUrl)?.split(":")[0] === hostname) || (strict ? void 0 : routes.find((r) => hostname.endsWith("." + r.hostname.toLowerCase())));
|
|
319
360
|
}
|
|
320
361
|
function createProxyServer(options) {
|
|
321
362
|
const {
|
|
322
363
|
getRoutes,
|
|
323
364
|
proxyPort,
|
|
324
365
|
tld = "localhost",
|
|
366
|
+
tlds = [tld],
|
|
325
367
|
strict = true,
|
|
326
368
|
onError = (msg) => console.error(msg),
|
|
327
369
|
tls
|
|
328
370
|
} = options;
|
|
329
|
-
const
|
|
371
|
+
const tldSuffixes = [...new Set(tlds.length > 0 ? tlds : [tld])].map((value) => `.${value}`);
|
|
372
|
+
const primaryTldSuffix = tldSuffixes[0] ?? ".localhost";
|
|
330
373
|
const handleRequest = (req, res) => {
|
|
331
374
|
const reqTls = isEncrypted(req);
|
|
332
375
|
res.setHeader(PORTLESS_HEADER, "1");
|
|
333
376
|
const routes = getRoutes();
|
|
334
|
-
const
|
|
377
|
+
const rawHost = getRequestHost(req);
|
|
378
|
+
const host = rawHost.split(":")[0];
|
|
335
379
|
if (!host) {
|
|
336
380
|
res.writeHead(400, { "Content-Type": "text/plain" });
|
|
337
381
|
res.end("Missing Host header");
|
|
@@ -349,7 +393,7 @@ function createProxyServer(options) {
|
|
|
349
393
|
"Loop Detected",
|
|
350
394
|
`<div class="content"><p class="desc">This request has passed through portless ${hops} times. This usually means a dev server (Vite, webpack, etc.) is proxying requests back through portless without rewriting the Host header.</p><div class="section"><p class="label">Fix: add changeOrigin to your proxy config</p><pre class="terminal">proxy: {
|
|
351
395
|
"/api": {
|
|
352
|
-
target: "${reqTls ? "https" : "http"}://<backend>${escapeHtml(
|
|
396
|
+
target: "${reqTls ? "https" : "http"}://<backend>${escapeHtml(primaryTldSuffix)}${reqTls ? "" : ":<port>"}",
|
|
353
397
|
changeOrigin: true,
|
|
354
398
|
},
|
|
355
399
|
}</pre></div></div>`
|
|
@@ -357,10 +401,11 @@ function createProxyServer(options) {
|
|
|
357
401
|
);
|
|
358
402
|
return;
|
|
359
403
|
}
|
|
360
|
-
const route = findRoute(routes,
|
|
404
|
+
const route = findRoute(routes, rawHost, strict);
|
|
361
405
|
if (!route) {
|
|
362
406
|
const safeHost = escapeHtml(host);
|
|
363
|
-
const
|
|
407
|
+
const matchedSuffix = tldSuffixes.find((suffix) => host.endsWith(suffix));
|
|
408
|
+
const strippedHost = matchedSuffix ? host.slice(0, -matchedSuffix.length) : host;
|
|
364
409
|
const safeSuggestion = escapeHtml(strippedHost);
|
|
365
410
|
const routesList = routes.length > 0 ? `<div class="section"><p class="label">Active apps</p><ul class="card">${routes.map((r) => `<li><a href="${escapeHtml(formatUrl(r.hostname, proxyPort, reqTls))}" class="card-link"><span class="name">${escapeHtml(r.hostname)}</span><span class="meta"><code class="port">127.0.0.1:${escapeHtml(String(r.port))}</code><span class="arrow">${ARROW_SVG}</span></span></a></li>`).join("")}</ul></div>` : '<p class="empty">No apps running.</p>';
|
|
366
411
|
res.writeHead(404, { "Content-Type": "text/html" });
|
|
@@ -389,8 +434,8 @@ function createProxyServer(options) {
|
|
|
389
434
|
}
|
|
390
435
|
const proxyReq = http.request(
|
|
391
436
|
{
|
|
392
|
-
|
|
393
|
-
|
|
437
|
+
// Dial via createLoopbackConnection so ::1-only backends work too.
|
|
438
|
+
createConnection: () => createLoopbackConnection(route.port),
|
|
394
439
|
path: req.url,
|
|
395
440
|
method: req.method,
|
|
396
441
|
headers: proxyReqHeaders
|
|
@@ -445,9 +490,9 @@ function createProxyServer(options) {
|
|
|
445
490
|
socket.on("error", () => socket.destroy());
|
|
446
491
|
const hops = parseInt(req.headers[PORTLESS_HOPS_HEADER], 10) || 0;
|
|
447
492
|
if (hops >= MAX_PROXY_HOPS) {
|
|
448
|
-
const
|
|
493
|
+
const host = getRequestHost(req).split(":")[0];
|
|
449
494
|
onError(
|
|
450
|
-
`WebSocket loop detected for ${
|
|
495
|
+
`WebSocket loop detected for ${host}: request has passed through portless ${hops} times. Set changeOrigin: true in your proxy config.`
|
|
451
496
|
);
|
|
452
497
|
socket.end(
|
|
453
498
|
"HTTP/1.1 508 Loop Detected\r\nContent-Type: text/plain\r\n\r\nLoop Detected: request has passed through portless too many times.\nAdd changeOrigin: true to your dev server proxy config.\n"
|
|
@@ -455,8 +500,7 @@ function createProxyServer(options) {
|
|
|
455
500
|
return;
|
|
456
501
|
}
|
|
457
502
|
const routes = getRoutes();
|
|
458
|
-
const
|
|
459
|
-
const route = findRoute(routes, host, strict);
|
|
503
|
+
const route = findRoute(routes, getRequestHost(req), strict);
|
|
460
504
|
if (!route) {
|
|
461
505
|
socket.destroy();
|
|
462
506
|
return;
|
|
@@ -476,8 +520,8 @@ function createProxyServer(options) {
|
|
|
476
520
|
proxyReqHeaders.host = getRequestHost(req);
|
|
477
521
|
}
|
|
478
522
|
const proxyReq = http.request({
|
|
479
|
-
|
|
480
|
-
|
|
523
|
+
// Dial via createLoopbackConnection so ::1-only backends work too.
|
|
524
|
+
createConnection: () => createLoopbackConnection(route.port),
|
|
481
525
|
path: req.url,
|
|
482
526
|
method: req.method,
|
|
483
527
|
headers: proxyReqHeaders
|
|
@@ -566,7 +610,7 @@ function createProxyServer(options) {
|
|
|
566
610
|
);
|
|
567
611
|
socket.destroy();
|
|
568
612
|
});
|
|
569
|
-
const wrapper =
|
|
613
|
+
const wrapper = net2.createServer((socket) => {
|
|
570
614
|
socket.on("error", () => {
|
|
571
615
|
socket.destroy();
|
|
572
616
|
});
|
|
@@ -694,9 +738,9 @@ function checkHostResolution(hostname) {
|
|
|
694
738
|
import * as fs3 from "fs";
|
|
695
739
|
import * as path2 from "path";
|
|
696
740
|
var STALE_LOCK_THRESHOLD_MS = 1e4;
|
|
697
|
-
var LOCK_TIMEOUT_MS =
|
|
741
|
+
var LOCK_TIMEOUT_MS = 15e3;
|
|
698
742
|
var LOCK_RETRY_BASE_MS = 10;
|
|
699
|
-
var LOCK_RETRY_CAP_MS =
|
|
743
|
+
var LOCK_RETRY_CAP_MS = 100;
|
|
700
744
|
var FILE_MODE = 420;
|
|
701
745
|
var DIR_MODE = 493;
|
|
702
746
|
function isValidRoute(value) {
|
|
@@ -989,12 +1033,14 @@ var RouteStore = class _RouteStore {
|
|
|
989
1033
|
};
|
|
990
1034
|
|
|
991
1035
|
export {
|
|
1036
|
+
createLoopbackConnection,
|
|
992
1037
|
fixOwnership,
|
|
993
1038
|
isErrnoException,
|
|
994
1039
|
isProcessAlive,
|
|
995
1040
|
escapeHtml,
|
|
996
1041
|
formatUrl,
|
|
997
1042
|
parseHostname,
|
|
1043
|
+
parseHostnames,
|
|
998
1044
|
PORTLESS_HEADER,
|
|
999
1045
|
createProxyServer,
|
|
1000
1046
|
createHttpRedirectServer,
|