UNPKG

@voilajsx/appkit

Version:

Minimal and framework agnostic Node.js toolkit designed for AI agentic backend development

163 lines 6.08 kB
/** * Ultra-simple configuration management that just works * @module @voilajsx/appkit/config * @file src/config/index.ts * * @llm-rule WHEN: Building apps that need configuration from environment variables * @llm-rule AVOID: Complex config setups with multiple files - this handles everything automatically * @llm-rule NOTE: Uses UPPER_SNAKE_CASE convention (DATABASE_HOST → config.get('database.host')) * @llm-rule NOTE: Common pattern - configClass.get() → config.get('path', default) → use value * * CRITICAL UNDERSCORE CONVENTION: * - VOILA_* and FLUX_* = Framework internal variables (NOT parsed as app config) * - Everything else = Your app config (parsed into config object) * * Examples: * ✅ VOILA_AUTH_SECRET=secret → Framework internal (not in config object) * ✅ DATABASE_HOST=localhost → config.get('database.host') * ✅ REDIS_URL=redis://local → config.get('redis.url') * ❌ VOILA_DATABASE_HOST=localhost → Framework var (won't be parsed as app config) */ import { ConfigClass } from './config.js'; import { getSmartDefaults } from './defaults.js'; // Global configuration instance for performance let globalConfig = null; /** * Get configuration instance - the only function you need to learn * Environment variables parsed once for performance * @llm-rule WHEN: Starting any operation that needs configuration - this is your main entry point * @llm-rule AVOID: Calling new ConfigClass() directly - always use this function * @llm-rule NOTE: Typical flow - get() → config.get('path') → use value * @llm-rule NOTE: Only parses non-framework variables for your app config */ function get(overrides = {}) { // Lazy initialization - parse environment once if (!globalConfig) { const defaults = getSmartDefaults(); const finalConfig = { ...defaults, ...overrides }; globalConfig = new ConfigClass(finalConfig); } return globalConfig; } /** * Reset global instance (useful for testing or config changes) * @llm-rule WHEN: Testing config logic with different environment variables * @llm-rule AVOID: Using in production - only for tests and development */ function reset(newConfig = {}) { const defaults = getSmartDefaults(); const finalConfig = { ...defaults, ...newConfig }; globalConfig = new ConfigClass(finalConfig); return globalConfig; } /** * Clear the cached configuration instance * @llm-rule WHEN: Testing or when you need to reload environment variables * @llm-rule AVOID: Using in production - only for tests and development */ function clearCache() { globalConfig = null; } /** * Get current environment (development, production, test) * @llm-rule WHEN: Need to conditionally enable features based on environment * @llm-rule AVOID: Checking process.env.NODE_ENV directly - use this for consistency */ function getEnvironment() { const config = get(); return config.get('app.environment', 'development') || 'development'; } /** * Check if running in development mode * @llm-rule WHEN: Need to enable debug features or detailed logging * @llm-rule AVOID: Manual environment checks - use this for consistency */ function isDevelopment() { return getEnvironment() === 'development'; } /** * Check if running in production mode * @llm-rule WHEN: Need to disable debug features or enable optimizations * @llm-rule AVOID: Manual environment checks - use this for consistency */ function isProduction() { return getEnvironment() === 'production'; } /** * Check if running in test mode * @llm-rule WHEN: Need to enable test-specific behavior * @llm-rule AVOID: Manual environment checks - use this for consistency */ function isTest() { return getEnvironment() === 'test'; } /** * Get all environment variables that follow the UPPER_SNAKE_CASE convention * @llm-rule WHEN: Debugging configuration or documenting available config options * @llm-rule AVOID: Using for runtime config access - use get() instead * @llm-rule NOTE: Only returns non-framework variables - your app config */ function getEnvVars() { const envVars = {}; for (const [key, value] of Object.entries(process.env)) { // Skip framework variables - only show app config if (!key.startsWith('VOILA_') && !key.startsWith('FLUX_') && !key.startsWith('NODE_') && !key.startsWith('npm_') && value !== undefined) { envVars[key] = value; } } return envVars; } /** * Validate that required configuration paths exist * @llm-rule WHEN: App startup to ensure critical config is present * @llm-rule AVOID: Using in request handlers - expensive validation * @llm-rule NOTE: Throws descriptive errors with environment variable names */ function validateRequired(paths) { const config = get(); const missing = []; for (const path of paths) { if (!config.has(path)) { missing.push(path); } } if (missing.length > 0) { const envVars = missing.map(path => path.split('.').join('_').toUpperCase()); throw new Error(`Missing required configuration: ${missing.join(', ')}\n` + `Set environment variables: ${envVars.join(', ')}`); } } /** * Get configuration for a specific module/feature * @llm-rule WHEN: Module initialization that needs multiple related config values * @llm-rule AVOID: Multiple get() calls - use this for better performance */ function getModuleConfig(modulePrefix, defaults = {}) { const config = get(); const moduleConfig = config.get(modulePrefix, {}); return { ...defaults, ...moduleConfig }; } /** * Single configuration export with enhanced functionality */ export const configClass = { // Core methods get, reset, clearCache, // Environment helpers getEnvironment, isDevelopment, isProduction, isTest, // Utility methods getEnvVars, validateRequired, getModuleConfig, }; export { ConfigClass } from './config.js'; //# sourceMappingURL=index.js.map