import { z } from 'zod'; import { logger } from '@/utils/logger'; // Schéma de validation pour les variables d'environnement // Aligné avec FRONTEND_INTEGRATION.md // Support URLs relatives (commençant par /) ou absolues const urlOrPathSchema = z.string().refine( (val) => { if (!val) return false; // Accepter les URLs absolues (http://, https://, ws://, wss://) if (/^https?:\/\//.test(val) || /^wss?:\/\//.test(val)) { try { new URL(val); return true; } catch { return false; } } // Accepter les chemins relatifs (commençant par /) return val.startsWith('/'); }, { message: 'Must be a valid URL or a path starting with /' } ); const envSchema = z.object({ VITE_API_URL: urlOrPathSchema.default('/api/v1'), VITE_WS_URL: urlOrPathSchema.default('/ws'), VITE_STREAM_URL: urlOrPathSchema.default('/stream'), VITE_UPLOAD_URL: urlOrPathSchema.default('/upload'), VITE_APP_NAME: z.string().default('Veza'), VITE_API_VERSION: z.string().default('v1'), VITE_DEBUG: z .string() .transform((val) => val === 'true' || val === '1') .default('false'), VITE_USE_MSW: z .string() .transform((val) => val === '1' || val === 'true') .default('0'), VITE_FCM_VAPID_KEY: z.string().optional(), // FIX #20: Configuration Sentry pour error tracking VITE_SENTRY_DSN: z.string().url().optional(), }); // Validation et parsing des variables d'environnement const parseEnv = () => { try { return envSchema.parse({ VITE_API_URL: import.meta.env.VITE_API_URL, VITE_WS_URL: import.meta.env.VITE_WS_URL, VITE_STREAM_URL: import.meta.env.VITE_STREAM_URL, VITE_UPLOAD_URL: import.meta.env.VITE_UPLOAD_URL, VITE_APP_NAME: import.meta.env.VITE_APP_NAME, VITE_API_VERSION: import.meta.env.VITE_API_VERSION, VITE_DEBUG: import.meta.env.VITE_DEBUG, VITE_USE_MSW: import.meta.env.VITE_USE_MSW, VITE_FCM_VAPID_KEY: import.meta.env.VITE_FCM_VAPID_KEY, VITE_SENTRY_DSN: import.meta.env.VITE_SENTRY_DSN, }); } catch (error) { if (error instanceof z.ZodError) { logger.error('❌ Invalid environment variables', { errors: error.errors, }); throw new Error( `Environment variables validation failed: ${error.errors .map((e) => `${e.path.join('.')}: ${e.message}`) .join(', ')}`, ); } throw error; } }; // Variables d'environnement validées const validatedEnv = parseEnv(); // Export de l'objet env avec types export const env = { API_URL: validatedEnv.VITE_API_URL, WS_URL: validatedEnv.VITE_WS_URL, STREAM_URL: validatedEnv.VITE_STREAM_URL, UPLOAD_URL: validatedEnv.VITE_UPLOAD_URL, APP_NAME: validatedEnv.VITE_APP_NAME, API_VERSION: validatedEnv.VITE_API_VERSION, DEBUG: validatedEnv.VITE_DEBUG, USE_MSW: validatedEnv.VITE_USE_MSW, FCM_VAPID_KEY: validatedEnv.VITE_FCM_VAPID_KEY, // FIX #20: Configuration Sentry SENTRY_DSN: validatedEnv.VITE_SENTRY_DSN, } as const; // Type pour les variables d'environnement export type Env = typeof env;