UNPKG

nx-config2

Version:

Next-generation configuration management for Node.js - Zero dependencies, TypeScript-first, production-ready

1,354 lines (1,069 loc) 42.2 kB
# nx-config2 🚀 > **Next-generation configuration management for Node.js** > Zero dependencies. TypeScript-first. Production-ready. [![npm version](https://img.shields.io/npm/v/nx-config2.svg)](https://www.npmjs.com/package/nx-config2) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) [![Downloads](https://img.shields.io/npm/dm/nx-config2.svg)](https://www.npmjs.com/package/nx-config2) **nxconfig** combines the best features from **9+ MIT-licensed configuration libraries** into one powerful, zero-dependency package. Perfect for cloud-native applications, microservices, and enterprise systems. --- ## ✨ Why nxconfig? **nxconfig** is the most comprehensive configuration management library for Node.js, combining the best features from 9+ popular MIT-licensed packages into one powerful, zero-dependency solution. Built with TypeScript-first design and production-ready features, it's perfect for cloud-native applications, microservices, and enterprise systems. **Key Capabilities:** - **ENV Token Resolution** with multi-environment file support - **Type Coercion** for 15+ built-in data types - **Schema Validation** with detailed error reporting - **Multi-Config Merging** with intelligent conflict resolution - **Environment Variable Inspection** with sensitive data masking - **Hot Reload** and **Auto-Documentation** generation --- ## 📦 Installation ```bash npm install nx-config2 ``` ```bash yarn add nx-config2 ``` ```bash pnpm add nx-config2 ``` --- ## 🚀 Quick Start ### Basic Usage ```typescript import { initConfig } from 'nx-config2'; // Set environment variables process.env.DB_HOST = 'localhost'; process.env.DB_PORT = '5432'; process.env.API_KEY = 'secret123'; const config = { database: { host: 'ENV.DB_HOST', port: 'ENV.DB_PORT:port', // Auto-validates port range password: 'ENV.DB_PASSWORD||changeme' // Default value }, api: { key: 'ENV.API_KEY', timeout: 'ENV.TIMEOUT:duration||30s' // Parses "30s" to 30000ms } }; const result = initConfig(config, { dotenvPath: '.env', verbose: true }); console.log(result.config); // { // database: { host: 'localhost', port: 5432, password: 'changeme' }, // api: { key: 'secret123', timeout: 30000 } // } ``` --- ## 🎯 Core Features ### 1. ENV Token Resolution Use `ENV.VARIABLE` tokens in your configuration: ```typescript const config = { service: 'ENV.SERVICE_NAME', port: 'ENV.PORT:number||3000' }; ``` ### 1.1. Multi-Environment File Support (NEW!) Load variables from different environment files based on the token pattern: ```typescript const config = { // Simple pattern: loads from .env or process.env app: { name: 'ENV.APP_NAME||my-app', version: 'ENV.APP_VERSION||1.0.0' }, // Multi-segment pattern: loads from .env.test file test: { apiKey: 'ENV.TEST.API_KEY', dbHost: 'ENV.TEST.DB_HOST', dbPort: 'ENV.TEST.DB_PORT:port' }, // Multi-segment pattern: loads from .env.prod.database file production: { database: { host: 'ENV.PROD.DATABASE.HOST', port: 'ENV.PROD.DATABASE.PORT:port', ssl: 'ENV.PROD.DATABASE.SSL:boolean' } } }; ``` **Pattern Rules:** - `ENV.VARIABLE` loads from `.env` file or `process.env` - `ENV.TEST.VARIABLE` loads from `.env.test` file - `ENV.PROD.DATABASE.HOST` loads from `.env.prod.database` file - `ENV.STAGING.API.KEY` loads from `.env.staging.api` file The last segment is always the variable name, everything before it becomes the environment file path. ### 2. Type Coercion (15+ Built-in Types) nxconfig provides comprehensive type coercion with built-in validation for 15+ data types. Each type includes validation, error handling, and automatic conversion: ```typescript 'ENV.PORT:port' // Validates 0-65535, throws error if invalid 'ENV.ENABLED:boolean' // Converts 'true'/'false', '1'/'0' to boolean 'ENV.COUNT:number' // Converts to number, validates not NaN 'ENV.COUNT:int' // Integer only, validates whole numbers 'ENV.COUNT:nat' // Natural number (>=0), validates non-negative 'ENV.MAX:bigint' // BigInt support for large numbers 'ENV.TAGS:array' // Comma-separated string to array 'ENV.DATA:json' // JSON parsing with error handling 'ENV.URL:url' // URL validation using native URL constructor 'ENV.EMAIL:email' // Email validation with regex pattern 'ENV.IP:ipaddress' // IPv4/IPv6 address validation 'ENV.TIMEOUT:duration' // Duration parsing: "5s", "10m", "2h", "1d", "1w" 'ENV.DATE:timestamp' // Date parsing, returns milliseconds 'ENV.PATTERN:regex' // RegExp compilation with error handling ``` **Type Validation Features:** - **Automatic Error Handling**: Invalid values throw descriptive errors - **Range Validation**: Port numbers (0-65535), natural numbers (≥0) - **Format Validation**: Email, URL, IP address patterns - **Custom Validators**: Extend with your own validation functions - **Null Safety**: Handles undefined/null values gracefully ### 3. Default Values nxconfig supports comprehensive default value handling with multiple fallback strategies: ```typescript 'ENV.HOST||localhost' // Simple default value 'ENV.PORT:number||3000' // Default with type coercion 'ENV.DEBUG:boolean||false' // Boolean default 'ENV.TIMEOUT:duration||30s' // Duration default 'ENV.TAGS:array||item1,item2' // Array default ``` **Default Value Features:** - **Multiple Fallback Levels**: ENV variable default value options defaults - **Type-Aware Defaults**: Defaults are processed through type coercion ### 2.1. Automatic JSON-like Parsing (NEW!) nxconfig automatically detects and parses JSON-like strings in environment variables, even without explicit type annotations. Values that start with `{` and end with `}` are parsed as objects, and values that start with `[` and end with `]` are parsed as arrays. **Object Parsing:** ```typescript // .env file DATABASE_CONFIG={"host":"localhost","port":5432,"ssl":true} // Config const config = { database: 'ENV.DATABASE_CONFIG' // Automatically parsed as object }; // Result // { database: { host: 'localhost', port: 5432, ssl: true } } ``` **Array Parsing:** ```typescript // .env file ALLOWED_HOSTS=["localhost","example.com","127.0.0.1"] PORT_NUMBERS=[3000,8080,9000] COMPLEX_ARRAY=[{"name":"server1","port":3000},{"name":"server2","port":8080}] // Config const config = { hosts: 'ENV.ALLOWED_HOSTS', // String array ports: 'ENV.PORT_NUMBERS', // Number array servers: 'ENV.COMPLEX_ARRAY' // Array of objects }; // Result // { // hosts: ['localhost', 'example.com', '127.0.0.1'], // ports: [3000, 8080, 9000], // servers: [{ name: 'server1', port: 3000 }, { name: 'server2', port: 8080 }] // } ``` **Fallback Behavior:** - If parsing fails (invalid JSON), the original string value is returned - This ensures no errors occur when a string happens to start with `{` or `[` but isn't JSON ```typescript // .env file NOT_JSON={not valid json // Config const config = { value: 'ENV.NOT_JSON' // Returns "{not valid json" (string) }; ``` **Array Type Enhancement:** The `array` type now supports both JSON arrays and comma-separated strings: ```typescript // JSON array (parsed as typed array) ENV.ITEMS:array with value "[1,2,3]" [1, 2, 3] (numbers) // Comma-separated string (split and trimmed) ENV.ITEMS:array with value "a,b,c" ['a', 'b', 'c'] (strings) ``` ### 2.2. JSON File References (NEW!) nxconfig supports referencing external JSON files directly from environment variables using the `{{path.json}}` syntax. This is useful for complex configurations that are better stored in separate files. **File Reference Pattern:** ```typescript // .env file DATABASE_CONFIG={{./configuration-examples/database.json}} SERVER_LIST={{./configs/servers.json}} // Config const config = { database: 'ENV.DATABASE_CONFIG', // Loads from ./configuration-examples/database.json servers: 'ENV.SERVER_LIST' // Loads from ./configs/servers.json }; // Result - automatically loads and parses the JSON files // { // database: { host: 'localhost', port: 5432, ... }, // servers: [{ name: 'server1', port: 3000 }, ...] // } ``` **Path Resolution:** - Paths are resolved relative to the config file location (if parsing from a file) - Otherwise, paths are resolved relative to `process.cwd()` - Supports both relative paths (`./config.json`) and absolute paths (`/absolute/path.json`) **Fallback Behavior:** - If the file doesn't exist, the original string value `{{path.json}}` is returned - If the file exists but contains invalid JSON, the original string is returned - This ensures no errors occur when files are missing or malformed ```typescript // .env file MISSING_FILE={{./nonexistent.json}} // Config const config = { value: 'ENV.MISSING_FILE' // Returns "{{./nonexistent.json}}" (string) }; ``` **Configuration Options:** - `heuristicJsonParsing`: Enable/disable automatic JSON detection (including file references) (default: `true`) - `lenientJson`: When using `:json` type, return original string on parse failure instead of throwing (default: `false`) ```typescript // Disable automatic JSON parsing (including file references) parseConfig(config, { heuristicJsonParsing: false }); // Use lenient JSON parsing (no errors on invalid JSON) parseConfig(config, { lenientJson: true }); ``` ### 2.3. Config Object File References (NEW!) nxconfig supports loading JSON files directly from config objects using the reserved `_loadFile` property. This allows you to reference external JSON files in your configuration structure. **Config File Reference Pattern:** ```typescript const config = { // Load entire object from file database: { _loadFile: './configs/database.json' }, // Load entire array from file servers: { _loadFile: './configs/servers.json' }, // Mix file references with direct values app: { name: 'my-app', config: { _loadFile: './configs/app-config.json' } } }; // Result - automatically loads and parses JSON files // { // database: { host: 'localhost', port: 5432, ... }, // servers: [{ name: 'server1', port: 3000 }, ...], // app: { // name: 'my-app', // config: { timeout: 5000, ... } // } // } ``` **Important Notes:** - `_loadFile` is a **reserved property name** - when present, the entire object is replaced with the file's contents - File contents can be either JSON objects or JSON arrays - Paths are resolved relative to the config file location (if parsing from a file) or `process.cwd()` (if parsing from an object) - If the file doesn't exist or contains invalid JSON, the original object (with `_loadFile`) is returned and a warning is generated - The loaded content is recursively parsed, so it can contain ENV tokens, nested `_loadFile` references, etc. **Example from Config File:** ```json { "database": { "_loadFile": "./database.json" }, "servers": { "_loadFile": "./servers.json" } } ``` - **Warning System**: Logs when defaults are used for transparency - **Nested Defaults**: Support for complex default structures ### 3. Automatic Config Loading (NEW!) nxconfig provides an automatic config loader that uses a default config map covering common use cases, then automatically adds any additional environment variables as camelCase properties at the root level. **Basic Usage:** ```typescript import { autoLoadConfig } from 'nx-config2'; // Automatically load all config from environment variables const config = autoLoadConfig(); // Access structured config console.log(config.api.port); // From ENV.API_PORT console.log(config.database.uri); // From ENV.MONGO_URI console.log(config.logging.level); // From ENV.LOG_LEVEL // Additional env vars automatically added as camelCase // ENV.CUSTOM_VAR config.customVar // ENV.MY_APP_VAR config.myAppVar ``` **Default Config Map:** The auto-loader includes a pre-configured map covering: - `api`: port, allowedCollections, mode, dataFolder, timeout, host, corsOrigins, rateLimitWindow, rateLimitMax - `atm`: enabled, endpoint, token, accountId, cache settings, retry settings - `ai`: Comprehensive coverage for 20+ AI/LLM providers (OpenAI, Anthropic, Google, Azure, etc.) - `vectordb`: Pinecone, Weaviate, Qdrant, Milvus, Chroma, Supabase, ElasticSearch - `database`: PostgreSQL, MySQL, MongoDB, Redis, SQLite, CockroachDB, DynamoDB, Cassandra, Neo4j - `dataTier`: mode (xronox/nx-mongo), engine, xronox settings, nxMongo settings - `storage`: S3-compatible storage with full aliasing (S3_/SPACE_/STORAGE_) - `messaging`: RabbitMQ, Kafka, SQS, Pub/Sub, NATS - `observability`: Prometheus, Grafana, DataDog, New Relic, Sentry, OpenTelemetry - `logging`: level, format, toFile, filePath, toUnified, debugNamespace, maxFiles, maxSize, compress - `email`: SendGrid, Mailgun, AWS SES, SMTP - `payment`: Stripe, PayPal, Square - `auth`: Auth0, Okta, Clerk, Supabase Auth - `search`: Algolia, MeiliSearch, Typesense - `cdn`: Cloudflare, Cloudinary, ImageKit - `analytics`: Google Analytics, Mixpanel, Segment, PostHog - `featureFlags`: LaunchDarkly, Flagsmith - `deployment`: Vercel, Netlify, Docker Hub **Features:** - **Default Config Map**: Common patterns pre-configured with ENV tokens - **Automatic Addition**: All `ALL_UPPERCASE` env vars not in default config are added as camelCase at root - **JSON Parsing**: JSON-like env vars are automatically parsed - **Beautified Output**: Config is sorted with default sections first, then alphabetically - **Non-strict by Default**: Missing optional vars don't throw errors **Options:** ```typescript autoLoadConfig({ dotenvPath: '.env', // .env file path (default: '.env') includeAllEnvVars: true, // Include additional env vars (default: true) beautify: true, // Sort keys nicely (default: true) verbose: false, // Log resolved vars (default: false) heuristicJsonParsing: true // Auto-parse JSON (default: true) }); ``` **Example:** ```typescript // .env file API_PORT=8080 MONGO_URI=mongodb://localhost:27017/mydb LOG_LEVEL=debug DATATIER_MODE=nx-mongo XRONOX_ENABLED=false NX_MONGO_ENABLED=true CUSTOM_VAR=custom-value JSON_CONFIG={"key":"value"} // Auto-load config const config = autoLoadConfig(); // Result structure: // { // api: { port: 8080, ... }, // database: { mongodb: { uri: 'mongodb://...', ... }, ... }, // dataTier: { mode: 'nx-mongo', nxMongo: { enabled: true, ... }, ... }, // logging: { level: 'debug', ... }, // customVar: 'custom-value', // jsonConfig: { key: 'value' } // } ``` ### 4. Prefix/Suffix Support nxconfig provides flexible environment variable resolution with prefix and suffix support for multi-tenant and environment-specific configurations: ```typescript // All AWS_* variables parseConfig(config, { prefix: 'AWS_' }); // Environment-specific variables parseConfig(config, { suffix: '_PROD' // Prefers API_KEY_PROD over API_KEY }); // Combined prefix and suffix parseConfig(config, { prefix: 'APP_', suffix: '_PROD' // Looks for APP_API_KEY_PROD }); ``` **Prefix/Suffix Features:** - **Priority Resolution**: Suffix takes precedence over prefix - **Fallback Chain**: ENV_VAR_SUFFIX ENV_VAR_PREFIX ENV_VAR - **Multi-Environment Support**: Perfect for dev/staging/prod setups - **Tenant Isolation**: Use prefixes for multi-tenant applications ### 5. Environment Variable Inspection Inspect and analyze environment variables in your .env files with detailed information: ```typescript import { getEnvVariables } from 'nx-config2'; // Get variables from default .env file const defaultVars = getEnvVariables(); // Get variables from specific environment file const testVars = getEnvVariables('test'); // .env.test const prodVars = getEnvVariables('prod'); // .env.prod const dbVars = getEnvVariables('prod.database'); // .env.prod.database console.log(testVars); // [ // { varName: 'API_KEY', length: 20, synthesizedValue: 'te***89' }, // { varName: 'DB_HOST', length: 18, synthesizedValue: 'test-db.example.com' }, // { varName: 'PASSWORD', length: 25, synthesizedValue: 'su***23' } // ] ``` **Environment Variable Inspection Features:** - **Variable Discovery**: List all variables in any .env file - **Sensitive Data Masking**: Automatically mask passwords, keys, and tokens - **Length Information**: Get original value length for validation - **Multi-Environment Support**: Works with any environment file path - **Safe Inspection**: Sensitive fields are automatically masked - **TypeScript Support**: Full type definitions for variable information --- ## 🔥 Multi-Config Features nxconfig provides powerful multi-configuration management with intelligent merging, inheritance, and flexible source handling: ### Smart Configuration Merging Merge multiple configuration sources with intelligent conflict resolution: ```typescript import { parseMultiConfig } from 'nx-config2'; // Merge multiple configs into one const result = parseMultiConfig({ sources: ['./base.json', './production.json', './overrides.json'], mergeStrategy: 'deep', // 'deep' | 'shallow' | 'override' | 'append' priority: 'last', // 'first' | 'last' verbose: true }); console.log(result.config); // Deeply merged configuration ``` **Smart Merging Features:** - **Conflict Resolution**: Intelligent handling of overlapping keys - **Type Preservation**: Maintains data types during merging - **Array Handling**: Smart array concatenation and deduplication - **Nested Merging**: Deep recursive object merging - **Error Recovery**: Graceful handling of merge conflicts ### Named Configuration Access Keep configurations separate but accessible by name for multi-environment setups: ```typescript // Keep configs separate but accessible by name const result = parseMultiConfig({ sources: ['./prod.json', './staging.json', './dev.json'], keepSeparate: true, names: ['production', 'staging', 'development'] }); console.log(result.configs.production); // Production config console.log(result.configs.staging); // Staging config console.log(result.configs.development); // Development config ``` **Named Access Features:** - **Environment Isolation**: Keep configs completely separate - **Dynamic Selection**: Choose config at runtime based on environment - **Memory Efficient**: Only load needed configurations - **Type Safety**: Full TypeScript support for named configs ### Configuration Inheritance Build complex configuration hierarchies with base configs and overrides: ```typescript // Load base config first, then layer sources const result = parseMultiConfig({ extends: './base-config.json', // Loaded first sources: ['./env-specific.json'], mergeStrategy: 'deep' }); ``` **Inheritance Features:** - **Base Configuration**: Define common settings once - **Layered Overrides**: Environment-specific customizations - **Inheritance Chains**: Support for multiple levels of inheritance - **Override Protection**: Prevent accidental base config modification ### Merge Strategies Choose the right merging strategy for your use case: ```typescript // Deep merge (recursive object merging, array concatenation) mergeStrategy: 'deep' // Best for complex nested configs // Shallow merge (Object.assign style) mergeStrategy: 'shallow' // Fast, simple merging // Override (last source wins completely) mergeStrategy: 'override' // Complete replacement // Append (array-focused merging) mergeStrategy: 'append' // Array concatenation with deduplication ``` **Merge Strategy Details:** - **Deep**: Recursively merges objects, concatenates arrays, preserves structure - **Shallow**: Fast Object.assign-style merging, arrays are replaced - **Override**: Last source completely replaces previous sources - **Append**: Array-focused merging with intelligent deduplication --- ## 🛠️ Advanced Features ### Schema Validation (Convict-inspired) nxconfig provides comprehensive schema validation with detailed error reporting and custom validators: ```typescript const result = initConfig(config, { schema: { port: { type: 'port', required: true, doc: 'Server port number', env: 'PORT', arg: 'port', // --port from command line default: 3000, min: 1000, max: 9999 }, apiKey: { type: 'string', required: true, sensitive: true, // Masks in logs nullable: false, format: (val) => val.length >= 32 // Custom validator }, environment: { type: 'string', enum: ['development', 'staging', 'production'], default: 'development' }, timeout: { type: 'duration', doc: 'Request timeout', default: '30s' } } }); ``` **Schema Validation Features:** - **Type Validation**: Automatic type checking with detailed error messages - **Range Validation**: Min/max values for numeric types - **Enum Constraints**: Restrict values to predefined options - **Custom Validators**: Define your own validation functions - **Required Fields**: Enforce mandatory configuration values - **Sensitive Data**: Automatic masking of sensitive fields in logs - **Documentation**: Built-in field documentation support - **Command-line Integration**: Map schema fields to CLI arguments ### Hierarchical Configuration (nconf-inspired) Build complex configuration hierarchies with priority-based value resolution: ```typescript import { ConfigurationHierarchy } from 'nx-config2'; const config = new ConfigurationHierarchy(); // Priority: overrides > env > file > defaults config.set('database:host', '127.0.0.1'); config.set('database:port', 5432); console.log(config.get('database:host')); // '127.0.0.1' console.log(config.toObject()); ``` **Hierarchical Features:** - **Priority Resolution**: Clear precedence order for value sources - **Nested Key Access**: Use colon-separated keys for deep access - **Dynamic Updates**: Modify configuration at runtime - **Memory Management**: Efficient storage and retrieval - **Type Safety**: Full TypeScript support for hierarchical access ### Command-line Arguments Parse command-line arguments directly into your configuration: ```typescript // node app.js --port=8080 --debug=true const result = parseConfig(config, { commandLineArgs: true }); ``` **CLI Integration Features:** - **Automatic Parsing**: Parse `--flag=value` and `--flag` patterns - **Type Coercion**: Apply type conversion to CLI values - **Priority Override**: CLI args override environment variables - **Validation**: Validate CLI arguments against schema - **Help Generation**: Auto-generate help text from schema ### Auto-Documentation Generation Generate comprehensive documentation for your configuration automatically: ```typescript const result = initConfig(config, { generateDocs: true, docsPath: './ENV_VARS.md', descriptions: { API_KEY: 'Authentication key for external services', DB_HOST: 'Database server hostname', PORT: 'HTTP server port (1000-65535)' }, schema: { PORT: { type: 'port', required: true, doc: 'Server listening port' } } }); // Generates beautiful markdown documentation! ``` **Documentation Features:** - **Markdown Generation**: Professional documentation format - **Variable Tables**: Organized tables with types, defaults, descriptions - **Usage Examples**: Auto-generated usage examples - **Sensitive Data**: Automatic masking of sensitive fields - **Schema Integration**: Include validation rules in documentation **Output:** ```markdown # Configuration Documentation ## Environment Variables | Variable | Type | Required | Default | Description | Sensitive | |----------|------|----------|---------|-------------|-----------| | `API_KEY` | `string` | Yes | - | Authentication key... | 🔒 Yes | | `PORT` | `port` | Yes | `3000` | Server listening port | No | ## Usage Example ```bash export API_KEY="your-api-key" export PORT="8080" ``` ``` ### Directory Auto-Creation Automatically create missing directories for path-based configurations: ```typescript const config = { uploadDir: 'ENV.UPLOAD_PATH', cacheDir: 'ENV.CACHE_PATH', logDir: 'ENV.LOG_PATH' }; parseConfig(config, { createDirectories: true // Creates missing directories }); ``` **Directory Features:** - **Automatic Creation**: Creates missing directories recursively - **Permission Handling**: Respects existing permissions - **Error Recovery**: Graceful handling of creation failures - **Path Validation**: Validates paths before creation - **Verbose Logging**: Logs directory creation activities ### Path Validation Validate file and directory existence with comprehensive error reporting: ```typescript schema: { configFile: { type: 'string', isFile: true, // Validates file exists required: true }, dataDir: { type: 'string', isDirectory: true, // Validates directory exists required: true } } ``` **Path Validation Features:** - **File Existence**: Validate files exist and are readable - **Directory Validation**: Check directory existence and permissions - **Path Resolution**: Handle relative and absolute paths - **Error Details**: Detailed error messages for missing paths - **Schema Integration**: Works seamlessly with validation schemas ### Secret Masking Automatically detect and mask sensitive data in configurations: ```typescript import { maskSecrets } from 'nx-config2'; const config = { api_key: 'secret123456', password: 'mypassword', username: 'john' }; console.log(maskSecrets(config)); // { // api_key: 'se***56', // password: 'my***rd', // username: 'john' // } ``` **Secret Masking Features:** - **Automatic Detection**: Identifies sensitive fields by name patterns - **Smart Masking**: Preserves first/last characters for readability - **Schema Integration**: Use schema to mark sensitive fields - **Custom Patterns**: Define your own sensitive field patterns - **Log Safety**: Safe for logging and debugging ### Hot Reload Watch configuration files for changes and automatically reload: ```typescript import { watchConfig } from 'nx-config2'; const watcher = watchConfig('./config.json', { interval: 2000, onChange: (newConfig) => { console.log('⚡ Config reloaded:', newConfig); }, onError: (error) => { console.error('❌ Error:', error); } }); // Stop watching later watcher.stop(); ``` **Hot Reload Features:** - **File Watching**: Monitor configuration files for changes - **Automatic Reload**: Seamlessly reload on file changes - **Error Handling**: Graceful error recovery and reporting - **Performance**: Efficient file change detection - **Memory Management**: Proper cleanup and resource management ### Convict-style API Use a familiar convict-style API for configuration management: ```typescript import { createConfig } from 'nx-config2'; const config = createConfig({ env: { doc: 'The application environment', format: ['production', 'development', 'test'], default: 'development', env: 'NODE_ENV' }, port: { doc: 'The port to bind', format: 'port', default: 8080, env: 'PORT', arg: 'port' } }); config.validate(); console.log(config.get('port')); console.log(config.getProperties()); ``` **Convict-style Features:** - **Familiar API**: Drop-in replacement for convict users - **Schema Definition**: Define configuration schema declaratively - **Validation**: Built-in validation with detailed error messages - **Documentation**: Automatic documentation generation - **Type Safety**: Full TypeScript support - **Environment Integration**: Seamless environment variable handling ### Environment Variable Inspection Inspect and analyze environment variables in your .env files with detailed information: ```typescript import { getEnvVariables } from 'nx-config2'; // Get variables from default .env file const defaultVars = getEnvVariables(); // Get variables from specific environment file const testVars = getEnvVariables('test'); // .env.test const prodVars = getEnvVariables('prod'); // .env.prod const dbVars = getEnvVariables('prod.database'); // .env.prod.database console.log(testVars); // [ // { varName: 'API_KEY', length: 20, synthesizedValue: 'te***89' }, // { varName: 'DB_HOST', length: 18, synthesizedValue: 'test-db.example.com' }, // { varName: 'PASSWORD', length: 25, synthesizedValue: 'su***23' } // ] ``` **Environment Variable Inspection Features:** - **Variable Discovery**: List all variables in any .env file - **Sensitive Data Masking**: Automatically mask passwords, keys, and tokens - **Length Information**: Get original value length for validation - **Multi-Environment Support**: Works with any environment file path - **Safe Inspection**: Sensitive fields are automatically masked - **TypeScript Support**: Full type definitions for variable information --- ## 📖 Complete Examples ### Environment Variable Inspection (NEW!) ```typescript import { getEnvVariables, parseConfig } from 'nx-config2'; // Inspect variables from different environment files const defaultVars = getEnvVariables(); // .env const testVars = getEnvVariables('test'); // .env.test const prodVars = getEnvVariables('prod'); // .env.prod const dbVars = getEnvVariables('prod.database'); // .env.prod.database console.log('Default environment variables:', defaultVars.length); console.log('Test environment variables:', testVars.length); console.log('Production environment variables:', prodVars.length); console.log('Database environment variables:', dbVars.length); // Display variable information with sensitive data masking testVars.forEach(variable => { console.log(`${variable.varName}: ${variable.synthesizedValue} (length: ${variable.length})`); }); // Use in configuration validation const config = parseConfig({ api: { key: 'ENV.TEST.API_KEY', host: 'ENV.TEST.API_HOST' } }); // Verify all required variables exist const requiredVars = ['API_KEY', 'API_HOST']; const missingVars = requiredVars.filter(varName => !testVars.some(v => v.varName === varName) ); if (missingVars.length > 0) { console.error('Missing required variables:', missingVars); } ``` ### Cloud-Native Application ```typescript import { initConfig } from 'nx-config2'; const config = initConfig({ service: { name: 'ENV.SERVICE_NAME', version: 'ENV.APP_VERSION', port: 'ENV.PORT:port||8080', host: 'ENV.HOST||0.0.0.0' }, database: { url: 'ENV.DATABASE_URL', poolSize: 'ENV.DB_POOL_SIZE:nat||10', ssl: 'ENV.DB_SSL:boolean||true' }, redis: { url: 'ENV.REDIS_URL', ttl: 'ENV.REDIS_TTL:duration||1h' }, logging: { level: 'ENV.LOG_LEVEL||info', pretty: 'ENV.LOG_PRETTY:boolean||false' } }, { prefix: 'APP_', requiredVars: ['SERVICE_NAME', 'DATABASE_URL'], dotenvPath: '.env', generateDocs: true, docsPath: './docs/ENV_VARS.md', schema: { port: { type: 'port', min: 1000, max: 65535, doc: 'HTTP server port' } }, verbose: true }); console.log('✅ Configuration loaded successfully!'); ``` ### Multi-Environment Setup ```typescript const env = process.env.NODE_ENV || 'development'; const config = initConfig('./config.json', { dotenvPath: `.env.${env}`, suffix: `_${env.toUpperCase()}`, overrides: { environment: env }, defaults: { LOG_LEVEL: 'info', PORT: '3000' } }); ``` ### Multi-Environment File Setup (NEW!) ```typescript // .env.test file API_KEY=test-api-key-123 DB_HOST=test-db.example.com DB_PORT=5432 // .env.prod.database file HOST=prod-db.example.com PORT=5432 SSL=true // .env.staging.api file KEY=staging-api-key-456 TIMEOUT=30s const config = { // Simple pattern app: { name: 'ENV.APP_NAME||my-app' }, // Test environment test: { apiKey: 'ENV.TEST.API_KEY', dbHost: 'ENV.TEST.DB_HOST', dbPort: 'ENV.TEST.DB_PORT:port' }, // Production database production: { database: { host: 'ENV.PROD.DATABASE.HOST', port: 'ENV.PROD.DATABASE.PORT:port', ssl: 'ENV.PROD.DATABASE.SSL:boolean' } }, // Staging API staging: { api: { key: 'ENV.STAGING.API.KEY', timeout: 'ENV.STAGING.API.TIMEOUT:duration' } } }; const result = initConfig(config, { verbose: true }); ``` ### AWS Configuration with Prefix ```typescript process.env.AWS_ACCESS_KEY_ID = 'AKIA...'; process.env.AWS_SECRET_ACCESS_KEY = 'secret...'; process.env.AWS_REGION = 'us-east-1'; process.env.AWS_LOG_DIR = './aws-logs'; const awsConfig = initConfig({ accessKeyId: 'ENV.ACCESS_KEY_ID', secretAccessKey: 'ENV.SECRET_ACCESS_KEY', region: 'ENV.REGION', logDir: 'ENV.LOG_DIR' }, { prefix: 'AWS_', createDirectories: true, schema: { logDir: { type: 'string', isDirectory: true } } }); ``` ### Multi-Config Production Setup ```typescript import { parseMultiConfig } from 'nx-config2'; // Production environment with multiple config sources const result = parseMultiConfig({ sources: [ './configs/base.json', // Base configuration './configs/database.json', // Database settings './configs/redis.json', // Redis settings './configs/production.json', // Production overrides './configs/secrets.json' // Secret values ], mergeStrategy: 'deep', priority: 'last', dotenvPath: '.env.production', prefix: 'APP_', verbose: true, schema: { port: { type: 'port', required: true, doc: 'HTTP server port' } } }); console.log('🔧 Merged configuration:', result.config); console.log('📊 Resolved variables:', result.resolvedVars); ``` ### Separate Environment Configs ```typescript // Load all environment configs separately const envConfigs = parseMultiConfig({ sources: [ './configs/development.json', './configs/staging.json', './configs/production.json' ], keepSeparate: true, names: ['development', 'staging', 'production'], dotenvPath: '.env', verbose: true }); // Use the appropriate config based on NODE_ENV const env = process.env.NODE_ENV || 'development'; const currentConfig = envConfigs.configs[env]; console.log(`🌍 Using ${env} configuration:`, currentConfig); ``` --- ## 🔧 API Reference ### Core Functions #### `parseConfig<T>(config, options?)` Parse a configuration object and resolve ENV tokens. **Options:** - `strict`: Throw on missing vars (default: `true`) - `verbose`: Log resolved variables (default: `false`) - `dotenvPath`: Load .env file - `prefix`: Prepend to all ENV var names - `suffix`: Append to all ENV var names (env-specific) - `defaults`: Default values for ENV vars - `transform`: Custom transformers - `createDirectories`: Auto-create directories - `commandLineArgs`: Parse from process.argv - `envSeparator`: For nested keys (default: `__`) - `heuristicJsonParsing`: Auto-detect and parse JSON-like strings (default: `true`) - `lenientJson`: Return original string on JSON parse failure instead of throwing (default: `false`) #### `parseMultiConfig<T>(options)` (NEW!) Smart multi-config handling with merge strategies. **Options:** - `sources`: Array of config sources - `mergeStrategy`: How to merge configs ('deep' | 'shallow' | 'override' | 'append') - `keepSeparate`: Keep configs separate (named access) - `names`: Names for each config (if keepSeparate) - `extends`: Base config to extend from - `priority`: Which source has priority ('first' | 'last') - All `parseConfig` options #### `initConfig<T>(config, options?)` One-call initialization with validation. **Additional Options:** - `requiredVars`: Required environment variables - `validateOnInit`: Run validation (default: `true`) - `throwOnMissing`: Throw if vars missing (default: `true`) - `schema`: Schema validation - `generateDocs`: Auto-generate docs - `docsPath`: Where to save docs - `descriptions`: Variable descriptions - `overrides`: Highest priority values - `stores`: Multiple configuration stores #### `remoteConfig<T>(options?)` (NEW!) Initialize configuration from a remote JSON source using `nx-remote-json`. Fetches configuration from disk, S3-compatible storage, or MongoDB, then processes it through the standard `initConfig` pipeline. **Options:** - `remoteJsonConfig`: Configuration for the remote JSON client (see `nx-remote-json` package) - `mode`: Backend mode (`"disk"`, `"storage"`, or `"database"`) - supports `ENV.VARIABLE` pattern - `jsonRouter`: Router name for the remote config - supports `ENV.VARIABLE` pattern - `jsonKey`: Key name for the remote config - supports `ENV.VARIABLE` pattern - All `initConfig` options (except `stores`) **Example:** ```typescript import { remoteConfig } from 'nx-config2'; import { createRemoteJsonClient } from 'nx-remote-json'; const result = await remoteConfig({ remoteJsonConfig: { disk: { rootLocation: "/data/configs", mapping: [{ jsonRouter: "app", folder: "app-configs" }] } }, mode: "disk", jsonRouter: "app", jsonKey: "production" }); console.log(result.config); ``` **Using Environment Variables:** ```typescript // Set environment variables process.env.CONFIG_MODE = "storage"; process.env.CONFIG_ROUTER = "settings"; process.env.CONFIG_KEY = "user-123"; const result = await remoteConfig({ remoteJsonConfig: { storage: { region: "us-east-1", endpoint: "https://s3.amazonaws.com", bucket: "my-bucket", accessKey: process.env.AWS_ACCESS_KEY!, secretKey: process.env.AWS_SECRET_KEY!, mapping: [{ jsonRouter: "settings", folder: "settings" }] } }, mode: "ENV.CONFIG_MODE", // Resolved from process.env.CONFIG_MODE jsonRouter: "ENV.CONFIG_ROUTER", // Resolved from process.env.CONFIG_ROUTER jsonKey: "ENV.CONFIG_KEY" // Resolved from process.env.CONFIG_KEY }); ``` #### `verify(variableNames)` Validate environment variables are set. #### `watchConfig<T>(configPath, options?)` Watch a config file for changes. #### `createConfig<T>(schema)` Create a convict-style config with schema. #### `autoLoadConfig<T>(options?)` (NEW!) Automatically load configuration from environment variables using a default config map plus any additional env vars. **Options:** - `dotenvPath`: Path to .env file (default: `.env`) - `includeAllEnvVars`: Include all env vars not in default config (default: `true`) - `beautify`: Sort and format output nicely (default: `true`) - All `parseConfig` options ### Utility Functions #### `maskSecrets(config, path?, schema?)` Mask sensitive fields in configuration. #### `extractEnvTokens(config)` Extract all ENV tokens from a configuration. #### `generateDocumentation(config, resolvedVars, descriptions?, schema?)` Generate markdown documentation. #### `validateRequiredEnvVars(variableNames)` Validate required environment variables. --- ## 🎨 TypeScript Support Full TypeScript support with generics: ```typescript interface AppConfig { database: { host: string; port: number; }; api: { key: string; timeout: number; }; } const result = initConfig<AppConfig>(config); // result.config is typed as AppConfig ``` --- ## 🌟 Inspired By nxconfig combines the best features from these MIT-licensed packages: 1. **[dotenv](https://github.com/motdotla/dotenv)** - .env file loading 2. **[env-var](https://github.com/evanshortiss/env-var)** - Type coercion & validation 3. **[node-config](https://github.com/node-config/node-config)** - Multi-environment support 4. **[convict](https://github.com/mozilla/node-convict)** - Schema-based validation 5. **[nconf](https://github.com/flatiron/nconf)** - Hierarchical configuration 6. **[xconfig](https://github.com/kaelzhang/node-xconfig)** - Flexible architecture 7. **[envconfig](https://github.com/jsonxr/envconfig)** - Directory validation 8. **[@jondotsoy/envconfig](https://github.com/jondotsoy/envconfig)** - Prefix/suffix, BigInt 9. **[@logdna/env-config](https://github.com/logdna/env-config)** - Documentation generation --- ## 🤝 Contributing Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for details. ## 📄 License MIT © [nx-morpheus](https://github.com/nx-morpheus) --- ## 🔗 Links - [GitHub](https://github.com/nx-morpheus/nxconfig) - [npm](https://www.npmjs.com/package/nx-config2) - [Documentation](https://github.com/nx-morpheus/nxconfig/wiki) - [Changelog](https://github.com/nx-morpheus/nxconfig/blob/main/CHANGELOG.md) --- **Made with ❤️ for the Node.js community** *nxconfig is the only configuration library you'll ever need.*