
Security News
Rust RFC Proposes a Security Tab on crates.io for RustSec Advisories
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.
@vinsidious/nestjs-config
Advanced tools
Configuration component for NestJs.
This is a fork of the original nestjs-config which has been modified to use dotenv-flow instead of dotenv.
Yarn
yarn add nestjs-config
NPM
npm install nestjs-config --save
Let's imagine that we have a folder called config in our project under src
/src
├── app.module.ts
├── config
│ ├── express.ts
│ ├── graphql.ts
│ └── grpc.ts
Let's register the config module in app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from "nestjs-config";
@Module({
imports: [
ConfigModule.load(),
],
})
export class AppModule {}
That's it!
Now let's say that your application isn't in a folder called src, it's in ./app.
import * as path from 'path';
import { Module } from '@nestjs/common';
import { ConfigModule } from "nestjs-config";
@Module({
imports: [
ConfigModule.load(
path.resolve(__dirname, 'config/**/*.{ts,js}')
),
],
})
export class AppModule {}
We provide as first argument the glob of our interested configuration that we want to load.
For example project has the next structure:
/
├── dist/
├── src/
│ ├── app/
│ │ ├── app.module.ts
│ │ └── bootstrap/
│ │ │ ├── index.ts
│ │ │ └── bootstrap.module.ts
│ ├── migrations/
│ ├── cli/
│ ├── config/
│ │ ├── app.ts
│ │ └── database.ts
│ └── main.ts
├── tsconfig.json
└── package.json
On this example, config files are located near the app folder, because they are shared between app, migrations and cli scripts.
Also during typescript compilation all files from src/ folder will be moved to the dist/ folder.
Moreover ConfigModule is imported in BootstrapModule, but not directly in AppModule.
// app.module.ts
import { Module } from '@nestjs/common';
import { BootstrapModule } from "./bootstrap";
@Module({
imports: [BootstrapModule],
})
export class AppModule {}
// bootstrap.module.ts
import * as path from 'path';
import { Module } from '@nestjs/common';
import { ConfigModule } from "nestjs-config";
@Module({
imports: [
ConfigModule.load(path.resolve(__dirname, '../../config/**/*.{ts,js}')),
],
})
export class BootstrapModule {}
We still provide as first argument the glob of our configuration, but an example above looks a little bit ugly.
Also we will always have to remember about this glob path when we want to move the BootstrapModule
to different place.
There is two ways to avoid such situations:
Explicitly set absolute path to the project sources from AppModule and use glob with relative path:
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigService } from "nestjs-config";
import * as path from "path";
import { BootstrapModule } from "./bootstrap";
ConfigService.srcPath = path.resolve(__dirname, '..');
@Module({
imports: [BootstrapModule],
})
export class AppModule {}
// bootstrap.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from "nestjs-config";
@Module({
imports: [
ConfigModule.load('config/**/*.{ts,js}')
],
})
export class BootstrapModule {}
Invoke ConfigModule.resolveSrcPath(__dirname) from any your module before config loading and use glob with relative path.
// bootstrap.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from "nestjs-config";
@Module({
imports: [
ConfigModule.resolveSrcPath(__dirname).load('config/**/*.{ts,js}')
],
})
export class BootstrapModule {}
On these examples we provide as first argument the glob of our configuration, but it is relative to the src/ folder.
This package ship with the amazing dotenv so that you can create
a .env file in your preferred location.
let's create one!
# .env
EXPRESS_PORT=3000
now in our src/config/express.ts file we can refer to that environment variable
// src/config/express.ts
export default {
port: process.env.EXPRESS_PORT
}
Note: By default the package look for a .env file in the path that you started your server from.
If you want to specify a path for your .env file use the second parameter of ConfigModule.load.
Now we are ready to inject our ConfigService everywhere we'd like.
import {ConfigService} from 'nestjs-config'
@Injectable()
class SomeService {
constructor(private readonly config: ConfigService) {
this.config = config;
}
isProduction() {
const env = this.config.get('app.environment');
return env === 'production';
}
}
You can also use the @InjectConfig decorator instead, as following:
import {InjectConfig} from 'nestjs-config';
@Injectable()
class SomeService {
constructor(@InjectConfig() private readonly config) {
this.config = config;
}
}
This feature allows you to create small helper function that computes values from configurations.
example isProduction helper:
// src/config/express.ts
export default {
environment: process.env.EXPRESS_PORT
port: process.env.EXPRESS_PORT,
// helpers
isProduction() {
return this.get('express.environment') === 'production';
}
}
usage:
this.config.get('express').isProduction();
// or
this.config._isProduction(); // note the underscore prefix.
Global Helpers
You can also attach helpers to the global instance as follow:
this.config.registerHelper('isProduction', () => {
return this.get('express.environment') === 'production';
});
Then use it:
this.config.isProduction();
Get a configuration value via path, you can use dot notation to traverse nested object.
this.config.get('server.port'); // 3000
Set a value at runtime, it creates one if doesn't exists.
this.config.set('server.port', 2000); // {server:{ port: 2000 }}
Determine if the given path for a configuration exists and set
this.config.has('server.port'); // true or false
You can load other configuration at runtime. Great for package development.
@Module({})
export class PackageModule implements NestModule {
constructor(@InjectConfig() private readonly config) {}
async configure(consumer: MiddlewareConsumer) {
await this.config.merge(path.join(__dirname, '**/*.config.{ts,js}'));
}
}
Register custom global helper
this.config.registerHelper('isProduction', () => {
return this.get('express.environment') === 'production';
});
It's possible to use decorators instead of injecting the ConfigService.
But note that @Configurable() decorator replaces descriptor.value for the
method with own function. Regarding to the current nestjs implementation
(Issue-1180) this behavior will
break all decorators that follow after Configurable() decorator.
For the right behavior @Configurable() decorator MUST be placed at
the last place when you use several decorators for one method.
Working example:
import {Injectable, Get} from '@nestjs/common';
import {Configurable, ConfigParam} from 'nestjs-config';
@Injectable()
export default class UserController {
@Get("/")
@Configurable()
index(@ConfigParam('my.parameter', 'deafult value') parameter?: string) {
return { data: parameter };
}
}
Broken example:
import {Injectable, Get, UseInterceptors} from '@nestjs/common';
import {Configurable, ConfigParam} from 'nestjs-config';
import {TransformInterceptor} from '../interceptors';
@Injectable()
export default class UserController {
@Configurable()
@Get("/") // <-- nestjs decorator won't work because it placed after @Configurable()
@UseInterceptors(TransformInterceptor)// <-- nestjs decorator won't work because it placed after @Configurable()
index(@ConfigParam('my.parameter', 'deafult value') parameter?: string) {
return { data: parameter };
}
}
Broken example 2:
import {Injectable, Get, UseInterceptors} from '@nestjs/common';
import {Configurable, ConfigParam} from 'nestjs-config';
import {TransformInterceptor} from '../interceptors';
@Injectable()
export default class UserController {
@Get("/") // <-- nestjs decorator will work fine because it placed after @Configurable()
@Configurable()
@UseInterceptors(TransformInterceptor) // <-- nestjs decorator won't work because it placed after @Configurable()
index(@ConfigParam('my.parameter', 'deafult value') parameter?: string) {
return { data: parameter };
}
}
Usage with typeorm requires the use of the forRootAsync function supplied by the typeorm package for nestjs
import {Module} from '@nestjs/common';
import {ConfigModule, ConfigService} from 'nestjs-config';
import {TypeOrmModule} from '@nestjs/typeorm';
import * as path from 'path';
@Module({
imports: [
ConfigModule.load(path.resolve(__dirname, 'config/**/*.{ts,js}')),
TypeOrmModule.forRootAsync({
useFactory: (config: ConfigService) => config.get('database'),
inject: [ConfigService],
}),
],
})
export default class AppModule {}
And your config file:
//config/database.ts
export default {
type: 'mysql',
host: process.env.DB_HOST,
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
port: parseInt(process.env.DB_PORT),
};
Built from Fenos, Shekohex and Bashleigh
FAQs
Easy to use Nest congifuration module
We found that @vinsidious/nestjs-config demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.

Security News
/Research
Socket found a Rust typosquat (finch-rust) that loads sha-rust to steal credentials, using impersonation and an unpinned dependency to auto-deliver updates.

Research
/Security Fundamentals
A pair of typosquatted Go packages posing as Google’s UUID library quietly turn helper functions into encrypted exfiltration channels to a paste site, putting developer and CI data at risk.