import path from "node:path"; interface AppConfig { openAiApiKey: string; openAiBaseUrl: string; openAiImageModel: string; openAiTimeoutMs: number; databasePath: string; generatedImagesPath: string; adminUsername: string; adminPassword: string; adminSyncOnBoot: boolean; defaultMonthlyQuota: number; sessionDays: number; } function parseInteger(value: unknown, fallbackValue: number): number { const numericValue = Number.parseInt(String(value ?? ""), 10); if (Number.isFinite(numericValue)) { return numericValue; } return fallbackValue; } function parseBoolean(value: unknown, fallbackValue: boolean): boolean { if (value === undefined || value === null || value === "") { return fallbackValue; } const normalizedValue = String(value).trim().toLowerCase(); if (["1", "true", "yes", "on"].includes(normalizedValue)) { return true; } if (["0", "false", "no", "off"].includes(normalizedValue)) { return false; } return fallbackValue; } function resolveDatabasePath(rawPath?: string): string { if (!rawPath) { return path.join( /* turbopackIgnore: true */ process.cwd(), "data", "image-prompt-studio.db", ); } if (path.isAbsolute(rawPath)) { return rawPath; } return path.resolve(/* turbopackIgnore: true */ process.cwd(), rawPath); } function resolveGeneratedImagesPath( databasePath: string, rawPath?: string, ): string { if (!rawPath) { return path.join(path.dirname(databasePath), "generated-images"); } if (path.isAbsolute(rawPath)) { return rawPath; } return path.resolve(/* turbopackIgnore: true */ process.cwd(), rawPath); } const databasePath = resolveDatabasePath(process.env.DATABASE_PATH); export const appConfig: AppConfig = { openAiApiKey: process.env.OPENAI_API_KEY ?? "", openAiBaseUrl: process.env.OPENAI_BASE_URL ?? "https://api.openai.com/v1", openAiImageModel: process.env.OPENAI_IMAGE_MODEL ?? "gpt-image-2", openAiTimeoutMs: parseInteger(process.env.OPENAI_TIMEOUT_MS, 140000), databasePath, generatedImagesPath: resolveGeneratedImagesPath( databasePath, process.env.GENERATED_IMAGES_PATH, ), adminUsername: String(process.env.ADMIN_USERNAME ?? "admin") .trim() .toLowerCase(), adminPassword: String(process.env.ADMIN_PASSWORD ?? "change-me-now"), adminSyncOnBoot: parseBoolean(process.env.ADMIN_SYNC_ON_BOOT, true), defaultMonthlyQuota: parseInteger(process.env.DEFAULT_MONTHLY_QUOTA, 20), sessionDays: parseInteger(process.env.SESSION_DAYS, 30), };