Skip to content

Repository files navigation

@nestbolt/settings

Database-backed key-value application settings for NestJS with TypeORM.

npm versionnpm downloadstestslicense


This package provides a database-backed settings store for NestJS that lets you manage application configuration at runtime with typed access, in-memory caching, and auto-seeding.

Once installed, using it is as simple as:

constappName=awaitsettingsService.get<string>("app.name","MyApp");awaitsettingsService.set("app.theme","dark");

Table of Contents

Installation

Install the package via npm:

npm install @nestbolt/settings

Or via yarn:

yarn add @nestbolt/settings

Or via pnpm:

pnpm add @nestbolt/settings

Peer Dependencies

This package requires the following peer dependencies, which you likely already have in a NestJS project:

@nestjs/common ^10.0.0 || ^11.0.0
@nestjs/core ^10.0.0 || ^11.0.0
@nestjs/typeorm ^10.0.0 || ^11.0.0
typeorm ^0.3.0
reflect-metadata ^0.1.13 || ^0.2.0

Optional:

@nestjs/event-emitter ^2.0.0 || ^3.0.0

Quick Start

  1. Register the module in your AppModule:
import{SettingsModule}from"@nestbolt/settings";
@Module({imports: [TypeOrmModule.forRoot({/* ... */}),SettingsModule.forRoot({defaults: [{key: "app.name",value: "MyApp",type: "string"},{key: "app.perPage",value: 25,type: "number"},],}),],})exportclassAppModule{}
  1. Inject and use the service:
import{SettingsService}from"@nestbolt/settings";
@Injectable()exportclassAppService{constructor(privatereadonlysettings: SettingsService){}asyncgetAppName(): Promise<string>{returnthis.settings.get<string>("app.name","Default");}asyncupdateTheme(theme: string): Promise<void>{awaitthis.settings.set("app.theme",theme,{group: "appearance"});}}

Module Configuration

Static Configuration (forRoot)

SettingsModule.forRoot({cacheTtl: 60000,// 1 minute cache (default)autoSeed: true,// Auto-seed defaults (default: true)defaults: [{key: "app.name",value: "MyApp",type: "string",group: "app"},{key: "app.debug",value: false,type: "boolean",group: "app"},{key: "mail.from",value: "noreply@example.com",type: "string",group: "mail",},],});

Async Configuration (forRootAsync)

SettingsModule.forRootAsync({imports: [ConfigModule],inject: [ConfigService],useFactory: (config: ConfigService)=>({cacheTtl: config.get("SETTINGS_CACHE_TTL",60000),defaults: [{key: "app.name",value: config.get("APP_NAME"),type: "string"},],}),});

The module is registered as globalSettingsService is available everywhere without re-importing.

Using the Service

Inject SettingsService into any service or controller:

MethodReturnsDescription
get<T>(key, default?)Promise<T>Get a setting value, returns default if not found
getOrFail<T>(key)Promise<T>Get a setting value, throws SettingNotFoundException if not found
set(key, value, options?)Promise<SettingEntity>Create or update a setting
has(key)Promise<boolean>Check if a setting exists
forget(key)Promise<void>Delete a setting
all()Promise<Record<string, any>>Get all settings as a key-value map
group(name)Promise<Record<string, any>>Get all settings in a group
flushCache()voidClear the in-memory cache

Setting Types

Settings support four types with automatic casting:

TypeStored AsCast To
stringtextstring
numbertextNumber()
booleantexttrue/"1" = true, else false
jsontextJSON.parse()
awaitsettings.set("app.port",3000,{type: "number"});awaitsettings.set("app.debug",true,{type: "boolean"});awaitsettings.set("app.config",{theme: "dark"},{type: "json"});

If no type is specified, it is inferred from the value.

Setting Groups

Organize settings by group for easy retrieval:

awaitsettings.set("mail.host","smtp.example.com",{group: "mail"});awaitsettings.set("mail.port","587",{group: "mail"});constmailSettings=awaitsettings.group("mail");// { 'mail.host': 'smtp.example.com', 'mail.port': '587' }

Caching

Settings are cached in memory with a configurable TTL (default: 60 seconds). Set cacheTtl: 0 to disable caching.

The cache is automatically invalidated when you call set() or forget(). Use flushCache() to manually clear it.

Auto-Seeding

When autoSeed is enabled (default), the module seeds any defaults that don't already exist in the database during initialization. Existing settings are never overwritten.

Events

When @nestjs/event-emitter is installed, the following events are emitted:

EventPayload
settings.created{ key, value, type, group }
settings.updated{ key, oldValue, newValue, type }
settings.deleted{ key, lastValue }

Configuration Options

OptionTypeDefaultDescription
defaultsSettingDefinition[]undefinedDefault settings to seed on init
cacheTtlnumber60000Cache TTL in ms (0 to disable)
autoSeedbooleantrueAuto-seed defaults if keys don't exist

Testing

npm test

Run tests in watch mode:

npm run test:watch

Generate coverage report:

npm run test:cov

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

If you discover any security-related issues, please report them via GitHub Issues with the security label instead of using the public issue tracker.

License

The MIT License (MIT). Please see License File for more information.

About

Database-backed key-value application settings for NestJS with TypeORM, typed access, caching, and auto-seeding.

Topics

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages