Files

209 lines
4.6 KiB
JavaScript
Raw Permalink Normal View History

2025-11-06 11:08:59 +01:00
const path = require('path');
const fs = require('fs');
const logger = require('./logger');
class ConfigLoader {
constructor() {
this.config = {};
this.env = process.env.NODE_ENV || 'development';
this.loadConfig();
}
loadConfig() {
try {
// Load base configuration
this.loadBaseConfig();
// Load environment-specific configuration
this.loadEnvConfig();
// Validate configuration
this.validateConfig();
logger.info(`Configuration loaded for environment: ${this.env}`);
} catch (error) {
logger.error('Configuration loading failed:', error);
throw error;
}
}
loadBaseConfig() {
// Load from appConfig.js
const { appConfig } = require('../config/appConfig');
this.config = { ...appConfig };
}
loadEnvConfig() {
const envFile = path.join(__dirname, '../../', `env.${this.env}`);
if (fs.existsSync(envFile)) {
logger.info(`Loading environment configuration from: ${envFile}`);
// Parse environment file
const envContent = fs.readFileSync(envFile, 'utf8');
const envVars = this.parseEnvFile(envContent);
// Override configuration with environment-specific values
Object.assign(process.env, envVars);
// Reload configuration with new environment variables
const { appConfig } = require('../config/appConfig');
this.config = { ...appConfig };
} else {
logger.warn(`Environment configuration file not found: ${envFile}`);
}
}
parseEnvFile(content) {
const envVars = {};
const lines = content.split('\n');
for (const line of lines) {
const trimmedLine = line.trim();
// Skip empty lines and comments
if (!trimmedLine || trimmedLine.startsWith('#')) {
continue;
}
// Parse KEY=VALUE format
const equalIndex = trimmedLine.indexOf('=');
if (equalIndex > 0) {
const key = trimmedLine.substring(0, equalIndex).trim();
const value = trimmedLine.substring(equalIndex + 1).trim();
// Remove quotes if present
const cleanValue = value.replace(/^["']|["']$/g, '');
envVars[key] = cleanValue;
}
}
return envVars;
}
validateConfig() {
const errors = [];
const warnings = [];
// Required fields validation
if (!this.config.apis.groq.apiKey) {
errors.push('GROQ_API_KEY is required');
}
if (!this.config.auth.jwtSecret) {
errors.push('JWT_SECRET is required');
}
if (!this.config.database.password) {
errors.push('DB_PASSWORD is required');
}
// Environment-specific validations
if (this.env === 'production') {
if (this.config.auth.jwtSecret === 'dev_secret_key_change_in_production') {
errors.push('JWT_SECRET must be changed for production');
}
if (!this.config.database.ssl) {
warnings.push('Database SSL is recommended for production');
}
}
// Log warnings
warnings.forEach(warning => {
logger.warn(`Configuration warning: ${warning}`);
});
// Throw errors
if (errors.length > 0) {
const errorMessage = `Configuration errors: ${errors.join(', ')}`;
logger.error(errorMessage);
throw new Error(errorMessage);
}
}
get(key, defaultValue = null) {
const keys = key.split('.');
let value = this.config;
for (const k of keys) {
if (value && typeof value === 'object' && k in value) {
value = value[k];
} else {
return defaultValue;
}
}
return value;
}
getAll() {
return this.config;
}
getServerConfig() {
return this.config.server;
}
getDatabaseConfig() {
return this.config.database;
}
getApiConfig() {
return this.config.apis;
}
getAuthConfig() {
return this.config.auth;
}
getUploadConfig() {
return this.config.upload;
}
getRateLimitConfig() {
return this.config.rateLimit;
}
getLoggingConfig() {
return this.config.logging;
}
getModelConfig() {
return this.config.models;
}
getSecurityConfig() {
return this.config.security;
}
getMonitoringConfig() {
return this.config.monitoring;
}
getDevelopmentConfig() {
return this.config.development;
}
isDevelopment() {
return this.env === 'development';
}
isProduction() {
return this.env === 'production';
}
isTest() {
return this.env === 'test';
}
getEnvironment() {
return this.env;
}
}
// Create singleton instance
const configLoader = new ConfigLoader();
module.exports = configLoader;