@triproject/nestjs-core
v1.0.50
Published
A collection of NestJS modules and utilities to speed up development.
Readme
@triproject/nestjs-core
A collection of NestJS modules and utilities to speed up development with built-in support for caching, database access, encryption, logging, mail, notifications, queues, and more.
Features
- 🚀 Quick Bootstrap - Preconfigured NestJS application setup
- 🔐 Encryption & Authentication - JWT, password hashing (PBKDF2), AES-256-GCM encryption, TOTP/2FA
- 💾 Database - Sequelize ORM with TypeScript support
- 🗄️ Caching - Redis integration with helpers
- 📧 Email - Nodemailer with queue support
- 🔔 Notifications - Push notifications and Slack integration
- ⚡ Queue Management - Bull and BullMQ support
- 📝 Logging - Structured logging with Slack alerts
- 🎨 Swagger - API documentation helpers
- 🔌 Modular - Import only what you need
Installation
npm install @triproject/nestjs-coreModular Imports
This package uses subpath exports to avoid loading unnecessary dependencies. Import only what you need:
Bootstrap (Core)
import { bootstrap } from '@triproject/nestjs-core/bootstrap';
import { APP_PORT, APP_KEY } from '@triproject/nestjs-core/config';Required peer dependencies:
@nestjs/common(^11.0.0)@nestjs/core(^11.0.0)express(^4.0.0 || ^5.0.0)helmet(^7.0.0 || ^8.0.0)cookie-parser(^1.4.0)class-validator(^0.14.0)dotenv(^16.0.0 || ^17.0.0)
Configuration
import {
APP_NAME,
APP_PORT,
APP_KEY,
DB_HOST,
DB_PORT,
REDIS_HOST,
REDIS_PORT,
// ... and more
} from '@triproject/nestjs-core/config';All environment variables are pre-configured with sensible defaults.
Cache (Redis)
import { AppCache, Redis, CacheModule } from '@triproject/nestjs-core/cache';
// In your module
@Module({
imports: [CacheModule],
})
export class AppModule {}
// In your service
constructor(private cache: AppCache) {}
async cacheData() {
await this.cache.set('key', { data: 'value' }, 3600);
const data = await this.cache.get<{ data: string }>('key');
await this.cache.delete('key');
}Required peer dependencies:
redis(^4.0.0 || ^5.0.0)
Database (Sequelize)
import { DatabaseModule, Repository } from '@triproject/nestjs-core/sequelize';
// In your module
@Module({
imports: [DatabaseModule],
})
export class AppModule {}
// Base repository with pagination and common queries
export class UserRepository extends Repository<UserModel> {
constructor() {
super(UserModel);
}
}Required peer dependencies:
sequelize(^6.0.0)sequelize-typescript(^2.0.0)@nestjs/sequelize(^11.0.0)
Encryption & JWT
import { PasswordHash, Jwt, Encryption, EncryptionModule } from '@triproject/nestjs-core/encryption';
// Password hashing
const hash = passwordHash.sign('myPassword');
const isValid = passwordHash.verify('myPassword', hash);
// JWT tokens
const token = jwt.sign({ userId: 123 }, 3600);
const decoded = jwt.verify<{ userId: number }>(token);
// AES-256-GCM encryption
const encrypted = encryption.encrypt('sensitive data');
const decrypted = encryption.decrypt(encrypted);Required peer dependencies:
jsonwebtoken(^9.0.0)
Features:
Environment Variables:
Set the following variables in your .env file depending on the storage driver:
Common:
STORAGE_DRIVER=local # or s3 or minioLocal Storage:
S3_BUCKET=./storage # Local directory path for file storageAWS S3:
S3_BUCKET=your-bucket-name
S3_REGION=your-region
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-keyMinIO:
MINIO_HOST=localhost
MINIO_PORT=9000
MINIO_USE_SSL=false
S3_BUCKET=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key- PBKDF2 password hashing with SHA-512
- RS512 JWT tokens
- AES-256-GCM encryption
- Native Node.js crypto (no external dependencies)
Logger
import { AppLogger, SlackLogger } from '@triproject/nestjs-core/logger';
const logger = new AppLogger('MyService');
logger.log('Info message');
logger.error('Error message', error);
logger.warn('Warning message');
logger.debug('Debug message');
// Slack integration
const slackLogger = new SlackLogger();
await slackLogger.error('Critical error', error);Required peer dependencies:
axios(^1.0.0)lodash(^4.17.0)moment(^2.30.0)
import { MailModule, Mailer } from '@triproject/nestjs-core/mail';
@Module({
imports: [MailModule],
})
export class AppModule {}
// Send email
await mailer.send({
to: '[email protected]',
subject: 'Welcome',
html: '<p>Welcome to our app!</p>',
});Required peer dependencies:
nodemailer(^6.0.0 || ^7.0.0)@nestjs/bull(^11.0.0)bull(^4.0.0)
Notifications
import { NotificationModule, PushNotification } from '@triproject/nestjs-core/notifications';
@Module({
imports: [NotificationModule],
})
export class AppModule {}
// Send push notification
await pushNotification.send({
playerIds: ['user-id'],
title: 'New Message',
message: 'You have a new message',
});Required peer dependencies:
@nestjs/bull(^11.0.0)bull(^4.0.0)
Queues (BullMQ)
import { QueueModule, AppQueue } from '@triproject/nestjs-core/queues';
@Module({
imports: [QueueModule],
})
export class AppModule {}
// Create queue processor
@Processor('myQueue')
export class MyQueue extends AppQueue {
@Process('job-name')
async processJob(job: Job) {
// Process job
}
}Required peer dependencies:
@nestjs/bullmq(^11.0.0)bullmq(^5.0.0)
Helpers
import {
CatchError,
TransformResponseInterceptor,
totp,
SwaggerApiPaginateResponse,
} from '@triproject/nestjs-core/helpers';
// Error handling decorator
class MyService {
@CatchError('Operation failed')
async myMethod() {
// Automatically catches and transforms errors
}
}
// TOTP/2FA
// Generate TOTP secret and QR code
const { secret, qrCodeBase64 } = await totp.generate({
email: '[email protected]',
issuer: 'MyApp',
});
const isValid = totp.verify(secret, '123456');
// Protect a route/controller with TOTP guard
import { Controller, Get, UseGuards } from '@nestjs/common';
import { TotpGuard } from '@triproject/nestjs-core/totp';
@Controller('secure')
export class SecureController {
@Get()
@UseGuards(TotpGuard)
getSecureData() {
return 'This route requires a valid TOTP code in the X-TOTP header.';
}
}
// Swagger decorators
@SwaggerApiPaginateResponse(UserDto)
async getUsers() {
// Returns paginated response with Swagger docs
}Required peer dependencies (for TOTP):
speakeasy(^2.0.0)qrcode(^1.5.0)
Complete Usage Example
// main.ts
import { bootstrap } from '@triproject/nestjs-core/bootstrap';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
const setupSwagger = (app) => {
const config = new DocumentBuilder().setTitle('My API').setVersion('1.0').build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('docs', app, document);
};
bootstrap(AppModule, setupSwagger);
// app.module.ts
import { Module } from '@nestjs/common';
import { CacheModule } from '@triproject/nestjs-core/cache';
import { DatabaseModule } from '@triproject/nestjs-core/sequelize';
import { EncryptionModule } from '@triproject/nestjs-core/encryption';
import { MailModule } from '@triproject/nestjs-core/mail';
@Module({
imports: [DatabaseModule, CacheModule, EncryptionModule, MailModule],
})
export class AppModule {}
// user.service.ts
import { Injectable } from '@nestjs/common';
import { AppCache } from '@triproject/nestjs-core/cache';
import { PasswordHash, Jwt } from '@triproject/nestjs-core/encryption';
@Injectable()
export class UserService {
constructor(private cache: AppCache, private passwordHash: PasswordHash, private jwt: Jwt) {}
async login(email: string, password: string) {
// Get user from cache or database
const user = await this.cache.get(`user:${email}`);
// Verify password
const isValid = this.passwordHash.verify(password, user.password);
if (!isValid) throw new Error('Invalid credentials');
// Generate JWT token
const token = this.jwt.sign({ userId: user.id }, 86400);
return { token };
}
}Environment Variables
All configuration is done through environment variables. Create a .env file:
# App
APP_NAME=MyApp
APP_PORT=3000
APP_KEY=your-app-secret-key
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=password
DB_NAME=mydb
# Redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# JWT
JWT_PUBLIC_KEY=your-rsa-public-key
JWT_PRIVATE_KEY=your-rsa-private-key
# Encryption
PASSWORD_HASH_SECRET=your-hash-secret
ENCRYPTION_KEY=your-aes-256-key
# Mail
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME=your-email
MAIL_PASSWORD=your-password
# Slack
SLACK_ERROR_WEBHOOK_URL=your-slack-webhook
# OneSignal
ONESIGNAL_APP_ID=your-app-id
ONESIGNAL_REST_API_KEY=your-api-keyTesting
This package includes comprehensive test coverage:
npm testDevelopment
# Install dependencies
npm install
# Build
npm run build
# Run tests
npm testLicense
ISC
Storage (Local, S3, MinIO)
Unified file storage abstraction supporting local filesystem, AWS S3, MinIO, as well as CSV and Excel file creation and storage. Choose the driver via the STORAGE_DRIVER environment variable (local, s3, or minio).
import { StorageModule, StorageService, CsvStorage, ExcelService } from '@triproject/nestjs-core/storage';
@Module({
imports: [StorageModule],
})
export class AppModule {}
constructor(
private storage: StorageService,
private csvStorage: CsvStorage,
private excelService: ExcelService,
) {}
// Upload a file
await this.storage.upload('uploads/file.txt', Buffer.from('hello'));
// Get a file URL
const file = await this.storage.get('uploads/file.txt');
console.log(file.url); // Signed URL or local path
// Delete a file
await this.storage.delete('uploads/file.txt');
// Check if file exists
const exists = await this.storage.isExists('uploads/file.txt');
// --- CSV Example ---
await this.csvStorage.upload({
path: 'exports/data',
header: ['id', 'name'],
body: [
[1, 'Alice'],
[2, 'Bob'],
],
});
const csvFile = await this.storage.get('exports/data.csv');
// --- Excel Example ---
await this.excelService.upload('exports/report', {
title: 'Report',
header: ['id', 'name'],
body: [
[1, 'Alice'],
[2, 'Bob'],
],
});
const excelFile = await this.storage.get('exports/report.xlsx');Required peer dependencies:
- For S3:
@aws-sdk/client-s3,@aws-sdk/s3-request-presigner - For MinIO:
minio - For local: Node.js built-in
fs,path - For Excel:
exceljs
Features:
- 🛡️ Rate Limiting - Throttle requests with Redis-backed storage (AppThrottleModule)
Throttling (Rate Limiting)
import { AppThrottleModule } from '@triproject/nestjs-core/throttle';
// For per-route or controller-level throttling:
import { AppThrottleGuard } from '@triproject/nestjs-core/throttle';
@Module({
imports: [AppThrottleModule],
})
export class AppModule {}Usage: AppThrottleGuard
Apply custom throttling to a route or controller:
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AppThrottleGuard } from '@triproject/nestjs-core/throttle';
@Controller('demo')
export class DemoController {
@Get()
@UseGuards(AppThrottleGuard({ limit: 10, ttl: 60000 }))
getDemo() {
return 'Throttled endpoint';
}
}Required peer dependencies:
@nestjs/throttler(^6.0.0)@nest-lab/throttler-storage-redis(^1.0.0)
Features:
Global rate limiting for your NestJS app
Redis-backed storage for distributed environments
Custom key generation per request (IP + path)
Per-route or controller-level throttling with
AppThrottleGuardUnified API for local, S3, MinIO, CSV, and Excel
File upload, download (signed URL), delete, move, and existence check
CSV file creation, upload, and validation
Excel (.xlsx) file creation and upload
Contract-based for custom driver extension
Dependency-injectable service for use in any provider
Message Broker (RabbitMQ, Kafka)
Unified message broker abstraction supporting RabbitMQ and Kafka. Choose the driver via the MESSAGE_BROKER_DRIVER environment variable (rabbitmq or kafka).
import { MessageBrokerModule, MessageBroker } from '@triproject/nestjs-core/message-broker';
@Module({
imports: [MessageBrokerModule],
})
export class AppModule {}
constructor(private broker: MessageBroker) {}
// Publish a message
await this.broker.publish('my-topic', { foo: 'bar' });
// Consume messages
await this.broker.consume('my-topic', async (payload) => {
console.log(payload.data);
});Required peer dependencies:
- For RabbitMQ:
amqplib,amqp-connection-manager - For Kafka:
kafkajs
Environment Variables:
# Common
MESSAGE_BROKER_DRIVER=rabbitmq # or kafka
# RabbitMQ
RABBITMQ_HOST=amqp://localhost
# Kafka
KAFKA_BROKERS=localhost:9092
KAFKA_CLIENT_ID=my-appFeatures:
Unified API for RabbitMQ and Kafka
Publish and consume messages with a consistent interface
Dependency-injectable service for use in any provider
Unified API for local, S3, and MinIO
File upload, download (signed URL), delete, move, and existence check
Contract-based for custom driver extension
Dependency-injectable service for use in any provider
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
