index.ts 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. import "dotenv/config";
  2. import express from "express";
  3. import { createServer } from "http";
  4. import net from "net";
  5. import { createExpressMiddleware } from "@trpc/server/adapters/express";
  6. import { registerOAuthRoutes } from "./oauth";
  7. import { appRouter } from "../routers";
  8. import { createContext } from "./context";
  9. import { serveStatic, setupVite } from "./vite";
  10. function isPortAvailable(port: number): Promise<boolean> {
  11. return new Promise(resolve => {
  12. const server = net.createServer();
  13. server.listen(port, () => {
  14. server.close(() => resolve(true));
  15. });
  16. server.on("error", () => resolve(false));
  17. });
  18. }
  19. async function findAvailablePort(startPort: number = 3000): Promise<number> {
  20. for (let port = startPort; port < startPort + 20; port++) {
  21. if (await isPortAvailable(port)) {
  22. return port;
  23. }
  24. }
  25. throw new Error(`No available port found starting from ${startPort}`);
  26. }
  27. async function startServer() {
  28. const app = express();
  29. const server = createServer(app);
  30. // Trust Apache reverse proxy so req.protocol reflects HTTPS correctly
  31. app.set("trust proxy", 1);
  32. // Configure body parser with larger size limit for file uploads
  33. app.use(express.json({ limit: "50mb" }));
  34. app.use(express.urlencoded({ limit: "50mb", extended: true }));
  35. // OAuth callback under /api/oauth/callback
  36. registerOAuthRoutes(app);
  37. // tRPC API
  38. app.use(
  39. "/api/trpc",
  40. createExpressMiddleware({
  41. router: appRouter,
  42. createContext,
  43. })
  44. );
  45. // development mode uses Vite, production mode uses static files
  46. if (process.env.NODE_ENV === "development") {
  47. await setupVite(app, server);
  48. } else {
  49. serveStatic(app);
  50. }
  51. const preferredPort = parseInt(process.env.PORT || "3000");
  52. const port = await findAvailablePort(preferredPort);
  53. if (port !== preferredPort) {
  54. console.log(`Port ${preferredPort} is busy, using port ${port} instead`);
  55. }
  56. server.listen(port, () => {
  57. console.log(`Server running on http://localhost:${port}/`);
  58. });
  59. }
  60. startServer().catch(console.error);