import { plainToInstance, Type } from 'class-transformer'; import { IsEnum, IsInt, IsNotEmpty, IsOptional, IsString, Max, Min, validateSync, } from 'class-validator'; export enum NodeEnv { Development = 'development', Production = 'production', Test = 'test', } /** * Schéma des variables d'environnement. Validé au démarrage via `validateEnv` * (branché sur `ConfigModule.forRoot({ validate })`) : l'app refuse de démarrer * si une variable requise manque ou est mal typée, plutôt que d'utiliser * silencieusement des valeurs par défaut (ex. credentials DB). */ export class EnvironmentVariables { @IsEnum(NodeEnv) @IsOptional() NODE_ENV: NodeEnv = NodeEnv.Development; @IsString() @IsNotEmpty() DATABASE_HOST!: string; @Type(() => Number) @IsInt() @Min(1) @Max(65535) DATABASE_PORT!: number; @IsString() @IsNotEmpty() DATABASE_USER!: string; @IsString() @IsNotEmpty() DATABASE_PASSWORD!: string; @IsString() @IsNotEmpty() DATABASE_NAME!: string; @Type(() => Number) @IsInt() @Min(1) @Max(65535) @IsOptional() PORT = 3000; @IsString() @IsOptional() DOCS_OUTPUT_DIR?: string; } export function validateEnv(config: Record): EnvironmentVariables { const validated = plainToInstance(EnvironmentVariables, config, { enableImplicitConversion: true, }); const errors = validateSync(validated, { skipMissingProperties: false }); if (errors.length > 0) { const details = errors .map((e) => Object.values(e.constraints ?? {}).join(', ')) .join('\n - '); throw new Error(`Configuration d'environnement invalide:\n - ${details}`); } return validated; }