nestjs-zod-config
v2.4.0
Published
NestJS module to load, type and validate configuration using Zod
Downloads
130
Maintainers
Readme
NestJS Zod Config
nestjs-zod-config - NestJS module to load, type and validate configuration using Zod. Insied and outside the NestJS context.
Installation
yarn add nestjs-zod-config
Peer dependencies:
yarn add @nestjs/common zod
Setup
The first thing that we need to do is to create a config class that extends ZodConfig
and pass it our Zod schema.
// app.config.ts
import { ZodConfig } from 'nestjs-zod-config';
import { z } from 'zod';
const appConfigSchema = z.object({
HOSTNAME: z.string().min(1).default('0.0.0.0'),
PORT: z.coerce.number().default(3000),
});
export class AppConfig extends ZodConfig(appConfigSchema) {}
This assumes that you have a
.env
file in the root of your project or that you have set the environment variables inprocess.env
in some other way.
✨ All done. Let's see how we can use it.
Then we need to register the config class in our module.
Usage
Inside NestJS context
We will have to register the config class in a module:
// app.module.ts
import { Module } from '@nestjs/common';
import { ZodConfigModule } from 'nestjs-zod-config';
import { AppConfig } from './app.config';
@Module({
imports: [
ZodConfigModule.forRoot({
config: AppConfig,
isGlobal: true, // optional, defaults to `false`
}),
],
})
export class AppModule {}
It is recommended to register the config class in the root module of your application.
Now we can inject AppConfig
in your services like this:
// app.service.ts
import { Injectable } from '@nestjs/common';
import { AppConfig } from './app.config';
@Injectable()
export class AppService {
constructor(private readonly appConfig: AppConfig) {}
getPort(): number {
return this.appConfig.get('PORT');
}
}
or in our main.ts
, like this:
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppConfig } from './app.config';
import { AppModule } from './app.module';
const main = async () => {
const app = await NestFactory.create(AppModule);
const appConfig = app.get(AppConfig);
const hostname = appConfig.get('HOSTNAME');
const port = appConfig.get('PORT');
await app.listen(port, hostname);
};
void main();
Outside NestJS context
There are cases where we need to access the config outside the NestJS context. For example, we might want to use the config in a seeder script:
// seed.ts
import { loadZodConfig } from 'nestjs-zod-config';
const seedDb = async () => {
const appConfig = loadZodConfig(AppConfig);
const databaseurl = appConfig.get('DATABASE_URL');
// use the `databaseurl` to connect to the database and seed it
};
In this case we cannot inject the
AppConfig
and we don't have access to theapp
instance. The file is executed outside the NestJS context.
Testing
yarn test
Roadmap
- [ ] Provide a way to customize the env loader. Useful when different name, format or location of the env file is needed.
- [ ] Provide async methods to load the config.
- [ ] Write tests 🧪
Tips and Tricks
Use safeBooleanCoerce
to coerce strings to booleans safely
This is a utility function that can be used to coerce a string value to a boolean in a strict manner.
Normally you will do: z.coerce.boolean()
but this will also coerce the string 'false'
to true
.
So instead we use this function to only allow 'false'
or false
to be coerced to false
, 'true'
or true
to true
and everything else will throw an error.