// Всё окружение api читается здесь. Telegram-переменные необязательны: без них api // принимает заявки, а отправки копятся в pending до настройки. import { DEFAULT_DB_PATH } from './db/index.js'; export type TelegramConfig = { token?: string; /** id группы, у супергрупп отрицательный: -100… */ chatId?: number; leadsThreadId?: number; systemThreadId?: number; adminId?: number; }; export type Config = { port: number; dbPath: string; version: string; trustedProxies: string[]; telegram: TelegramConfig; }; type Env = Record; function optional(env: Env, name: string): string | undefined { const value = env[name]?.trim(); return value ? value : undefined; } function optionalInt(env: Env, name: string): number | undefined { const raw = optional(env, name); if (raw === undefined) return undefined; if (!/^-?\d+$/.test(raw) || !Number.isSafeInteger(Number(raw))) { throw new Error(`${name}: ожидается целое число`); } return Number(raw); } export function loadConfig(env: Env = process.env): Config { const port = optionalInt(env, 'PORT') ?? 3001; const token = optional(env, 'TELEGRAM_BOT_TOKEN'); // Значение токена в текст ошибки не попадает — только факт, что формат не тот. if (token !== undefined && !/^\d+:[\w-]+$/.test(token)) throw new Error('TELEGRAM_BOT_TOKEN: неверный формат'); return { port, dbPath: optional(env, 'DB_PATH') ?? DEFAULT_DB_PATH, version: optional(env, 'APP_VERSION') ?? 'dev', trustedProxies: (optional(env, 'TRUSTED_PROXIES') ?? '') .split(',') .map((s) => s.trim()) .filter(Boolean), telegram: { token, chatId: optionalInt(env, 'TELEGRAM_CHAT_ID'), leadsThreadId: optionalInt(env, 'TELEGRAM_LEADS_THREAD_ID'), systemThreadId: optionalInt(env, 'TELEGRAM_SYSTEM_THREAD_ID'), adminId: optionalInt(env, 'TELEGRAM_ADMIN_ID'), }, }; }