-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.ts
More file actions
68 lines (58 loc) · 2.16 KB
/
server.ts
File metadata and controls
68 lines (58 loc) · 2.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
/**
* Custom Bun production server for TanStack Start.
*
* The built server.js only handles SSR and API routes — it does NOT serve
* static files. This wrapper intercepts requests and checks if the requested
* path exists in `dist/client` first. If it does, it serves the file directly.
* Otherwise it delegates to the TanStack Start handler.
*/
import { statSync } from "node:fs";
import { join } from "node:path";
// Import the TanStack Start server handler
// @ts-expect-error - This file is generated by the build and might not have types
import app from "./dist/server/server.js";
// Determine directory
const CLIENT_DIR = join(import.meta.dirname, "dist", "client");
const PORT = Number(process.env.PORT) || 3000;
/**
* Try to resolve a static file from dist/client.
* Returns the Bun File object if found, null otherwise.
*/
function resolveStaticFile(pathname: string): string | null {
// Prevent path traversal
const safePath = join(CLIENT_DIR, pathname);
if (!safePath.startsWith(CLIENT_DIR)) return null;
try {
const stat = statSync(safePath);
if (stat.isFile()) return safePath;
} catch {
// File not found, that's fine
}
return null;
}
const server = Bun.serve({
port: PORT,
hostname: "0.0.0.0", // Explicitly bind to all interfaces for Docker
async fetch(request: Request) {
const url = new URL(request.url);
// 1. Proxy PocketBase API and Dashboard requests
// This allows the app to work on a single port (3000)
if (url.pathname.startsWith("/api/") || url.pathname.startsWith("/_/")) {
const pbUrl = new URL(url.pathname + url.search, "http://127.0.0.1:8090");
return fetch(pbUrl, {
method: request.method,
headers: request.headers,
body: request.body,
redirect: "manual",
});
}
// 2. Try to serve static file from dist/client
const staticPath = resolveStaticFile(url.pathname);
if (staticPath) {
return new Response(Bun.file(staticPath));
}
// 3. Delegate to TanStack Start SSR handler
return (app as { fetch: (req: Request) => Promise<Response> }).fetch(request);
},
});
console.log(`Started server: http://0.0.0.0:${server.port}`);