generated from Dicken/dickendock
99 lines
3.4 KiB
TypeScript
99 lines
3.4 KiB
TypeScript
import "./env.js";
|
|
import Fastify from "fastify";
|
|
import cors from "@fastify/cors";
|
|
import { ensureSchema } from "./db/client.js";
|
|
import { healthRoutes } from "./routes/health.js";
|
|
import { deviceRoutes } from "./routes/devices.js";
|
|
import { serviceRoutes } from "./routes/services.js";
|
|
import { categoryRoutes } from "./routes/categories.js";
|
|
import { scanRoutes } from "./routes/scan.js";
|
|
import { logRoutes } from "./routes/logs.js";
|
|
import { pluginRoutes } from "./routes/plugins.js";
|
|
import { resetRoutes } from "./routes/reset.js";
|
|
import { transferRoutes } from "./routes/transfer.js";
|
|
import { bookmarkRoutes } from "./routes/bookmarks.js";
|
|
import { recentVisitsRoutes } from "./routes/recentVisits.js";
|
|
import { settingsRoutes } from "./routes/settings.js";
|
|
import { readLaterRoutes } from "./routes/readLater.js";
|
|
import { faviconProxyRoutes } from "./routes/faviconProxy.js";
|
|
import { iconsRoutes } from "./routes/icons.js";
|
|
import { apiRoutes } from "./routes/apis.js";
|
|
import { loadPlugins } from "./plugins/loader.js";
|
|
import { startLiveStatusHeartbeat } from "./liveStatus.js";
|
|
import * as serviceRepo from "./db/repositories/services.js";
|
|
import * as bookmarkRepo from "./db/repositories/bookmarks.js";
|
|
import * as categoryRepo from "./db/repositories/categories.js";
|
|
|
|
const PORT = Number(process.env.PORT ?? 3001);
|
|
const HOST = process.env.HOST ?? "0.0.0.0";
|
|
|
|
async function main() {
|
|
const app = Fastify({
|
|
logger: {
|
|
level: process.env.LOG_LEVEL ?? "info",
|
|
transport:
|
|
process.env.NODE_ENV !== "production"
|
|
? { target: "pino-pretty", options: { colorize: true } }
|
|
: undefined,
|
|
},
|
|
});
|
|
|
|
await app.register(cors, {
|
|
origin: process.env.CORS_ORIGIN ?? true,
|
|
});
|
|
|
|
ensureSchema();
|
|
|
|
// Kategorien, die bereits auf Diensten stehen (z. B. aus Scans vor diesem
|
|
// Fix, oder von Plugins), aber noch nicht in der categories-Tabelle sind,
|
|
// hier nachtragen. Damit zeigt Admin -> Kategorien immer das, was auch in
|
|
// der Suche als Kategorie auftaucht.
|
|
const existingCategoryNames = Array.from(
|
|
new Set(
|
|
[
|
|
...serviceRepo.listServices().map((s) => s.category),
|
|
...bookmarkRepo.listBookmarks().map((b) => b.category),
|
|
].filter((c): c is string => !!c)
|
|
)
|
|
);
|
|
const syncedCount = categoryRepo.syncCategoriesFromServiceValues(existingCategoryNames);
|
|
if (syncedCount > 0) {
|
|
app.log.info(`${syncedCount} Kategorie(n) aus bestehenden Diensten nachgetragen`);
|
|
}
|
|
|
|
const plugins = await loadPlugins();
|
|
app.log.info(`${plugins.length} Plugin(s) geladen`);
|
|
|
|
await app.register(healthRoutes);
|
|
await app.register(deviceRoutes);
|
|
await app.register(serviceRoutes);
|
|
await app.register(categoryRoutes);
|
|
await app.register(scanRoutes);
|
|
await app.register(logRoutes);
|
|
await app.register(pluginRoutes);
|
|
await app.register(resetRoutes);
|
|
await app.register(transferRoutes);
|
|
await app.register(bookmarkRoutes);
|
|
await app.register(recentVisitsRoutes);
|
|
await app.register(settingsRoutes);
|
|
await app.register(readLaterRoutes);
|
|
await app.register(faviconProxyRoutes);
|
|
await app.register(iconsRoutes);
|
|
await app.register(apiRoutes);
|
|
|
|
app.get("/", async () => {
|
|
return { name: "LaunchPad API", status: "running" };
|
|
});
|
|
|
|
try {
|
|
await app.listen({ port: PORT, host: HOST });
|
|
app.log.info(`LaunchPad backend läuft auf http://${HOST}:${PORT}`);
|
|
startLiveStatusHeartbeat();
|
|
} catch (err) {
|
|
app.log.error(err);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|