mic-bot/cfg/config.ts

127 lines
4.0 KiB
TypeScript
Raw Normal View History

2024-10-24 08:35:13 +00:00
import type * as pg from "npm:pg";
2024-10-19 10:00:35 +00:00
import { strToBool } from "../utils/convert.ts";
import { BadConfigErr } from "../utils/errors.ts";
import { readJsonFileSync } from "../utils/io.ts";
2024-10-24 08:35:13 +00:00
import * as path from "jsr:@std/path";
2024-10-19 10:00:35 +00:00
2024-10-24 08:35:13 +00:00
export const POSTGRES_PASSWORD = "POSTGRES_PASSWORD"
2024-10-19 10:00:35 +00:00
export const MIC_APPLY_MIGRATIONS = "MIC_APPLY_MIGRATIONS"
2024-10-24 08:35:13 +00:00
export const DEFAULT_CONFIG_FILE_PATH = import.meta.dirname ? path.join(import.meta.dirname, '../config.json') : '/app/config.json'
2024-10-19 10:00:35 +00:00
export const MIC_DROP_DB = "MIC_DROP_DB"
export const BOT_TOKEN = "BOT_TOKEN"
export const MIC_CONFIG_PATH = "MIC_CONFIG_PATH"
2024-10-24 08:35:13 +00:00
export enum BotMode{ setup, normal }
export type BotConfig = {
mode: BotMode,
bot_token: string,
chat_id: number,
admin_ids: number[],
locales_dir: string
2024-10-24 08:35:13 +00:00
}
2024-10-19 10:00:35 +00:00
export interface EnvConfig {
db_password?: string,
bot_token?: string,
mic_config_path?: string,
mic_apply_migrations: boolean,
mic_drop_db: boolean,
}
export interface FileConfig {
db_user?: string,
db_name?: string,
db_port?: number,
db_host?: string,
db_tls?: boolean,
db_password_file?: string,
bot_token?: string,
}
export interface Config {
db_user?: string,
db_name?: string,
db_port?: number,
db_host?: string,
db_tls?: boolean,
db_password: string,
bot_token: string,
config_path: string,
apply_migrations: boolean,
drop_db: boolean,
}
export interface MigrationConfig {
dropDb: boolean
applyMigrations: boolean
migrationsPath: string
}
export interface CompiledConfig {
2024-10-24 08:35:13 +00:00
pgPoolCfg: pg.PoolConfig
2024-10-19 10:00:35 +00:00
botCfg: BotConfig
migrationCfg?: MigrationConfig
}
export const getEnvConfig = (): EnvConfig => {
const apply_migrations =
strToBool(Deno.env.get(MIC_APPLY_MIGRATIONS) || "n") || false
if (apply_migrations) Deno.env.set(MIC_APPLY_MIGRATIONS, "n")
const drop_db = strToBool(Deno.env.get(MIC_DROP_DB) || "n") || false
if (drop_db) Deno.env.set(MIC_DROP_DB, "n")
return {
db_password: Deno.env.get(POSTGRES_PASSWORD),
bot_token: Deno.env.get(BOT_TOKEN),
mic_config_path: Deno.env.get(MIC_CONFIG_PATH),
mic_apply_migrations: apply_migrations,
mic_drop_db: drop_db,
}
}
export const getConfig = (): Config => {
const envCfg = getEnvConfig()
const config_path = envCfg.mic_config_path || DEFAULT_CONFIG_FILE_PATH
const fileCfg = readJsonFileSync<FileConfig>(config_path)
let db_password: string;
if (fileCfg.db_password_file) {
const decoder = new TextDecoder("utf-8")
const data = Deno.readFileSync(fileCfg.db_password_file)
2024-10-24 08:35:13 +00:00
db_password = decoder.decode(data).toString()
2024-10-24 14:39:42 +00:00
if (db_password[db_password.length - 1] === '\n') {
db_password = db_password.slice(0, -1)
}
2024-10-19 10:00:35 +00:00
} else if (envCfg.db_password) {
db_password = envCfg.db_password
} else throw new BadConfigErr(
"Expected db_password_file to be set in the config "+
"or the POSTGRES_PASSWORD environment variable, "+
"but bot both are undefined. "+
"Check the Config section in README.md"
)
const bot_token: string | undefined = envCfg.bot_token || fileCfg.bot_token
if (!bot_token) throw new BadConfigErr(
"Expected bot_token to be set in the config "+
"or at the BOT_TOKEN environment variable, "+
"but bot token is undefined. "+
"Check the Config section in README.md"
)
return {
db_host: fileCfg.db_host,
db_user: fileCfg.db_user,
db_name: fileCfg.db_name,
db_port: fileCfg.db_port,
db_tls: fileCfg.db_tls,
db_password,
config_path,
apply_migrations: envCfg.mic_apply_migrations,
drop_db: envCfg.mic_drop_db,
bot_token,
}
2024-10-24 14:39:42 +00:00
}