nestjs-config-validator
Version:
Advanced configuration validator for NestJS with type-safe schema validation and full TypeScript type inference
217 lines (165 loc) • 5.19 kB
Markdown
# Migration Guide: v2.0.0 → v2.1.0
## Overview
Version 2.1.0 introduces full TypeScript type inference, providing compile-time type safety for your configuration access. This is a **backward compatible** release - existing code will continue to work.
## What's New?
### Before (v2.0.0)
```typescript
// ❌ No type safety
const config = createNestJSConfiguration(configSchema);
const port = configService.get('app').port; // type: any
```
### After (v2.1.0)
```typescript
// ✅ Full type safety with autocomplete!
const { config, paths } = createTypedConfig<typeof configSchemas>(rootSchema);
const port = configService.get(CONFIG_PATHS.APP).port; // type: number
```
## Migration Steps
### Step 1: Update Your Schemas
Add `as const satisfies ConfigSchema` to your schema definitions:
```typescript
// Before
export const appSchema = {
name: 'app',
type: 'object',
properties: [...]
};
// After
export const appSchema = {
name: 'app',
type: 'object',
properties: [...]
} as const satisfies ConfigSchema;
```
### Step 2: Create Schema Array
Combine your schemas into a typed array:
```typescript
export const configSchemas = [
databaseSchema,
redisSchema,
appSchema,
// ... other schemas
] as const;
export const rootConfigSchema = {
description: 'Application Configuration',
properties: configSchemas
};
```
### Step 3: Use createTypedConfig
Replace `createNestJSConfiguration` with `createTypedConfig`:
```typescript
// Before
import { createNestJSConfiguration } from 'nestjs-config-validator';
export const getConfig = () => createNestJSConfiguration(rootSchema);
// After
import { createTypedConfig } from 'nestjs-config-validator';
const typedConfig = createTypedConfig<typeof configSchemas>(rootConfigSchema);
export const CONFIG_PATHS = typedConfig.paths;
export const getConfig = () => typedConfig.config;
```
### Step 4: Update Your Usage
Use the new `CONFIG_PATHS` for type-safe access:
```typescript
// Before
const port = configService.get('app').port; // type: any
// After
import { CONFIG_PATHS } from './config';
const port = configService.get(CONFIG_PATHS.APP).port; // type: number ✨
```
## Benefits
### 1. IDE Autocomplete
Your IDE will now show all available configuration properties:
```typescript
configService.get(CONFIG_PATHS.APP). // IDE shows: port, environment, cors, etc.
```
### 2. Compile-Time Type Checking
TypeScript will catch errors at compile time:
```typescript
const port: string = configService.get(CONFIG_PATHS.APP).port;
// ❌ Error: Type 'number' is not assignable to type 'string'
```
### 3. Enum Type Inference
Enum values become literal union types:
```typescript
const env = configService.get(CONFIG_PATHS.APP).environment;
// type: 'development' | 'production' | 'staging'
```
## Backward Compatibility
If you prefer to keep using v2.0.0 style:
```typescript
import { createNestJSConfiguration } from 'nestjs-config-validator';
// This still works! No migration required.
export const getConfig = () => createNestJSConfiguration(rootSchema);
```
## Full Example
```typescript
// config.schema.ts
import { ConfigSchema } from 'nestjs-config-validator';
export const appSchema = {
name: 'app',
type: 'object',
properties: [
{
name: 'port',
type: 'number',
defaultValue: 3000
},
{
name: 'environment',
type: 'enum',
enum: ['development', 'production'],
defaultValue: 'development'
}
]
} as const satisfies ConfigSchema;
export const databaseSchema = {
name: 'database',
type: 'object',
properties: [
{ name: 'host', type: 'string', required: true },
{ name: 'port', type: 'number', defaultValue: 5432 }
]
} as const satisfies ConfigSchema;
export const configSchemas = [appSchema, databaseSchema] as const;
export const rootConfigSchema = {
description: 'Application Configuration',
properties: configSchemas
};
```
```typescript
// config.ts
import { createTypedConfig } from 'nestjs-config-validator';
import { rootConfigSchema, configSchemas } from './config.schema';
const typedConfig = createTypedConfig<typeof configSchemas>(rootConfigSchema);
export const CONFIG_PATHS = typedConfig.paths;
export const getConfig = () => typedConfig.config;
```
```typescript
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { getConfig } from './config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [getConfig],
cache: true,
}),
],
})
export class AppModule {}
```
```typescript
// main.ts
import { ConfigService } from '@nestjs/config';
import { CONFIG_PATHS } from './config';
const configService = app.get(ConfigService);
// ✅ Full type safety!
const port = configService.get(CONFIG_PATHS.APP).port; // type: number
const env = configService.get(CONFIG_PATHS.APP).environment; // type: 'development' | 'production'
const dbHost = configService.get(CONFIG_PATHS.DATABASE).host; // type: string
```
## Questions?
If you have any questions or issues with the migration, please [open an issue](https://github.com/Dovlan1990/nestjs-config-validation/issues).
Happy coding! 🚀