Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 2 additions & 31 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: CI
name: Build

on:
push:
Expand Down Expand Up @@ -34,33 +34,4 @@ jobs:
run: yarn build

- name: Run tests
run: yarn test


# publish:
# needs: build-and-test
# if: github.event_name == 'push' && github.ref == 'refs/heads/main'
# runs-on: ubuntu-latest
#
# steps:
# - uses: actions/checkout@v5
#
# - name: Enable Corepack
# run: corepack enable
#
# - name: Use Node.js
# uses: actions/setup-node@v5
# with:
# node-version: '20.x'
# registry-url: 'https://registry.npmjs.org'
#
# - name: Install dependencies
# run: yarn install --immutable
#
# - name: Build packages
# run: yarn build
#
# - name: Publish to NPM
# run: yarn publish:packages
# env:
# NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
run: yarn test
31 changes: 31 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: publish.yml
on:
release:
types: [ published ]

jobs:
publish:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v5

- name: Enable Corepack
run: corepack enable

- name: Use Node.js
uses: actions/setup-node@v5
with:
node-version: '20.x'
registry-url: 'https://registry.npmjs.org'

- name: Install dependencies
run: yarn install --immutable

- name: Build packages
run: yarn build

- name: Publish to NPM
run: yarn publish:packages
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }}
1 change: 1 addition & 0 deletions .yarnrc.yml
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
nodeLinker: node-modules

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,6 @@ MIT © Ganesan Arunachalam
## Support

