kozukata-toa/src/lib/setup/config.ts

67 lines
1.7 KiB
TypeScript

import dotenv from "dotenv";
import JSON5 from "json5";
import { z } from "zod";
import { fromZodError } from "zod-validation-error";
import fs from "fs";
dotenv.config();
const logger = console;
const confLocation = process.env.TOA_CONFIG ?? "./config.json5";
let configFile;
try {
configFile = fs.readFileSync(confLocation, "utf-8");
} catch (err) {
logger.error("Error while trying to open conf.json5. Is one present?", { err });
process.exit(1);
}
const config: unknown = JSON5.parse(configFile);
const zod16bitNumber = z.number().gt(0).lte(65535);
const zodLogLevel = z.enum(["crit", "debug", "error", "info", "verbose", "warn"]);
const zodOptionalHexString16 = z
.string()
.length(16)
.regex(/^[0-9a-z]+$/iu, "value is not a hex string")
.optional();
const configSchema = z.object({
NAME: z.string(),
DATABASE_PATH: z.string(),
LISTEN_ADDRESS: z.string().ip(),
LOGGER_CONFIG: z.object({
LOG_LEVEL: zodLogLevel,
CONSOLE: z.boolean(),
FOLDER: z.string().optional(),
}),
ALLNET_CONFIG: z.object({
ENABLED: z.boolean(),
PORT: zod16bitNumber,
ALLOW_UNREGISTERED_SERIALS: z.boolean(),
UPDATE_CFG_FOLDER: z.string().optional(),
}),
AIMEDB_CONFIG: z.object({
ENABLED: z.boolean(),
PORT: zod16bitNumber,
KEY: z.string().length(16).optional(),
AIME_MOBILE_CARD_KEY: zodOptionalHexString16,
RESERVED_CARD_PREFIX: z.string().length(5).optional(),
RESERVED_CARD_KEY: zodOptionalHexString16,
}),
});
const parseResult = configSchema.safeParse(config);
if (!parseResult.success) {
const humanFriendlyMessage = fromZodError(parseResult.error);
throw new Error(`Invalid config.json5 file: ${humanFriendlyMessage}`);
}
export const Config = parseResult.data;