process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"; import { serve } from "@hono/node-server"; import { OpenAPIHono } from "@hono/zod-openapi"; 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 os from "os"; import { tryCatch } from "./globalUtils/tryCatch.js"; import { sendEmail } from "./services/notifications/controller/sendMail.js"; import notify from "./services/notifications/notifyService.js"; import eom from "./services/eom/eomService.js"; import dataMart from "./services/dataMart/dataMartService.js"; // 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 { data: settingsData, error: settingError } = await tryCatch( db.select().from(settings) ); if (settingError) { throw Error("Error getting settings from the db. critical error."); } const serverIntialized: any = settingsData; export const installed = serverIntialized.length === 0 && process.env.NODE_ENV !== "development" ? false : true; createLog("info", "LST", "server", `Server is installed: ${installed}`); const app = new OpenAPIHono({ strict: false }); // middle ware if (process.env.NODE_ENV === "development") { 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) { // await 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, notify, eom, dataMart, ] 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(); const emailData = { email: "blake.matthes@alpla.com", // should be moved to the db so it can be reused. subject: `${os.hostname()} has just encountered a crash.`, template: "serverCrash", context: { error: err, plant: `${os.hostname()}`, }, }; await sendEmail(emailData); //process.exit(1); }); process.on("beforeExit", async () => { console.log("Process is about to exit..."); //await closePool(); process.exit(0); }); 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;