Files
sunrise/server/config.ts
T

34 lines
1.6 KiB
TypeScript

import { readFileSync } from 'node:fs';
export type ServerConfig = {
host: string;
port: number;
mongoUri: string;
mongoDatabase: string;
visitStore: 'mongo' | 'memory';
allowedOrigins: string[];
};
export function loadServerConfig(path: string | URL = new URL('../.config.json', import.meta.url)): ServerConfig {
let contents: string;
try { contents = readFileSync(path, 'utf8'); }
catch { throw new Error('Cannot read .config.json; copy .config.example.json to .config.json and configure the server.'); }
let value: unknown;
try { value = JSON.parse(contents); }
catch { throw new Error('Invalid JSON in .config.json'); }
if (!value || typeof value !== 'object' || Array.isArray(value)) throw new Error('Invalid .config.json: expected an object');
const config = value as Record<string, unknown>;
const nonempty = (value: unknown): value is string => typeof value === 'string' && value.trim().length > 0;
for (const field of ['host', 'mongoUri', 'mongoDatabase']) {
if (!nonempty(config[field])) throw new Error(`Invalid .config.json field: ${field}`);
}
if (typeof config.port !== 'number' || !Number.isInteger(config.port) || config.port < 0 || config.port > 65535) {
throw new Error('Invalid .config.json field: port');
}
if (config.visitStore !== 'mongo' && config.visitStore !== 'memory') throw new Error('Invalid .config.json field: visitStore');
if (!Array.isArray(config.allowedOrigins) || !config.allowedOrigins.length || !config.allowedOrigins.every(nonempty)) {
throw new Error('Invalid .config.json field: allowedOrigins');
}
return config as ServerConfig;
}