import { z } from 'zod' const boolFromEnv = (v: string | undefined, fallback: boolean) => { if (v === undefined || v === '') return fallback return v === '1' || v.toLowerCase() === 'true' } export const configSchema = z.object({ databaseUrl: z.string().default('sqlite:data/app.db'), jwtSecret: z.string().min(8), jwtTtlHours: z.coerce.number().positive().default(1), refreshTtlDays: z.coerce.number().positive().default(14), issuer: z.string().url().default('https://auth.shnt.top'), adminEmail: z.string().email().default('admin@shnt.top'), adminPassword: z.string().default('admin'), adminName: z.string().default('Admin'), returnToAllowlist: z.string().default('.shnt.top,localhost,private'), serverPort: z.coerce.number().int().positive().default(8080), staticDir: z.string().optional(), logLevel: z.string().default('info'), isProd: z.boolean(), }) export type AppConfig = z.infer export function loadConfig(env: NodeJS.ProcessEnv = process.env): AppConfig { const isProd = env.NODE_ENV === 'production' const jwtSecret = env.JWT_SECRET ?? (isProd ? '' : 'dev-secret-change-me') return configSchema.parse({ databaseUrl: env.DATABASE_URL ?? 'sqlite:data/app.db', jwtSecret, jwtTtlHours: env.JWT_TTL_HOURS ?? 1, refreshTtlDays: env.REFRESH_TTL_DAYS ?? 14, issuer: env.ISSUER ?? 'https://auth.shnt.top', adminEmail: env.ADMIN_EMAIL ?? 'admin@shnt.top', adminPassword: env.ADMIN_PASSWORD ?? 'admin', adminName: env.ADMIN_NAME ?? 'Admin', returnToAllowlist: env.RETURN_TO_ALLOWLIST ?? '.shnt.top,localhost,private', serverPort: env.SERVER_PORT ?? 8080, staticDir: env.STATIC_DIR || undefined, logLevel: env.LOG_LEVEL ?? 'info', isProd: boolFromEnv(env.NODE_ENV === 'production' ? 'true' : undefined, false) || isProd, }) }