first commit
This commit is contained in:
112
apps/server/src/index.ts
Normal file
112
apps/server/src/index.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import express from "express";
|
||||
import http from "node:http";
|
||||
import path from "node:path";
|
||||
import cookieParser from "cookie-parser";
|
||||
import cors from "cors";
|
||||
import { config, isDev } from "./config"
|
||||
import { ensureDataPaths } from "./storage/paths"
|
||||
import { initAuth } from "./auth/auth.service"
|
||||
import authRoutes from "./auth/auth.routes"
|
||||
import { requireAuth } from "./auth/auth.middleware"
|
||||
import qbitRoutes from "./qbit/qbit.routes"
|
||||
import torrentRoutes from "./torrent/torrent.routes"
|
||||
import loopRoutes from "./loop/loop.routes"
|
||||
import profilesRoutes from "./loop/profiles.routes"
|
||||
import statusRoutes from "./status/status.routes"
|
||||
import timerRoutes from "./timer/timer.routes"
|
||||
import { QbitClient } from "./qbit/qbit.client"
|
||||
import { detectCapabilities } from "./qbit/qbit.capabilities"
|
||||
import { setQbitClient, setQbitCapabilities } from "./qbit/qbit.context"
|
||||
import { setQbitStatus } from "./status/status.service"
|
||||
import { createSocketServer } from "./realtime/socket"
|
||||
import { initEmitter, emitQbitHealth } from "./realtime/emitter"
|
||||
import { startLoopScheduler } from "./loop/loop.scheduler"
|
||||
import { startEnforcementWorker } from "./enforcement/enforcement.worker"
|
||||
import { startTimerWorker } from "./timer/timer.worker"
|
||||
import { logger } from "./utils/logger"
|
||||
|
||||
process.on("unhandledRejection", (reason) => {
|
||||
logger.error({ reason }, "Unhandled promise rejection");
|
||||
});
|
||||
|
||||
process.on("uncaughtException", (error) => {
|
||||
logger.error({ error }, "Uncaught exception");
|
||||
});
|
||||
|
||||
let serverStarted = false;
|
||||
|
||||
const bootstrap = async () => {
|
||||
await ensureDataPaths();
|
||||
await initAuth();
|
||||
|
||||
const app = express();
|
||||
app.use(cookieParser());
|
||||
app.use(express.json());
|
||||
|
||||
if (isDev) {
|
||||
const fallbackOrigin = `http://localhost:${config.webPort}`;
|
||||
const origins = [config.webOrigin || fallbackOrigin, fallbackOrigin];
|
||||
app.use(
|
||||
cors({
|
||||
origin: origins,
|
||||
credentials: true,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
app.use("/api/auth", authRoutes);
|
||||
app.use("/api/qbit", requireAuth, qbitRoutes);
|
||||
app.use("/api/torrent", requireAuth, torrentRoutes);
|
||||
app.use("/api/loop", requireAuth, loopRoutes);
|
||||
app.use("/api/profiles", requireAuth, profilesRoutes);
|
||||
app.use("/api/status", requireAuth, statusRoutes);
|
||||
app.use("/api/timer", requireAuth, timerRoutes);
|
||||
|
||||
if (!isDev) {
|
||||
app.use(express.static(config.webPublicDir));
|
||||
app.get("*", (req, res, next) => {
|
||||
if (req.path.startsWith("/api")) {
|
||||
return next();
|
||||
}
|
||||
return res.sendFile(path.join(config.webPublicDir, "index.html"));
|
||||
});
|
||||
}
|
||||
|
||||
const server = http.createServer(app);
|
||||
const io = createSocketServer(server);
|
||||
initEmitter(io);
|
||||
|
||||
const qbit = new QbitClient();
|
||||
setQbitClient(qbit);
|
||||
|
||||
try {
|
||||
const caps = await detectCapabilities(qbit);
|
||||
setQbitCapabilities(caps);
|
||||
setQbitStatus({ ok: true, version: caps.version, capabilities: caps });
|
||||
emitQbitHealth({ ok: true, version: caps.version, capabilities: caps });
|
||||
} catch (error) {
|
||||
logger.error({ error }, "Failed to connect to qBittorrent");
|
||||
setQbitStatus({ ok: false, lastError: (error as Error).message });
|
||||
emitQbitHealth({ ok: false, lastError: (error as Error).message });
|
||||
}
|
||||
|
||||
startLoopScheduler(qbit, config.pollIntervalMs);
|
||||
startEnforcementWorker(config.enforceIntervalMs);
|
||||
startTimerWorker(qbit, config.timerPollMs);
|
||||
|
||||
server.listen(config.port, () => {
|
||||
serverStarted = true;
|
||||
logger.info(`q-buffer server listening on ${config.port}`);
|
||||
});
|
||||
};
|
||||
|
||||
const startWithRetry = () => {
|
||||
bootstrap().catch((error) => {
|
||||
logger.error({ error }, "Failed to start server");
|
||||
if (!serverStarted) {
|
||||
setTimeout(startWithRetry, 5000);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
startWithRetry();
|
||||
Reference in New Issue
Block a user