process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; import {serve} from "@hono/node-server"; import {OpenAPIHono} from "@hono/zod-openapi"; import {proxy} from "hono/proxy"; import {serveStatic} from "@hono/node-server/serve-static"; import {logger} from "hono/logger"; import {cors} from "hono/cors"; import {createLog} from "./services/logger/logger.js"; // custom routes import scalar from "./services/general/route/scalar.js"; import system from "./services/server/systemServer.js"; import auth from "./services/auth/authService.js"; import tcpServer from "./services/tcpServer/tcpServer.js"; import ocme from "./services/ocme/ocmeService.js"; import sqlService from "./services/sqlServer/sqlService.js"; import logistics from "./services/logistics/logisticsService.js"; import rfid from "./services/rfid/rfidService.js"; import printers from "./services/printers/printerService.js"; import loggerService from "./services/logger/loggerService.js"; import ocpService from "./services/ocp/ocpService.js"; import {db} from "../database/dbclient.js"; import {settings} from "../database/schema/settings.js"; import {count, eq} from "drizzle-orm"; // create the main prodlogin here const username = "lst_user"; const password = "Alpla$$Prod"; export const lstAuth = btoa(`${username}:${password}`); // checking to make sure we have the settings intialized const serverIntialized = await db.select({count: count()}).from(settings); export const installed = serverIntialized[0].count === 0 && process.env.NODE_ENV !== "development" ? false : true; createLog("info", "LST", "server", `Server is installed: ${installed}`); const app = new OpenAPIHono({strict: false}); // middle ware app.use("*", logger()); app.use( "*", cors({ origin: "*", // Allow all origins allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"], allowMethods: ["GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"], exposeHeaders: ["Content-Length", "X-Kuma-Revision"], credentials: true, // Allow credentials if needed maxAge: 600, }) ); // Middleware to normalize route case app.use("*", async (c, next) => { const lowercasedUrl = c.req.url.toLowerCase(); //console.log("Incoming Request:", c.req.url, c.req.method); // If the URL is already lowercase, continue as usual if (c.req.url === lowercasedUrl) { return next(); } // Otherwise, re-route internally return c.redirect(lowercasedUrl, 308); // 308 preserves the HTTP method }); app.doc("/api/ref", { openapi: "3.0.0", info: { version: "2.0.0", title: "LST API", }, }); const routes = [ scalar, auth, // apiHits, system, tcpServer, sqlService, logistics, rfid, printers, loggerService, ocpService, ] as const; const appRoutes = routes.forEach((route) => { app.route("/api/", route); }); app.route("/ocme/*", ocme); //--------------- lst v1 proxy ----------------------\\ app.all("/api/v1/*", (c) => { const path = c.req.path.replace("/api/v1/", ""); // Extract the subpath const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params return proxy(`http://localhost:4900/${path}${query}`, { headers: { ...c.req.header(), "X-Forwarded-For": "127.0.0.1", "X-Forwarded-Host": c.req.header("host"), }, }); }); app.all("/system/*", (c) => { const path = c.req.path.replace("/system/", ""); // Extract the subpath const query = c.req.query() ? "?" + new URLSearchParams(c.req.query()).toString() : ""; // Get query params return proxy(`http://localhost:4200/${path}${query}`, { headers: { ...c.req.header(), "X-Forwarded-For": "127.0.0.1", "X-Forwarded-Host": c.req.header("host"), }, }); }); //---------------------------------------------------\\ // the catch all api route app.all("/api/*", (c) => c.json({error: "API route not found"}, 404)); // front end static files app.use("/*", serveStatic({root: "./frontend/dist"})); app.use("*", serveStatic({path: "./frontend/dist/index.html"})); // Handle app exit signals process.on("SIGINT", async () => { console.log("\nGracefully shutting down..."); //await closePool(); process.exit(0); }); process.on("SIGTERM", async () => { console.log("Received termination signal, closing database..."); //await closePool(); process.exit(0); }); process.on("uncaughtException", async (err) => { console.log("Uncaught Exception:", err); //await closePool(); process.exit(1); }); process.on("beforeExit", async () => { console.log("Process is about to exit..."); //await closePool(); }); const port = process.env.NODE_ENV === "development" ? process.env.VITE_SERVER_PORT : process.env.PROD_PORT; serve( { fetch: app.fetch, port: Number(port), hostname: "0.0.0.0", }, (info) => { createLog("info", "LST", "server", `Server is running on http://${info.address}:${info.port}`); } ); export type AppRoutes = typeof appRoutes;