@sklv-labs/ts-nestjs-cls
v0.1.1
Published
NestJS Async Context Local Storage helper
Maintainers
Readme
@sklv-labs/ts-nestjs-cls
A NestJS module wrapper for nestjs-cls that provides simplified configuration and automatic request ID handling using Continuation Local Storage (CLS).
Features
- 🎯 Type-Safe - Full TypeScript support with comprehensive type definitions
- 🚀 Easy Setup - Simple API for both synchronous and asynchronous configuration
- 🛠️ NestJS Native - Built on top of NestJS with seamless integration
- 📦 Auto Request ID - Automatically extracts or generates request IDs from headers
- 🔌 Plugin Support - Easy integration with additional CLS plugins
- 🌐 Platform Agnostic - Works with both Express and Fastify adapters
Installation
npm install @sklv-labs/ts-nestjs-clsPeer Dependencies
This package requires the following peer dependencies:
npm install @nestjs/common@^11.1.11 @nestjs/core@^11.1.11 nestjs-cls@^6.1.0Note: This package requires Node.js 24 LTS or higher.
Quick Start
// app.module.ts
import { Module } from '@nestjs/common';
import { ClsModule } from '@sklv-labs/ts-nestjs-cls';
@Module({
imports: [
ClsModule.forRoot({
enableMiddleware: true,
}),
],
})
export class AppModule {}Using CLS Service
import { Injectable } from '@nestjs/common';
import { ClsService } from '@sklv-labs/ts-nestjs-cls';
@Injectable()
export class MyService {
constructor(private readonly cls: ClsService) {}
getRequestId(): string | undefined {
return this.cls.get('requestId');
}
}Async Configuration
// app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ClsModule } from '@sklv-labs/ts-nestjs-cls';
@Module({
imports: [
ConfigModule.forRoot(),
ClsModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (config: ConfigService) => ({
enableMiddleware: config.get('CLS_ENABLED') === 'true',
setup: (cls, req) => {
// Custom setup logic
cls.set('customKey', 'customValue');
},
}),
}),
],
})
export class AppModule {}Custom Setup Function
import { ClsModule, ClsService } from '@sklv-labs/ts-nestjs-cls';
import type { Request } from 'express';
@Module({
imports: [
ClsModule.forRoot({
setup: (cls: ClsService, req: Request) => {
// Extract request ID from header
const requestId = req.headers['x-request-id'];
if (requestId) {
cls.set('requestId', Array.isArray(requestId) ? requestId[0] : requestId);
}
// Set additional context
cls.set('userId', req.user?.id);
cls.set('ip', req.ip);
},
}),
],
})
export class AppModule {}Using Plugins
import { ClsModule } from '@sklv-labs/ts-nestjs-cls';
import { ClsPluginRequestId } from 'nestjs-cls';
@Module({
imports: [
ClsModule.forRoot({
plugins: [
new ClsPluginRequestId({
// Plugin configuration
}),
],
}),
],
})
export class AppModule {}API Reference
ClsModule.forRoot(options?: ClsModuleOptions)
Configure the CLS module synchronously.
Options
enableMiddleware?: boolean- Enable CLS middleware (default:true)setup?: (cls: ClsService, req: Request) => void- Custom setup function for CLS contextplugins?: ClsPlugin[]- Additional CLS plugins to register- All other options from
nestjs-clsClsModuleOptionsare supported
ClsModule.forRootAsync(options: ClsModuleAsyncOptions)
Configure the CLS module asynchronously.
Options
imports?: Module[]- Modules to importinject?: Type[]- Dependencies to inject intouseFactoryuseFactory: (...args) => ClsModuleOptions | Promise<ClsModuleOptions>- Factory function returning configuration
Default Behavior
By default, the module:
- Extracts the
x-request-idheader from incoming requests - If no request ID is found, generates a new UUID using
crypto.randomUUID() - Stores the request ID in the CLS context under the key
requestId - Makes the CLS context available globally throughout your application
Development
# Build
npm run build
# Lint
npm run lint
# Format
npm run format
# Test
npm run test
# Type check
npm run type-checkLicense
MIT © sklv-labs
