@brdene95/nestjs-shared-lib
v1.0.2
Published
Comprehensive NestJS shared library with authentication guards, utilities, interceptors, and infrastructure modules for microservices architecture
Maintainers
Readme
NestJS Shared Library
A comprehensive shared library for NestJS microservices providing authentication guards, utilities, DTOs, base classes, common patterns, and infrastructure modules.
Installation
npm install @brdene95/nestjs-shared-libOr with Yarn:
yarn add @brdene95/nestjs-shared-libFeatures
- 🔐 Authentication Guards: JWT, RPC token validation, permissions, roles
- 🛡️ Base Classes: CRUD services and controllers with standard patterns
- 📝 DTOs: Common data transfer objects for pagination, validation, messaging
- 🔧 Utilities: Crypto, date, string, validation helpers
- 🎯 Decorators: Public routes, permissions, roles, current user
- 🚀 Interceptors: Logging, caching, timeout, response transformation
- 📏 Pipes: Validation, UUID parsing, string trimming
- 🔗 Interfaces: Type definitions for auth, microservices, base entities
- ⚙️ Constants: Auth, HTTP, microservice configuration constants
- 📊 Logger Module: Enhanced logging with context and formatting
- ⏰ Scheduler Module: Cron jobs and scheduled tasks management
- 📋 Swagger Utilities: API documentation helpers and decorators
- 🌍 I18n Module: Internationalization and localization support
- 🗄️ MongoDB Module: MongoDB database connectivity and operations
- 🐰 RabbitMQ Module: Message queue operations and patterns
- 🔴 Redis Module: Caching and session management
- 🔌 WebSocket Module: Real-time communication support
Quick Start
1. Authentication Guards
import { ExternalTokenRpcGuard, PermissionGuard } from '@brdene95/nestjs-shared-lib';
@Controller('users')
@UseGuards(ExternalTokenRpcGuard, PermissionGuard)
export class UsersController {
@Get()
@RequirePermissions('users.read')
findAll() {
// Your code here
}
}2. Base CRUD Service
import { BaseCrudService } from '@brdene95/nestjs-shared-lib';
@Injectable()
export class UsersService extends BaseCrudService<User, CreateUserDto, UpdateUserDto> {
protected readonly modelName = 'User';
constructor(private repository: UserRepository) {
super(repository);
}
protected buildWhereClause(search?: string, filters?: any): any {
const conditions = [];
if (search) {
conditions.push(CrudUtils.buildSearchConditions(search, ['name', 'email']));
}
return CrudUtils.mergeConditions(...conditions, filters);
}
}3. Infrastructure Modules
Logger Module
import { LoggerModule, LoggerService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [LoggerModule.forRoot('MyService')],
})
export class AppModule {}
// Usage
constructor(private logger: LoggerService) {
this.logger.log('Service initialized');
this.logger.error('Error occurred', error.stack);
this.logger.logRequest('GET', '/api/users', userId, duration);
}Scheduler Module
import { SchedulerModule, SchedulerService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [SchedulerModule],
})
export class AppModule {}
// Usage
constructor(private scheduler: SchedulerService) {
// Add cron job
this.scheduler.addCronJob('daily-report', '0 0 * * *', () => {
console.log('Running daily report');
});
// Add interval
this.scheduler.addInterval('health-check', 60000, () => {
console.log('Health check');
});
}Swagger Configuration
import { createSwaggerConfig, ApiCrudEndpoint, ApiPaginationQuery } from '@brdene95/nestjs-shared-lib';
// In main.ts
const config = createSwaggerConfig({
title: 'My API',
description: 'API Description',
version: '1.0',
bearerAuth: true,
servers: ['http://localhost:3000', 'https://api.example.com'],
});
const document = SwaggerModule.createDocument(app, config.build());
SwaggerModule.setup('api', app, document);
// In controllers
@Get()
@ApiCrudEndpoint('user', 'list')
@ApiPaginationQuery()
async findAll(@Query() query: PaginationDto) {
// Your code here
}I18n Module
import { I18nModule, I18nService, Lang } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
loaderOptions: {
path: path.join(__dirname, 'i18n'),
},
}),
],
})
export class AppModule {}
// Usage
constructor(private i18n: I18nService) {}
@Get('greeting')
async getGreeting(@Lang() lang: string) {
return this.i18n.translate('messages.welcome', { name: 'User' }, lang);
}MongoDB Module
import { MongoDbModule, MongoDbService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [
MongoDbModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
uri: config.get('MONGODB_URI'),
dbName: config.get('MONGODB_DB'),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
// Usage
constructor(private mongodb: MongoDbService) {}
async createUser(user: User) {
const userId = await this.mongodb.insertOne('users', user);
return userId;
}
async findUsers(filter: any) {
return this.mongodb.find('users', filter);
}RabbitMQ Module
import { RabbitMQModule, RabbitMQService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [
RabbitMQModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
url: config.get('RABBITMQ_URL'),
exchange: 'my-exchange',
queue: 'my-queue',
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
// Usage
constructor(private rabbitmq: RabbitMQService) {}
// Publish message
await this.rabbitmq.publish({
type: 'user.created',
data: { userId: '123', email: '[email protected]' }
});
// Subscribe to messages
await this.rabbitmq.subscribe(async (message) => {
console.log('Received:', message);
});
// RPC pattern
const response = await this.rabbitmq.rpcCall('auth-queue', {
type: 'validate.token',
data: { token: 'jwt-token' }
});Redis Module
import { RedisModule, RedisService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [
RedisModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
host: config.get('REDIS_HOST'),
port: config.get('REDIS_PORT'),
password: config.get('REDIS_PASSWORD'),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
// Usage
constructor(private redis: RedisService) {}
// Cache operations
await this.redis.set('user:123', userData, 3600); // TTL: 1 hour
const user = await this.redis.get('user:123');
await this.redis.del('user:123');
// Hash operations
await this.redis.hset('session:123', 'userId', '456');
const userId = await this.redis.hget('session:123', 'userId');
// List operations
await this.redis.lpush('queue:tasks', task);
const nextTask = await this.redis.rpop('queue:tasks');
// Pub/Sub
await this.redis.publish('notifications', { type: 'alert', message: 'Hello' });
await this.redis.subscribe('notifications', (channel, message) => {
console.log(`Received on ${channel}:`, message);
});WebSocket Module
import { WebSocketModule, WebSocketService } from '@brdene95/nestjs-shared-lib';
@Module({
imports: [WebSocketModule],
})
export class AppModule {}
// Usage
constructor(private websocket: WebSocketService) {}
// Send to specific user
this.websocket.sendToUser(userId, 'notification', {
type: 'message',
content: 'You have a new message'
});
// Broadcast to all
this.websocket.broadcast('announcement', {
message: 'System maintenance in 10 minutes'
});
// Send to room
this.websocket.sendToRoom('chat:123', 'message', {
from: 'user456',
text: 'Hello everyone!'
});
// Check connection status
const isOnline = this.websocket.isUserConnected(userId);4. Decorators and Utilities
import {
Public,
CurrentUser,
RequirePermissions,
ValidationUtil,
CryptoUtil
} from '@brdene95/nestjs-shared-lib';
@Controller('auth')
export class AuthController {
@Post('login')
@Public()
async login(@Body() dto: LoginDto) {
// Public endpoint - no authentication required
}
@Get('profile')
async getProfile(@CurrentUser() user: any) {
// User extracted from JWT token
return user;
}
@Post('admin-action')
@RequirePermissions('admin.manage')
async adminAction(@CurrentUser('id') userId: string) {
// Requires admin.manage permission
}
}Configuration
Environment Variables
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# MongoDB
MONGODB_URI=mongodb://localhost:27017
MONGODB_DB=mydb
# RabbitMQ
RABBITMQ_URL=amqp://localhost:5672
# I18n
I18N_DEFAULT_LANG=enSetting up RPC Auth Service
// In your module
import { IAuthRpcService } from '@brdene95/nestjs-shared-lib';
@Injectable()
export class AuthRpcService implements IAuthRpcService {
constructor(@Inject('AUTH_CLIENT') private client: ClientProxy) {}
async validateToken(token: string) {
return this.client.send('validate_token', { token }).toPromise();
}
}
// Register the guard
@Module({
providers: [
AuthRpcService,
{
provide: IAuthRpcService,
useClass: AuthRpcService,
},
ExternalTokenRpcGuard,
],
exports: [ExternalTokenRpcGuard],
})
export class AuthModule {}Utilities
Crypto Operations
import { CryptoUtil } from '@brdene95/nestjs-shared-lib';
// Hash password
const hashedPassword = await CryptoUtil.hashPassword('password123');
// Verify password
const isValid = await CryptoUtil.comparePassword('password123', hashedPassword);
// Generate tokens
const token = CryptoUtil.generateToken(32);
const uuid = CryptoUtil.generateUuid();Date Operations
import { DateUtil } from '@brdene95/nestjs-shared-lib';
const tomorrow = DateUtil.addDays(new Date(), 1);
const isExpired = DateUtil.isExpired(expiryDate);
const daysDiff = DateUtil.diffInDays(date1, date2);String Operations
import { StringUtil } from '@brdene95/nestjs-shared-lib';
const camelCase = StringUtil.toCamelCase('hello world'); // 'helloWorld'
const slug = StringUtil.slugify('Hello World!'); // 'hello-world'
const truncated = StringUtil.truncate('Long text here', 10); // 'Long te...'Validation
import { ValidationUtil } from '@brdene95/nestjs-shared-lib';
const isValidEmail = ValidationUtil.isValidEmail('[email protected]');
const isValidUuid = ValidationUtil.isValidUuid('123e4567-e89b-12d3-a456-426614174000');
const passwordCheck = ValidationUtil.isStrongPassword('MyPassword123!');Best Practices
- Guards: Always use
ExternalTokenRpcGuardfor cross-service authentication - Permissions: Combine with
PermissionGuardfor fine-grained access control - DTOs: Use the provided DTOs for consistent API responses
- Base Classes: Extend base classes to reduce boilerplate code
- Utilities: Leverage utility functions for common operations
- Constants: Use predefined constants instead of magic strings
- Interceptors: Apply logging and caching interceptors globally when possible
- Infrastructure: Use the provided modules for common services (Redis, MongoDB, etc.)
- Type Safety: Leverage TypeScript generics for type-safe operations
- Error Handling: Use the error interceptor for consistent error responses
Integration with Existing Services
To integrate with your existing microservices:
- Install the package:
npm install @brdene95/nestjs-shared-lib - Update your auth module to use the shared guards
- Replace custom CRUD services with base classes
- Standardize DTOs using the provided ones
- Apply interceptors for logging and caching
- Use utility functions to replace custom implementations
- Integrate infrastructure modules (Logger, Redis, MongoDB, etc.)
- Update Swagger documentation using provided utilities
Contributing
This library is designed to be extended based on project needs. Feel free to add new utilities, guards, or base classes following the established patterns.
License
MIT
