Improve code readability by reformatting and reindenting environment validation logic

This commit is contained in:
2026-01-29 13:18:46 +00:00
parent 4d3818f961
commit 4615fa0ef1

View File

@@ -1,6 +1,6 @@
/** /**
* Environment Variable Validation * Environment Variable Validation
* *
* Validates required environment variables at startup and provides * Validates required environment variables at startup and provides
* helpful error messages for production deployments. * helpful error messages for production deployments.
*/ */
@@ -13,26 +13,33 @@ const REQUIRED_ENV_VARS = {
NODE_ENV: { NODE_ENV: {
required: true, required: true,
description: 'Environment mode (development, production)', description: 'Environment mode (development, production)',
validate: (val) => ['development', 'production', 'test'].includes(val) validate: val => ['development', 'production', 'test'].includes(val)
}, },
PORT: { PORT: {
required: true, required: true,
description: 'Server port number', description: 'Server port number',
validate: (val) => !isNaN(parseInt(val)) && parseInt(val) > 0 && parseInt(val) < 65536 validate: val =>
!isNaN(parseInt(val)) && parseInt(val) > 0 && parseInt(val) < 65536
}, },
// Optional but recommended for production // Optional but recommended for production
SESSION_SECRET: { SESSION_SECRET: {
required: false, required: false,
description: 'Secret key for session encryption', description: 'Secret key for session encryption',
warn: (val) => !val || val.length < 32 ? 'SESSION_SECRET should be at least 32 characters for security' : null warn: val =>
!val || val.length < 32
? 'SESSION_SECRET should be at least 32 characters for security'
: null
}, },
FRONTEND_URL: { FRONTEND_URL: {
required: false, required: false,
description: 'Frontend URL for CORS (required in production)', description: 'Frontend URL for CORS (required in production)',
warn: (val, env) => env.NODE_ENV === 'production' && !val ? 'FRONTEND_URL should be set in production for proper CORS' : null warn: (val, env) =>
env.NODE_ENV === 'production' && !val
? 'FRONTEND_URL should be set in production for proper CORS'
: null
}, },
// Challonge OAuth (optional) // Challonge OAuth (optional)
CHALLONGE_CLIENT_ID: { CHALLONGE_CLIENT_ID: {
required: false, required: false,
@@ -56,23 +63,27 @@ export function validateEnvironment() {
const errors = []; const errors = [];
const warnings = []; const warnings = [];
const missing = []; const missing = [];
// Check required variables // Check required variables
for (const [key, config] of Object.entries(REQUIRED_ENV_VARS)) { for (const [key, config] of Object.entries(REQUIRED_ENV_VARS)) {
const value = process.env[key]; const value = process.env[key];
// Check if required variable is missing // Check if required variable is missing
if (config.required && !value) { if (config.required && !value) {
errors.push(`Missing required environment variable: ${key} - ${config.description}`); errors.push(
`Missing required environment variable: ${key} - ${config.description}`
);
missing.push(key); missing.push(key);
continue; continue;
} }
// Validate value if present // Validate value if present
if (value && config.validate && !config.validate(value)) { if (value && config.validate && !config.validate(value)) {
errors.push(`Invalid value for ${key}: "${value}" - ${config.description}`); errors.push(
`Invalid value for ${key}: "${value}" - ${config.description}`
);
} }
// Check for warnings // Check for warnings
if (config.warn) { if (config.warn) {
const warning = config.warn(value, process.env); const warning = config.warn(value, process.env);
@@ -81,7 +92,7 @@ export function validateEnvironment() {
} }
} }
} }
return { return {
valid: errors.length === 0, valid: errors.length === 0,
errors, errors,
@@ -96,17 +107,17 @@ export function validateEnvironment() {
*/ */
export function validateOrExit(exitOnError = true) { export function validateOrExit(exitOnError = true) {
const result = validateEnvironment(); const result = validateEnvironment();
// Print validation results // Print validation results
console.log('\n🔍 Environment Validation:'); console.log('\n🔍 Environment Validation:');
console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`); console.log(` NODE_ENV: ${process.env.NODE_ENV || 'not set'}`);
console.log(` PORT: ${process.env.PORT || 'not set'}`); console.log(` PORT: ${process.env.PORT || 'not set'}`);
// Show errors // Show errors
if (result.errors.length > 0) { if (result.errors.length > 0) {
console.error('\n❌ Environment Validation Errors:'); console.error('\n❌ Environment Validation Errors:');
result.errors.forEach(error => console.error(` - ${error}`)); result.errors.forEach(error => console.error(` - ${error}`));
if (result.missing.length > 0) { if (result.missing.length > 0) {
console.error('\n💡 Tip: Create a .env file with these variables:'); console.error('\n💡 Tip: Create a .env file with these variables:');
result.missing.forEach(key => { result.missing.forEach(key => {
@@ -114,7 +125,7 @@ export function validateOrExit(exitOnError = true) {
}); });
console.error('\n See .env.example for reference'); console.error('\n See .env.example for reference');
} }
if (exitOnError) { if (exitOnError) {
console.error('\n❌ Server cannot start due to environment errors\n'); console.error('\n❌ Server cannot start due to environment errors\n');
process.exit(1); process.exit(1);
@@ -122,13 +133,13 @@ export function validateOrExit(exitOnError = true) {
} else { } else {
console.log(' ✅ All required variables present'); console.log(' ✅ All required variables present');
} }
// Show warnings // Show warnings
if (result.warnings.length > 0) { if (result.warnings.length > 0) {
console.warn('\n⚠ Environment Warnings:'); console.warn('\n⚠ Environment Warnings:');
result.warnings.forEach(warning => console.warn(` - ${warning}`)); result.warnings.forEach(warning => console.warn(` - ${warning}`));
} }
console.log(''); console.log('');
return result; return result;
} }
@@ -143,22 +154,29 @@ export function getConfig() {
port: parseInt(process.env.PORT || '3001'), port: parseInt(process.env.PORT || '3001'),
isProduction: process.env.NODE_ENV === 'production', isProduction: process.env.NODE_ENV === 'production',
isDevelopment: process.env.NODE_ENV === 'development', isDevelopment: process.env.NODE_ENV === 'development',
// Challonge OAuth // Challonge OAuth
challonge: { challonge: {
clientId: process.env.CHALLONGE_CLIENT_ID, clientId: process.env.CHALLONGE_CLIENT_ID,
clientSecret: process.env.CHALLONGE_CLIENT_SECRET, clientSecret: process.env.CHALLONGE_CLIENT_SECRET,
redirectUri: process.env.CHALLONGE_REDIRECT_URI, redirectUri: process.env.CHALLONGE_REDIRECT_URI,
configured: !!(process.env.CHALLONGE_CLIENT_ID && process.env.CHALLONGE_CLIENT_SECRET) configured: !!(
process.env.CHALLONGE_CLIENT_ID && process.env.CHALLONGE_CLIENT_SECRET
)
}, },
// CORS // CORS
cors: { cors: {
origin: process.env.NODE_ENV === 'production' origin:
? process.env.FRONTEND_URL process.env.NODE_ENV === 'production'
: ['http://localhost:5173', 'http://localhost:5174', 'http://localhost:5175'] ? process.env.FRONTEND_URL
: [
'http://localhost:5173',
'http://localhost:5174',
'http://localhost:5175'
]
}, },
// Security // Security
session: { session: {
secret: process.env.SESSION_SECRET || 'dev-secret-change-in-production' secret: process.env.SESSION_SECRET || 'dev-secret-change-in-production'