- 📚 [Documentation](./packages/core/README.md)
- 💬 [GitHub Issues](https://github.com/snow-tzu/type-config/issues)
- 💬 [GitHub Issues](https://github.com/ganesanarun/type-config/issues)
- 📧 [Email Support](mailto:support@example.com)
- 💡 [Examples](./examples)
40 changes: 27 additions & 13 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ Basic Express.js application using Type Config.

- Express middleware integration
- Profile-based configuration
- Hot reload support
- Type-safe configuration classes

**Start:** `cd express-basic && yarn dev`
Expand All @@ -27,7 +26,6 @@ Basic Fastify application using Type Config.

- Fastify plugin integration
- Profile-based configuration
- Hot reload support
- Type-safe configuration classes
- Async/await support

Expand All @@ -44,7 +42,6 @@ Basic NestJS application using Type Config.
- NestJS module integration
- Dependency injection
- Profile-based configuration
- Hot reload support
- Type-safe configuration classes

**Start:** `cd nestjs-basic && yarn dev`
Expand All @@ -57,8 +54,7 @@ NestJS application with remote configuration server support.

**Features:**

- Remote Spring Cloud Config Server integration
- Automatic config refresh with polling
- Remote Consul integration
- Fallback to local configuration
- Bearer token authentication
- Manual refresh endpoint
Expand All @@ -85,14 +81,39 @@ Pure Node.js application (no framework) using Type Config Core.
- Direct ConfigManager API usage
- Built-in HTTP server
- Profile-based configuration
- Hot reload support
- Graceful shutdown handling
- No framework dependencies

**Start:** `cd nodejs-basic && yarn dev`

---

### 6. Nested Configuration Classes (`nested-basic/`)

NestJS application demonstrating nested configuration classes with full decorator support.

**Features:**

- **Single-level nesting**: Configuration classes containing other configuration classes
- **Multi-level nesting**: Configuration classes nested multiple levels deep (e.g., `app.server.ssl`)
- **@DefaultValue decorator**: Default values on nested class properties
- **@Required decorator**: Required validation on nested class properties
- **@Validate() decorator**: class-validator integration on nested classes
- **Optional @ConfigProperty**: Properties bind without @ConfigProperty when names match
- **Profile-specific configuration**: Different values for development and production

**Start:** `cd nested-basic && yarn dev`

**Production:** `NODE_ENV=production yarn dev`

**Key Concepts:**
- Nested classes provide modularity and type safety for complex configurations
- All decorators work recursively at all nesting levels
- No @ConfigProperty needed when property names match configuration keys
- Validation errors include full property paths for easy debugging

---

## Quick Start

### Install All Dependencies
Expand Down Expand Up @@ -210,13 +231,6 @@ Each example uses a specific package:

## Testing Configuration Changes

### Hot Reload (Development)

1. Start any example with `yarn dev`
2. Modify the config file (e.g., `config/application.yml`)
3. Watch the console for reload message
4. Visit the `/config` endpoint to see changes

### Profile Switching

```bash
Expand Down
5 changes: 5 additions & 0 deletions examples/nested-basic/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules/
dist/
*.log
.DS_Store
*.tsbuildinfo
185 changes: 185 additions & 0 deletions examples/nested-basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
# Nested Configuration Classes Example

This example demonstrates the use of nested configuration classes with full decorator support in Type Config.

## Features Demonstrated

- **Single-level nesting**: Configuration classes containing other configuration classes
- **Multi-level nesting**: Configuration classes nested multiple levels deep
- **@DefaultValue decorator**: Default values on nested class properties
- **@Required decorator**: Required validation on nested class properties
- **@Validate() decorator**: class-validator integration on nested classes
- **Optional @ConfigProperty**: Properties bind without @ConfigProperty when names match
- **Profile-specific configuration**: Different values for development and production

## Configuration Structure

```
AppConfig (root)
├── server: ServerConfig
│ └── ssl: SslConfig (2-level nesting)
├── database: DatabaseConfig
│ └── pool: PoolConfig (2-level nesting)
└── services: ServicesConfig
├── api: ApiConfig
└── cache: CacheConfig
```

## Running the Example

### Development Mode

```bash
# Install dependencies (from workspace root)
yarn install

# Run in development mode
cd examples/nested-basic
yarn dev
```

### Production Mode

```bash
# Build the application
yarn build

# Run in production mode
yarn start:prod
```

## Configuration Files

- `config/application.yml` - Base configuration with defaults
- `config/application-production.yml` - Production overrides

## Key Concepts

### 1. Nested Classes Without @ConfigProperty

When property names match configuration keys, @ConfigProperty is optional:

```typescript
@ConfigurationProperties('app')
class AppConfig {
server: ServerConfig; // No @ConfigProperty needed!
database: DatabaseConfig;
}
```

### 2. Decorators Work at All Levels

All decorators (@DefaultValue, @Required, @Validate) work on nested classes:

```typescript
class PoolConfig {
@DefaultValue(10)
maxConnections: number; // Default applied even though it's nested
}

class DatabaseConfig {
pool: PoolConfig; // Nested class with decorators
}
```

### 3. Multi-Level Nesting

Nest as deeply as needed:

```typescript
class SslConfig {
@DefaultValue(false)
enabled: boolean;
}

class ServerConfig {
ssl: SslConfig; // Level 2
}

class AppConfig {
server: ServerConfig; // Level 1
}
```

### 4. Validation on Nested Classes

Use @Validate() on nested classes for comprehensive validation:

```typescript
@Validate()
class ApiConfig {
@IsUrl()
@Required()
endpoint: string;

@IsNumber()
@Min(1000)
@DefaultValue(5000)
timeout: number;
}
```

## Expected Output

When you run the example, you'll see:

```
🚀 Application Configuration Loaded
📝 Profile: development

=== Server Configuration ===
Host: localhost
Port: 3000
SSL Enabled: false
SSL Cert Path: ./certs/cert.pem

=== Database Configuration ===
Host: localhost
Port: 5432
Username: dev_user
Max Connections: 10
Min Connections: 2

=== Services Configuration ===
API Endpoint: https://api.example.com
API Timeout: 5000ms
Cache Host: localhost
Cache Port: 6379
Cache TTL: 3600s

🚀 Server running on http://localhost:3000
```

## Migration Example

This example also shows how to migrate from plain objects to nested classes:

**Before** (plain object):
```typescript
@ConfigurationProperties('app')
class AppConfig {
@ConfigProperty('database')
database: any; // Plain object, no type safety or decorators
}
```

**After** (nested class):
```typescript
class DatabaseConfig {
@Required()
host: string;

@DefaultValue(5432)
port: number;
}

@ConfigurationProperties('app')
class AppConfig {
database: DatabaseConfig; // Fully typed with decorator support!
}
```

## Learn More

- [Type Config Documentation](../../packages/core/README.md)
- [Configuration File Management](../../packages/core/CONFIG_FILES.md)
25 changes: 25 additions & 0 deletions examples/nested-basic/config/application-production.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
app:
server:
host: 0.0.0.0
port: 8080
ssl:
enabled: true
certPath: /etc/ssl/certs/app-cert.pem

database:
host: prod-db.example.com
port: 5432
username: prod_user
password: prod_secure_pass
pool:
maxConnections: 50
minConnections: 5

services:
api:
timeout: 10000

cache:
host: prod-cache.example.com
port: 6379
ttl: 7200
3 changes: 3 additions & 0 deletions examples/nested-basic/config/application.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
app:
database:
host: ${DB_HOST:localhost}
Loading