Files
ReadaBook/apps/api/src/config/env.ts
Git Agent 7b72cc0d83 fix(api): chemins de bibliothèques — validation dédiée, alias et unicité
Validation des chemins externalisée (library-path) avec codes d'erreur
explicites, support d'alias LIBRARY_PATH_ALIASES pour traduire un chemin
hôte vers le montage conteneur, rejet des doublons de chemin entre
bibliothèques, documentation README/.env.example et docker-compose
paramétrable via READABOOK_LIBRARY_HOST_PATH.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-23 16:23:57 +02:00

62 lines
2.2 KiB
TypeScript

import { mkdirSync } from "node:fs";
import { dirname, resolve } from "node:path";
export type AppConfig = {
nodeEnv: string;
host: string;
port: number;
databasePath: string;
storageDir: string;
jwtSecret: string;
cookieName: string;
cookieSecure: boolean;
openLibraryEnabled: boolean;
libraryPathAliases: Array<{ from: string; to: string }>;
initialAdminEmail: string;
initialAdminPassword: string;
initialAdminPasswordIsDefault: boolean;
};
const DEFAULT_INITIAL_ADMIN_EMAIL = "admin@readabook.local";
const DEFAULT_INITIAL_ADMIN_PASSWORD = "readabook-admin-change-me";
export function loadConfig(): AppConfig {
const databasePath = resolve(process.env.DATABASE_PATH ?? "./data/readabook.sqlite");
const storageDir = resolve(process.env.STORAGE_DIR ?? "./data/storage");
mkdirSync(dirname(databasePath), { recursive: true });
mkdirSync(storageDir, { recursive: true });
return {
nodeEnv: process.env.NODE_ENV ?? "development",
host: process.env.HOST ?? "0.0.0.0",
port: Number(process.env.PORT ?? 3000),
databasePath,
storageDir,
jwtSecret: process.env.JWT_SECRET ?? "dev-change-me-readabook",
cookieName: process.env.AUTH_COOKIE_NAME ?? "readabook_session",
cookieSecure: process.env.COOKIE_SECURE === "true",
openLibraryEnabled: process.env.OPEN_LIBRARY_ENABLED !== "false",
libraryPathAliases: parseLibraryPathAliases(process.env.LIBRARY_PATH_ALIASES),
initialAdminEmail: process.env.INITIAL_ADMIN_EMAIL ?? DEFAULT_INITIAL_ADMIN_EMAIL,
initialAdminPassword: process.env.INITIAL_ADMIN_PASSWORD ?? DEFAULT_INITIAL_ADMIN_PASSWORD,
initialAdminPasswordIsDefault: !process.env.INITIAL_ADMIN_PASSWORD
};
}
function parseLibraryPathAliases(value: string | undefined): Array<{ from: string; to: string }> {
if (!value) return [];
return value
.split(";")
.map((entry) => entry.trim())
.filter(Boolean)
.map((entry) => {
const separator = entry.indexOf("=");
if (separator === -1) return null;
const from = entry.slice(0, separator).trim();
const to = entry.slice(separator + 1).trim();
return from && to ? { from, to } : null;
})
.filter((entry): entry is { from: string; to: string } => Boolean(entry));
}