import path from "node:path"; import fs from "node:fs"; import { fileURLToPath } from "node:url"; const here = path.dirname(fileURLToPath(import.meta.url)); const rootDir = path.resolve(here, "..", ".."); export interface AppConfig { port: number; host: string; dataDir: string; mediaDir: string; originalsDir: string; derivedDir: string; dbPath: string; sessionSecret: string | null; runcomfyApiKey: string | null; runcomfyBaseUrl: string; runcomfyModelId: string; groqApiKey: string | null; groqModel: string; groqTunerModel: string; groqBaseUrl: string; baseApiToken: string | null; baseApiUrl: string; env: "development" | "test" | "production"; maxUploadBytes: number; } export function loadConfig(overrides: Partial = {}): AppConfig { const envFile = path.join(rootDir, ".env"); const testing = overrides.env === "test" || process.env.VILMAL_ENV === "test" || process.env.NODE_ENV === "test"; if (!testing && fs.existsSync(envFile)) process.loadEnvFile(envFile); const env = (process.env.VILMAL_ENV ?? process.env.NODE_ENV ?? "development") as AppConfig["env"]; const dataDir = path.resolve(rootDir, process.env.VILMAL_DATA_DIR ?? "./data"); const mediaDir = path.join(dataDir, "media"); return { port: Number(process.env.VILMAL_PORT ?? 8788), host: process.env.VILMAL_HOST ?? "127.0.0.1", dataDir, mediaDir, originalsDir: path.join(mediaDir, "originals"), derivedDir: path.join(mediaDir, "derived"), dbPath: path.join(dataDir, "vilmal.db"), sessionSecret: testing ? null : process.env.VILMAL_SESSION_SECRET ?? null, runcomfyApiKey: testing ? null : process.env.RUNCOMFY_API_KEY ?? null, runcomfyBaseUrl: process.env.RUNCOMFY_BASE_URL || "https://model-api.runcomfy.net", runcomfyModelId: process.env.RUNCOMFY_MODEL_ID || "google/nano-banana/pro/edit", groqApiKey: testing ? null : process.env.GROQ_API_KEY ?? null, groqModel: process.env.VILMAL_GROQ_MODEL || "meta-llama/llama-4-scout-17b-16e-instruct", groqTunerModel: process.env.VILMAL_GROQ_TUNER_MODEL || "openai/gpt-oss-120b", groqBaseUrl: process.env.VILMAL_GROQ_BASE_URL || "https://api.groq.com/openai/v1", baseApiToken: testing ? null : process.env.BASELINKER_API_TOKEN ?? null, baseApiUrl: process.env.VILMAL_BASE_API_URL || "https://api.baselinker.com/connector.php", env, maxUploadBytes: 25 * 1024 * 1024, ...overrides, }; } export { rootDir };