2023-11-23 05:10:37 +01:00
|
|
|
import type { PrismaClientInitializationError } from "@prisma/client/runtime/library";
|
2023-12-02 00:00:00 +01:00
|
|
|
import { initializeRedisCache } from "@redis";
|
2023-12-03 05:11:30 +01:00
|
|
|
import { connectMeili } from "@meilisearch";
|
2024-03-11 03:04:14 +01:00
|
|
|
import { ConfigManager } from "config-manager";
|
|
|
|
|
import { client } from "~database/datasource";
|
|
|
|
|
import { LogLevel, LogManager, MultiLogManager } from "log-manager";
|
|
|
|
|
import { moduleIsEntry } from "@module";
|
|
|
|
|
import { createServer } from "~server";
|
2024-03-13 18:28:12 +01:00
|
|
|
import { exists, mkdir } from "fs/promises";
|
2023-11-23 00:04:31 +01:00
|
|
|
|
2023-11-30 05:16:58 +01:00
|
|
|
const timeAtStart = performance.now();
|
2023-09-11 05:54:14 +02:00
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
const configManager = new ConfigManager({});
|
|
|
|
|
const config = await configManager.getConfig();
|
2023-09-11 05:46:20 +02:00
|
|
|
|
2023-09-15 05:21:38 +02:00
|
|
|
const requests_log = Bun.file(process.cwd() + "/logs/requests.log");
|
2024-03-11 03:04:14 +01:00
|
|
|
const isEntry = moduleIsEntry(import.meta.url);
|
|
|
|
|
// If imported as a module, redirect logs to /dev/null to not pollute console (e.g. in tests)
|
|
|
|
|
const logger = new LogManager(isEntry ? requests_log : Bun.file(`/dev/null`));
|
|
|
|
|
const consoleLogger = new LogManager(
|
|
|
|
|
isEntry ? Bun.stdout : Bun.file(`/dev/null`)
|
|
|
|
|
);
|
|
|
|
|
const dualLogger = new MultiLogManager([logger, consoleLogger]);
|
2023-09-15 05:21:38 +02:00
|
|
|
|
2024-03-13 18:28:12 +01:00
|
|
|
if (!(await exists(process.cwd() + "/logs/"))) {
|
|
|
|
|
await consoleLogger.log(
|
|
|
|
|
LogLevel.WARNING,
|
|
|
|
|
"Lysand",
|
|
|
|
|
`Creating logs directory at ${process.cwd()}/logs/`
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await mkdir(process.cwd() + "/logs/");
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
await dualLogger.log(LogLevel.INFO, "Lysand", "Starting Lysand...");
|
2023-12-09 04:32:45 +01:00
|
|
|
|
2023-12-09 02:51:48 +01:00
|
|
|
// NODE_ENV seems to be broken and output `development` even when set to production, so use the flag instead
|
|
|
|
|
const isProd =
|
|
|
|
|
process.env.NODE_ENV === "production" || process.argv.includes("--prod");
|
|
|
|
|
|
2023-12-02 00:00:00 +01:00
|
|
|
const redisCache = await initializeRedisCache();
|
|
|
|
|
|
2023-12-03 05:11:30 +01:00
|
|
|
if (config.meilisearch.enabled) {
|
2024-03-11 03:04:14 +01:00
|
|
|
await connectMeili(dualLogger);
|
2023-12-03 05:11:30 +01:00
|
|
|
}
|
|
|
|
|
|
2023-12-02 00:00:00 +01:00
|
|
|
if (redisCache) {
|
|
|
|
|
client.$use(redisCache);
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-21 00:58:39 +01:00
|
|
|
// Check if database is reachable
|
2023-11-29 04:57:35 +01:00
|
|
|
let postCount = 0;
|
2023-11-21 00:58:39 +01:00
|
|
|
try {
|
2023-11-29 04:57:35 +01:00
|
|
|
postCount = await client.status.count();
|
2023-11-21 00:58:39 +01:00
|
|
|
} catch (e) {
|
|
|
|
|
const error = e as PrismaClientInitializationError;
|
2024-03-11 03:04:14 +01:00
|
|
|
await logger.logError(LogLevel.CRITICAL, "Database", error);
|
|
|
|
|
await consoleLogger.logError(LogLevel.CRITICAL, "Database", error);
|
2023-11-21 00:58:39 +01:00
|
|
|
process.exit(1);
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
const server = createServer(config, configManager, dualLogger, isProd);
|
2023-11-11 03:36:06 +01:00
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
await dualLogger.log(
|
|
|
|
|
LogLevel.INFO,
|
|
|
|
|
"Server",
|
|
|
|
|
`Lysand started at ${config.http.bind}:${config.http.bind_port} in ${(performance.now() - timeAtStart).toFixed(0)}ms`
|
2023-10-23 02:32:17 +02:00
|
|
|
);
|
2023-11-21 00:58:39 +01:00
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
await dualLogger.log(
|
|
|
|
|
LogLevel.INFO,
|
|
|
|
|
"Database",
|
|
|
|
|
`Database is online, now serving ${postCount} posts`
|
2023-11-21 00:58:39 +01:00
|
|
|
);
|
|
|
|
|
|
2024-03-11 03:04:14 +01:00
|
|
|
export { config, server };
|