mirror of
https://github.com/infrost/RaptorQR.git
synced 2026-08-31 15:07:50 +08:00
Fix --serve: strip Vite base path, add --port/--host flags
This commit is contained in:
@@ -49,10 +49,12 @@ The terminal clears, enters an alternate screen buffer, and displays the QR fram
|
||||
### Start the web app preview server
|
||||
|
||||
```bash
|
||||
qr-stream --serve
|
||||
qr-stream --serve start web app preview server
|
||||
qr-stream --serve --port 8080 custom port
|
||||
qr-stream --serve --host 127.0.0.1 localhost only
|
||||
```
|
||||
|
||||
Serves the built web UI on `http://localhost:3000` (default). Change the port with the `PORT` environment variable:
|
||||
Serves the built web UI. Defaults to port 3000 and binds `0.0.0.0`. Change the port with the `--port` flag or `PORT` environment variable:
|
||||
|
||||
```bash
|
||||
PORT=8080 qr-stream --serve
|
||||
@@ -64,8 +66,10 @@ The server resolves the `dist/` directory automatically, so it works from both t
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `-h`, `--help` | Show usage information |
|
||||
| `-s`, `--serve` | Start the web preview server |
|
||||
| `-h`, `--help` | Show usage information |
|
||||
| `-s`, `--serve` | Start the web preview server |
|
||||
| `--port <n>` | TCP port for --serve (default: 3000, also: PORT env) |
|
||||
| `--host <ip>` | Bind address for --serve (default: 0.0.0.0) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
+30
-2
@@ -32,6 +32,9 @@ import {
|
||||
} from './terminal_raster';
|
||||
import { startServer } from './static_server';
|
||||
|
||||
/** Must match the `base` in vite.config.ts — assets are baked with this prefix. */
|
||||
const VITE_BASE = '/hermes-web-demos/qr-transfer/';
|
||||
|
||||
const FPS_MS = 100;
|
||||
|
||||
// ─────────────────────────────────────────────────────────────────────────────────
|
||||
@@ -48,6 +51,10 @@ Usage:
|
||||
bunx qr-stream [file] via bunx
|
||||
qr-stream --serve start web app preview server
|
||||
|
||||
Server flags (with --serve):
|
||||
--port <n> TCP port (default: 3000, also: PORT env)
|
||||
--host <ip> Bind address (default: 0.0.0.0)
|
||||
|
||||
Controls:
|
||||
q, Q quit
|
||||
Ctrl-C quit
|
||||
@@ -163,8 +170,29 @@ function main() {
|
||||
}
|
||||
|
||||
if (args.includes('--serve') || args.includes('-s')) {
|
||||
const port = Number(process.env.PORT) || 3000;
|
||||
const server = startServer(port);
|
||||
// Parse --port <n> (default 3000)
|
||||
let port = 3000;
|
||||
const portIdx = args.indexOf('--port');
|
||||
if (portIdx !== -1 && portIdx + 1 < args.length) {
|
||||
port = Number(args[portIdx + 1]);
|
||||
if (isNaN(port) || port < 1 || port > 65535) {
|
||||
console.error('Error: --port must be a number between 1 and 65535');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
// Also support PORT env var (overridable by --port)
|
||||
if (process.env.PORT && args.indexOf('--port') === -1) {
|
||||
port = Number(process.env.PORT);
|
||||
}
|
||||
|
||||
// Parse --host <ip> (default 0.0.0.0)
|
||||
let host: string | undefined;
|
||||
const hostIdx = args.indexOf('--host');
|
||||
if (hostIdx !== -1 && hostIdx + 1 < args.length) {
|
||||
host = args[hostIdx + 1];
|
||||
}
|
||||
|
||||
const server = startServer(port, host, VITE_BASE);
|
||||
|
||||
function shutdown() {
|
||||
console.log('\nShutting down server...');
|
||||
|
||||
@@ -45,8 +45,24 @@ function findWebRoot(): string {
|
||||
);
|
||||
}
|
||||
|
||||
export function startServer(port: number): Server {
|
||||
/**
|
||||
* Create a static HTTP server for the built web app.
|
||||
*
|
||||
* @param port TCP port to listen on
|
||||
* @param host Host address to bind to (default: '0.0.0.0')
|
||||
* @param base URL path prefix baked into the assets (e.g. '/my-subpath/'), or empty for root
|
||||
*/
|
||||
export function startServer(
|
||||
port: number,
|
||||
host?: string,
|
||||
base?: string,
|
||||
): Server {
|
||||
const root = findWebRoot();
|
||||
const basePath = base || '';
|
||||
// Normalise: ensure base starts with / and does not end with /
|
||||
const normalisedBase = basePath
|
||||
? '/' + basePath.replace(/^\/+|\/+$/g, '')
|
||||
: '';
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
let pathname = req.url ?? '/';
|
||||
@@ -54,8 +70,16 @@ export function startServer(port: number): Server {
|
||||
const qIdx = pathname.indexOf('?');
|
||||
if (qIdx !== -1) pathname = pathname.slice(0, qIdx);
|
||||
|
||||
// Strip base prefix if present (so /base/assets/foo.js → /assets/foo.js)
|
||||
let resolved = pathname;
|
||||
if (normalisedBase && pathname.startsWith(normalisedBase + '/')) {
|
||||
resolved = pathname.slice(normalisedBase.length);
|
||||
} else if (normalisedBase === pathname) {
|
||||
resolved = '/';
|
||||
}
|
||||
|
||||
// Security: prevent directory traversal
|
||||
const safePath = pathname.replace(/\.{2,}/g, '');
|
||||
const safePath = resolved.replace(/\.{2,}/g, '');
|
||||
let filePath = join(root, safePath);
|
||||
|
||||
if (!existsSync(filePath) || !filePath.startsWith(root)) {
|
||||
@@ -92,8 +116,9 @@ export function startServer(port: number): Server {
|
||||
res.end(content);
|
||||
});
|
||||
|
||||
server.listen(port, () => {
|
||||
console.log(`QR Stream web app serving at http://localhost:${port}`);
|
||||
server.listen(port, host ?? '0.0.0.0', () => {
|
||||
const addr = host ?? '0.0.0.0';
|
||||
console.log(`QR Stream web app serving at http://${addr}:${port}`);
|
||||
});
|
||||
|
||||
return server;
|
||||
|
||||
Reference in New Issue
Block a user