npm package: @synet/config
Description: Simple, immutable configuration management from multiple sources, supporting environment variables, JSON files, and more. Designed with Unit Architecture.
Author: Synet Team
Latest version: 1.0.0

# @synet/config


```bash
   _____             __ _         _    _       _ _   
  / ____|           / _(_)       | |  | |     (_) |  
 | |     ___  _ __ | |_ _  __ _  | |  | |_ __  _| |_ 
 | |    / _ \| '_ \|  _| |/ _` | | |  | | '_ \| | __|
 | |___| (_) | | | | | | | (_| | | |__| | | | | | |_ 
  \_____\___/|_| |_|_| |_|\__, |  \____/|_| |_|_|\__|
                           __/ |                     
                          |___/                      
version: 1.0.0
```

Simple, immutable configuration management for Node.js applications.

## Installation

```bash
npm install @synet/config
```

## Quick Start

```typescript
import { Config } from '@synet/config';

// Load from environment variables
const config = Config.fromEnv();
console.log(config.get('NODE_ENV', 'development'));

// Load from JSON
const jsonConfig = Config.fromJSON('{"port": 3000, "debug": true}');
console.log(jsonConfig.get('port')); // 3000

// Merge configurations
const merged = config.merge(jsonConfig);
```

## Features

- **Immutable** - All operations return new instances
- **Type-safe** - Full TypeScript support with generics
- **Multi-source** - Environment variables, JSON, and objects
- **Zero dependencies** - Lightweight and secure
- **Chainable** - Fluent API for configuration composition

## API Reference

### Static Methods

#### `Config.create(options?)`
Create a config instance with optional initial data.

```typescript
const config = Config.create({
  name: 'AppConfig',
  data: { debug: true, port: 3000 }
});
```

#### `Config.fromEnv(prefix?)`
Load configuration from environment variables.

```typescript
// Load all environment variables
const envConfig = Config.fromEnv();

// Load only variables with specific prefix
const appConfig = Config.fromEnv('APP_');
// APP_NAME=myapp becomes { name: 'myapp' }
```

#### `Config.fromJSON(jsonString)`
Parse JSON string into configuration.

```typescript
const config = Config.fromJSON(`{
  "database": {"host": "localhost", "port": 5432},
  "cache": {"ttl": 3600}
}`);
```

#### `Config.fromObject(object, name?)`
Create configuration from object.

```typescript
const config = Config.fromObject({
  debug: true,
  features: ['auth', 'logging']
}, 'MyConfig');
```

### Instance Methods

#### `get<T>(key, defaultValue?): T`
Retrieve configuration value with optional default.

```typescript
const port = config.get<number>('port', 3000);
const debug = config.get<boolean>('debug', false);
```

#### `has(key): boolean`
Check if configuration key exists.

```typescript
if (config.has('database')) {
  // Database configuration is available
}
```

#### `getAll(): Record<string, unknown>`
Get all configuration data as an object.

```typescript
const allConfig = config.getAll();
console.log(JSON.stringify(allConfig, null, 2));
```

#### `keys(): string[]`
Get array of all configuration keys.

```typescript
const configKeys = config.keys();
console.log('Available settings:', configKeys);
```

#### `merge(other): Config`
Create new configuration by merging with another config.

```typescript
const envConfig = Config.fromEnv();
const fileConfig = Config.fromJSON(jsonString);
const merged = envConfig.merge(fileConfig);
// Later values override earlier ones
```

#### `toJSON(): object`
Export configuration data and metadata.

```typescript
const exported = config.toJSON();
// Includes: unitId, version, name, data, source, created
```

### Properties

- `name: string` - Configuration name
- `size: number` - Number of configuration keys
- `source: 'env' | 'json' | 'object'` - Configuration source type

## Common Patterns

### Environment-based Configuration

```typescript
// Load environment-specific config
const config = Config.fromEnv()
  .merge(Config.fromJSON(fs.readFileSync(`config/${process.env.NODE_ENV}.json`, 'utf8')));

const dbUrl = config.get('DATABASE_URL');
const port = config.get<number>('PORT', 3000);
```

### Layered Configuration

```typescript
// Base config
const defaults = Config.fromObject({
  timeout: 5000,
  retries: 3,
  debug: false
});

// Environment overrides
const envConfig = Config.fromEnv('APP_');

// Runtime overrides
const runtime = Config.fromObject({
  timestamp: Date.now()
});

// Final configuration
const config = defaults.merge(envConfig).merge(runtime);
```

### Configuration Validation

```typescript
const config = Config.fromEnv();

// Type-safe access with defaults
const port = config.get<number>('PORT', 3000);
const host = config.get<string>('HOST', 'localhost');

// Existence checks
if (!config.has('DATABASE_URL')) {
  throw new Error('DATABASE_URL is required');
}
```

## TypeScript Support

Full TypeScript support with generic type inference:

```typescript
interface AppConfig {
  port: number;
  host: string;
  debug: boolean;
  features: string[];
}

const config = Config.fromJSON(jsonString);

const port = config.get<number>('port', 3000);     // number
const host = config.get<string>('host');           // string | undefined  
const debug = config.get<boolean>('debug', false); // boolean
const features = config.get<string[]>('features'); // string[] | undefined
```

## Error Handling

The library throws clear, actionable errors:

```typescript
try {
  const config = Config.fromJSON('invalid json');
} catch (error) {
  console.error(error.message); // "[config] Invalid JSON: ..."
}
```

## Performance

- **Lightweight** - Zero external dependencies
- **Fast** - Simple object operations, no complex parsing
- **Memory efficient** - Immutable operations reuse data where possible

## License

MIT