import dotenv from 'dotenv'; import { z } from 'zod'; // Load environment variables from .env file dotenv.config(); /** * Environment configuration schema with validation */ const envConfigSchema = z.object({ // AWS Configuration AWS_REGION: z.string().default('us-east-1'), // Server Configuration PORT: z.string().default('3000'), NODE_ENV: z.enum(['development', 'production', 'test']).default('development'), // Optional AWS Credentials - these might come from environment or AWS SDK will use default providers AWS_ACCESS_KEY_ID: z.string().optional(), AWS_SECRET_ACCESS_KEY: z.string().optional(), AWS_SESSION_TOKEN: z.string().optional(), AWS_PROFILE: z.string().optional(), // Metrics Configuration ENABLE_CLOUDWATCH_METRICS: z.string().optional().default('false'), CLOUDWATCH_METRICS_NAMESPACE: z.string().optional().default('AwsLogsMcp'), }); /** * Type for validated environment configuration */ export type EnvConfig = z.infer; // Cache for environment configuration let cachedConfig: EnvConfig | null = null; let configLogged = false; /** * Load and validate environment configuration * @param forceRefresh Force refresh the configuration cache * @returns Validated environment configuration */ export function loadEnvConfig(forceRefresh: boolean = false): EnvConfig { try { // Use cached config if available and not forcing refresh if (cachedConfig !== null && !forceRefresh) { return cachedConfig; } // Parse and validate environment variables const config = envConfigSchema.parse(process.env); // Log configuration only once (exclude sensitive values) if (!configLogged) { console.log('Environment configuration loaded:'); console.log(`- AWS_REGION: ${config.AWS_REGION}`); console.log(`- PORT: ${config.PORT}`); console.log(`- NODE_ENV: ${config.NODE_ENV}`); // Format credential information securely if (config.AWS_ACCESS_KEY_ID) { // Only show first 4 and last 4 chars, replace middle with *** const keyLength = config.AWS_ACCESS_KEY_ID.length; const maskedKey = keyLength > 8 ? `${config.AWS_ACCESS_KEY_ID.substring(0, 4)}...${config.AWS_ACCESS_KEY_ID.substring(keyLength - 4)}` : 'Set'; console.log(`- AWS_ACCESS_KEY_ID: ${maskedKey}`); } else { console.log('- AWS_ACCESS_KEY_ID: Not set'); } console.log(`- AWS_SECRET_ACCESS_KEY: ${config.AWS_SECRET_ACCESS_KEY ? 'Set' : 'Not set'}`); console.log(`- AWS_SESSION_TOKEN: ${config.AWS_SESSION_TOKEN ? 'Set' : 'Not set'}`); console.log(`- AWS_PROFILE: ${config.AWS_PROFILE ? 'Set' : 'Not set'}`); configLogged = true; } // Update cache and return cachedConfig = config; return config; } catch (error) { if (error instanceof z.ZodError) { console.error('Environment configuration validation error:', error.errors); throw new Error(`Invalid environment configuration: ${error.errors.map(e => e.message).join(', ')}`); } throw error; } } /** * Get current environment configuration * @returns Validated environment configuration */ export function getConfig(): EnvConfig { return loadEnvConfig(); }