feat: improve unified config system and build process
- Enhance unified config environment variable loading with better precedence - Add environment-aware validation (production validation only when NODE_ENV=production) - Add environment-specific build commands (build:dev, build:prod, build:staging) - Improve configuration debugging with cleaner logging - Remove unnecessary development warnings - Provides more flexible and maintainable configuration system
This commit is contained in:
@@ -512,14 +512,24 @@ const defaultConfig: UnifiedConfig = {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get environment variable with fallback
|
* Get environment variable with fallback
|
||||||
|
* Reads from .env file via process.env or import.meta.env
|
||||||
*/
|
*/
|
||||||
function getEnvVar(key: string, fallback: string = ''): string {
|
function getEnvVar(key: string, fallback: string = ''): string {
|
||||||
if (typeof process !== 'undefined' && process.env) {
|
// First try process.env (Node.js, includes .env via dotenv or build process)
|
||||||
return process.env[key] || fallback;
|
if (typeof process !== 'undefined' && process.env && process.env[key]) {
|
||||||
|
return process.env[key]!;
|
||||||
}
|
}
|
||||||
if (typeof import.meta !== 'undefined' && import.meta.env) {
|
|
||||||
return import.meta.env[key] || fallback;
|
// Then try import.meta.env (Vite/browser, includes .env via Vite's loadEnv)
|
||||||
|
if (
|
||||||
|
typeof import.meta !== 'undefined' &&
|
||||||
|
import.meta.env &&
|
||||||
|
import.meta.env[key]
|
||||||
|
) {
|
||||||
|
return import.meta.env[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use fallback if not found
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -543,7 +553,8 @@ function getNumberEnvVar(key: string, fallback: number = 0): number {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load configuration from environment variables
|
* Load configuration from environment variables (.env file)
|
||||||
|
* This provides environment-specific overrides for the unified config
|
||||||
*/
|
*/
|
||||||
function loadFromEnvironment(config: UnifiedConfig): UnifiedConfig {
|
function loadFromEnvironment(config: UnifiedConfig): UnifiedConfig {
|
||||||
return {
|
return {
|
||||||
@@ -701,8 +712,9 @@ function validateConfig(config: UnifiedConfig): void {
|
|||||||
const errors: string[] = [];
|
const errors: string[] = [];
|
||||||
const warnings: string[] = [];
|
const warnings: string[] = [];
|
||||||
|
|
||||||
// Production-specific validations
|
// Production-specific validations (only when NODE_ENV is explicitly production)
|
||||||
if (config.app.environment === 'production') {
|
const isActualProduction = getEnvVar('NODE_ENV') === 'production';
|
||||||
|
if (config.app.environment === 'production' && isActualProduction) {
|
||||||
if (config.auth.jwtSecret === defaultConfig.auth.jwtSecret) {
|
if (config.auth.jwtSecret === defaultConfig.auth.jwtSecret) {
|
||||||
errors.push('JWT_SECRET must be changed in production');
|
errors.push('JWT_SECRET must be changed in production');
|
||||||
}
|
}
|
||||||
@@ -718,22 +730,6 @@ function validateConfig(config: UnifiedConfig): void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Development warnings for default secrets
|
|
||||||
if (config.app.environment === 'development') {
|
|
||||||
if (config.auth.jwtSecret === defaultConfig.auth.jwtSecret) {
|
|
||||||
warnings.push(
|
|
||||||
'Using default JWT_SECRET in development - change for production'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
config.security.sessionSecret === defaultConfig.security.sessionSecret
|
|
||||||
) {
|
|
||||||
warnings.push(
|
|
||||||
'Using default SESSION_SECRET in development - change for production'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Email configuration validation
|
// Email configuration validation
|
||||||
if (
|
if (
|
||||||
config.features.enableEmailVerification &&
|
config.features.enableEmailVerification &&
|
||||||
@@ -768,9 +764,10 @@ function validateConfig(config: UnifiedConfig): void {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create unified configuration
|
* Create unified configuration
|
||||||
|
* Uses .env file as primary source for environment-specific overrides
|
||||||
*/
|
*/
|
||||||
export function createUnifiedConfig(): UnifiedConfig {
|
export function createUnifiedConfig(): UnifiedConfig {
|
||||||
// Determine environment
|
// Determine environment from .env file or NODE_ENV
|
||||||
const nodeEnv = getEnvVar('NODE_ENV', 'development') as Environment;
|
const nodeEnv = getEnvVar('NODE_ENV', 'development') as Environment;
|
||||||
const environment = ['development', 'staging', 'production', 'test'].includes(
|
const environment = ['development', 'staging', 'production', 'test'].includes(
|
||||||
nodeEnv
|
nodeEnv
|
||||||
@@ -783,6 +780,7 @@ export function createUnifiedConfig(): UnifiedConfig {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create unified configuration for specific environment
|
* Create unified configuration for specific environment
|
||||||
|
* Priority: .env file overrides > environment-specific config > defaults
|
||||||
*/
|
*/
|
||||||
export function createUnifiedConfigForEnvironment(
|
export function createUnifiedConfigForEnvironment(
|
||||||
environment: Environment
|
environment: Environment
|
||||||
@@ -791,15 +789,15 @@ export function createUnifiedConfigForEnvironment(
|
|||||||
let config = { ...defaultConfig };
|
let config = { ...defaultConfig };
|
||||||
config.app.environment = environment;
|
config.app.environment = environment;
|
||||||
|
|
||||||
// Apply environment-specific overrides
|
// Apply environment-specific overrides (lower priority)
|
||||||
if (environmentConfigs[environment]) {
|
if (environmentConfigs[environment]) {
|
||||||
config = deepMerge(config, environmentConfigs[environment]);
|
config = deepMerge(config, environmentConfigs[environment]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply environment variable overrides
|
// Apply .env file overrides (highest priority)
|
||||||
config = loadFromEnvironment(config);
|
config = loadFromEnvironment(config);
|
||||||
|
|
||||||
// Compute derived values
|
// Compute derived values after all overrides
|
||||||
config.container.imageUrl = `${config.container.registry}/${config.container.repository}:${config.container.tag}`;
|
config.container.imageUrl = `${config.container.registry}/${config.container.repository}:${config.container.tag}`;
|
||||||
|
|
||||||
// Validate configuration
|
// Validate configuration
|
||||||
@@ -927,7 +925,7 @@ export function exportAsEnvVars(
|
|||||||
*/
|
*/
|
||||||
export function logConfig(): void {
|
export function logConfig(): void {
|
||||||
if (unifiedConfig.features.debugMode) {
|
if (unifiedConfig.features.debugMode) {
|
||||||
console.warn('🔧 Unified Configuration:', {
|
console.warn('🔧 Unified Configuration (Single Source of Truth):', {
|
||||||
environment: unifiedConfig.app.environment,
|
environment: unifiedConfig.app.environment,
|
||||||
app: unifiedConfig.app.name,
|
app: unifiedConfig.app.name,
|
||||||
version: unifiedConfig.app.version,
|
version: unifiedConfig.app.version,
|
||||||
@@ -936,7 +934,13 @@ export function logConfig(): void {
|
|||||||
url: unifiedConfig.database.url,
|
url: unifiedConfig.database.url,
|
||||||
useMock: unifiedConfig.database.useMock,
|
useMock: unifiedConfig.database.useMock,
|
||||||
},
|
},
|
||||||
|
container: {
|
||||||
|
registry: unifiedConfig.container.registry,
|
||||||
|
repository: unifiedConfig.container.repository,
|
||||||
|
imageUrl: unifiedConfig.container.imageUrl,
|
||||||
|
},
|
||||||
features: unifiedConfig.features,
|
features: unifiedConfig.features,
|
||||||
|
configSource: '.env file overrides applied',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"predev": "./scripts/process-html.sh",
|
"predev": "./scripts/process-html.sh",
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "NODE_ENV=development vite build",
|
||||||
|
"build:prod": "NODE_ENV=production vite build",
|
||||||
|
"build:dev": "NODE_ENV=development vite build",
|
||||||
|
"build:staging": "NODE_ENV=staging vite build",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"lint": "eslint . --ext .ts,.tsx",
|
"lint": "eslint . --ext .ts,.tsx",
|
||||||
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
"lint:fix": "eslint . --ext .ts,.tsx --fix",
|
||||||
|
|||||||
Reference in New Issue
Block a user