130 lines
3.7 KiB
JavaScript
130 lines
3.7 KiB
JavaScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const DEFAULT_CONFIG = {
|
|
SERVER_HOST: "0.0.0.0",
|
|
SERVER_PORT: 9736,
|
|
MONGODB_HOST: "",
|
|
MONGODB_PORT: 27017,
|
|
MONGODB_DB: "arena",
|
|
MONGODB_USER: "",
|
|
MONGODB_PASS: "",
|
|
MONGODB_URI: "",
|
|
MONGODB_VISITOR_COLLECTION: "visitors",
|
|
MONGODB_MAX_POOL_SIZE: 10,
|
|
MONGODB_SERVER_SELECTION_TIMEOUT_MS: 5000,
|
|
COOKIE_SECURE: false,
|
|
};
|
|
|
|
let config;
|
|
|
|
export function getConfig() {
|
|
if (!config) {
|
|
config = loadConfig();
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
export function loadConfig(filePath = path.resolve(process.cwd(), "config.json")) {
|
|
const rawConfig = fs.existsSync(filePath)
|
|
? JSON.parse(fs.readFileSync(filePath, "utf8"))
|
|
: {};
|
|
|
|
return normalizeConfig(rawConfig);
|
|
}
|
|
|
|
export function hasMongoConfig() {
|
|
const appConfig = getConfig();
|
|
return Boolean(appConfig.MONGODB_URI || appConfig.MONGODB_HOST);
|
|
}
|
|
|
|
export function getMongoUri() {
|
|
const appConfig = getConfig();
|
|
|
|
if (appConfig.MONGODB_URI) {
|
|
return appConfig.MONGODB_URI;
|
|
}
|
|
|
|
if (!appConfig.MONGODB_HOST) {
|
|
throw new Error("MongoDB configuration is required for visitor tracking.");
|
|
}
|
|
|
|
const host = appConfig.MONGODB_HOST;
|
|
const port = Number(appConfig.MONGODB_PORT || DEFAULT_CONFIG.MONGODB_PORT);
|
|
const credentials = mongoCredentials(appConfig);
|
|
|
|
return `mongodb://${credentials}${host}:${port}`;
|
|
}
|
|
|
|
function normalizeConfig(rawConfig) {
|
|
const server = rawConfig.server || {};
|
|
const mongodb = rawConfig.mongodb || {};
|
|
|
|
return {
|
|
SERVER_HOST: stringValue(rawConfig.SERVER_HOST, server.host, DEFAULT_CONFIG.SERVER_HOST),
|
|
SERVER_PORT: numberValue(rawConfig.SERVER_PORT, server.port, DEFAULT_CONFIG.SERVER_PORT),
|
|
MONGODB_HOST: stringValue(rawConfig.MONGODB_HOST, mongodb.host, DEFAULT_CONFIG.MONGODB_HOST),
|
|
MONGODB_PORT: numberValue(rawConfig.MONGODB_PORT, mongodb.port, DEFAULT_CONFIG.MONGODB_PORT),
|
|
MONGODB_DB: stringValue(rawConfig.MONGODB_DB, mongodb.db, DEFAULT_CONFIG.MONGODB_DB),
|
|
MONGODB_USER: stringValue(rawConfig.MONGODB_USER, mongodb.user, DEFAULT_CONFIG.MONGODB_USER),
|
|
MONGODB_PASS: stringValue(rawConfig.MONGODB_PASS, mongodb.pass, DEFAULT_CONFIG.MONGODB_PASS),
|
|
MONGODB_URI: stringValue(rawConfig.MONGODB_URI, mongodb.uri, DEFAULT_CONFIG.MONGODB_URI),
|
|
MONGODB_VISITOR_COLLECTION: stringValue(
|
|
rawConfig.MONGODB_VISITOR_COLLECTION,
|
|
mongodb.visitorCollection,
|
|
DEFAULT_CONFIG.MONGODB_VISITOR_COLLECTION,
|
|
),
|
|
MONGODB_MAX_POOL_SIZE: numberValue(
|
|
rawConfig.MONGODB_MAX_POOL_SIZE,
|
|
mongodb.maxPoolSize,
|
|
DEFAULT_CONFIG.MONGODB_MAX_POOL_SIZE,
|
|
),
|
|
MONGODB_SERVER_SELECTION_TIMEOUT_MS: numberValue(
|
|
rawConfig.MONGODB_SERVER_SELECTION_TIMEOUT_MS,
|
|
mongodb.serverSelectionTimeoutMs,
|
|
DEFAULT_CONFIG.MONGODB_SERVER_SELECTION_TIMEOUT_MS,
|
|
),
|
|
COOKIE_SECURE: booleanValue(rawConfig.COOKIE_SECURE, server.cookieSecure, DEFAULT_CONFIG.COOKIE_SECURE),
|
|
};
|
|
}
|
|
|
|
function mongoCredentials(appConfig) {
|
|
if (!appConfig.MONGODB_USER) {
|
|
return "";
|
|
}
|
|
|
|
const user = encodeURIComponent(appConfig.MONGODB_USER);
|
|
const pass = encodeURIComponent(appConfig.MONGODB_PASS || "");
|
|
|
|
return `${user}:${pass}@`;
|
|
}
|
|
|
|
function stringValue(...values) {
|
|
const value = values.find((candidate) => typeof candidate === "string" && candidate.length > 0);
|
|
return value ?? "";
|
|
}
|
|
|
|
function numberValue(...values) {
|
|
const value = values.find((candidate) => {
|
|
const numericValue = Number(candidate);
|
|
return Number.isFinite(numericValue) && numericValue > 0;
|
|
});
|
|
|
|
return Number(value);
|
|
}
|
|
|
|
function booleanValue(...values) {
|
|
const value = values.find((candidate) => typeof candidate === "boolean" || candidate === "true" || candidate === "false");
|
|
|
|
if (value === "true") {
|
|
return true;
|
|
}
|
|
|
|
if (value === "false") {
|
|
return false;
|
|
}
|
|
|
|
return Boolean(value);
|
|
}
|