@jerald-jesudasan/code-utils
v1.1.2
Published
A collection of useful code utilities
Downloads
22
Maintainers
Readme
@jerald-jesudasan/code-utils
A comprehensive TypeScript utility library for enterprise Node.js applications. Provides modular, production-ready utilities for caching, logging, HTTP requests, message queuing, internationalization, data transformation, and more.
📦 What's Inside
This library provides 30+ production-ready utilities organized into three categories:
Core Infrastructure Utilities
Enterprise-grade utilities for building scalable applications:
- Cache - Redis & in-memory caching with namespace isolation
- Logger - Winston-based logging with request tracking
- HTTP - Unified HTTP client (Axios/Request)
- Queue - Message queuing (BullMQ/Kafka/QStash/Pub/Sub)
- Environment - Config management (dotenv/Vault)
- Response - Standardized HTTP responses
- Config - Path resolution utilities
Developer Productivity Utilities
Time-saving utilities for common development tasks:
- Date Helper - Date arithmetic & formatting
- Random Generator - Secure OTPs & passwords
- Object Util - Deep clone, merge, transform
- Template Engine - Handlebars with 30+ helpers
- IP to Location - Geolocation & distance calculations
- Locale Util - i18n with 100+ locales
- User Agent - Device & browser detection
- Request Context - Request tracking & metadata
- URL Helper - URL manipulation & formatting
Communication & Integration Utilities
Messaging, authentication, and external service integrations:
- SMS Helper - Multi-provider SMS (Twilio, MSG91, Unifonic, etc.)
- Email Helper - SMTP, AWS SES, SendGrid email sending
- Push Helper - OneSignal web push notifications
- File Helper - PDF generation from HTML
- JWT Helper - JWT parsing & validation (RS256/HS256/ES256)
- HOTP Helper - HMAC-based One-Time Passwords
- TOTP Helper - Time-based One-Time Passwords (2FA)
- PKCE Helper - OAuth 2.0 PKCE validation
- Validation Helper - Email & mobile number validation
Features
- 🚀 Production Ready: Battle-tested utilities for enterprise applications
- 📦 Modular Design: Use only what you need
- 🔒 Type Safe: Full TypeScript support with strict typing
- ⚡ Performance: Optimized for high-throughput applications
- 🔧 Configurable: Environment-based configuration
- 🎯 Consistent API: Unified interfaces across all utilities
- 📝 Well Documented: Comprehensive documentation for each module
Table of Contents
- Installation
- Quick Start
- Core Utilities
- Cache Helper - Redis & in-memory caching
- Logger Helper - Winston-based logging
- HTTP Helper - HTTP client abstraction
- Queue Helper - Message queue abstraction
- Environment Resolver - Env variable management
- Response Utility - Standardized HTTP responses
- Config Path Resolver - Path resolution
- Additional Utilities
- Date Helper - Date manipulation
- Random Number Generator - OTP & ID generation
- Object Util - Object transformation
- Template Engine - Handlebars rendering
- IP to Location Utils - IP geolocation
- Locale Util - Internationalization
- User Agent Helper - Device detection
- Common Entity Util - Request context
- URL Helper - URL manipulation
- Communication & Integration Utilities
- SMS Helper - Multi-provider SMS
- Email Helper - Email sending
- Push Helper - Push notifications
- File Helper - PDF generation
- JWT Helper - JWT handling
- HOTP Helper - HOTP authentication
- TOTP Helper - TOTP authentication
- PKCE Helper - OAuth PKCE
- Validation Helper - Input validation
- Environment Variables Reference
- Complete Example
- Architecture
- Development
- Best Practices
Installation
npm install @jerald-jesudasan/code-utilsQuick Start
import {
CacheHelper,
LoggerHelper,
HttpHelper,
QueueHelper,
EnvResolver,
ResultEntity,
ConfigPathResolver,
PDFHelper,
TOTPHelper,
EmailValidationService
} from '@jerald-jesudasan/code-utils';
// Load environment variables
await EnvResolver.Instance.loadEnvVariables();
// Initialize logger
const logger = LoggerHelper.Instance;
logger.info('app-startup', 'Application starting');
// Initialize cache
const cache = await CacheHelper.getInstance();
await cache.set('config', 'version', '1.0.0');
// Make HTTP requests
const http = await HttpHelper.getInstance();
const response = await http.get('https://api.example.com/data');
// Use message queues
const queue = await QueueHelper.getInstance();
await queue.ensureTopics(['events']);
await queue.add('events', { type: 'user.created', userId: '123' });
logger.info('app-startup', 'Application started successfully');Core Utilities
🗄️ Cache Helper
Flexible caching abstraction supporting Redis and in-memory Map storage.
import { CacheHelper } from '@jerald-jesudasan/code-utils';
const cache = await CacheHelper.getInstance();
await cache.set('users', 'user:123', JSON.stringify({ name: 'John' }));
const user = await cache.get('users', 'user:123');
await cache.delAll('users');Features:
- Redis and Map support
- Namespace isolation
- Automatic connection management
- Null object pattern for disabled cache
📝 Logger Helper
Winston-based logging with request ID tracking and multiple transports.
import { LoggerHelper } from '@jerald-jesudasan/code-utils';
const logger = LoggerHelper.Instance;
logger.info('req-123', 'User logged in', { userId: '456' });
logger.error('req-123', 'Payment failed', { error: 'Insufficient funds' });
logger.warn('req-123', 'Rate limit approaching', { current: 95 });Features:
- Console, file, and Google Cloud logging
- Request ID tracking
- Daily log rotation
- Structured logging
🌐 HTTP Helper
HTTP client abstraction supporting Axios and Request libraries.
import { HttpHelper, HttpLibType } from '@jerald-jesudasan/code-utils';
const http = await HttpHelper.getInstance({ httpLib: HttpLibType.AXIOS });
const response = await http.get('https://api.example.com/users');
const postResponse = await http.post('https://api.example.com/users', {
name: 'John Doe'
});Features:
- Unified interface for Axios and Request
- Custom headers support
- Binary/file download support
- Never throws on HTTP errors
📬 Queue Helper
Unified message queue interface for BullMQ, Kafka, QStash, and Google Pub/Sub.
import { QueueHelper } from '@jerald-jesudasan/code-utils';
const queue = await QueueHelper.getInstance();
await queue.ensureTopics(['user-events']);
await queue.add('user-events', { userId: '123', action: 'registration' });
queue.process('user-events', async (topic, partition, message, heartbeat, pause, commitOffsets) => {
console.log('Processing:', message);
await commitOffsets(topic, partition, message.offset);
});Features:
- BullMQ (Redis jobs)
- Kafka (event streaming)
- QStash (HTTP webhooks)
- Google Pub/Sub (cloud messaging)
- AWS MSK IAM authentication
🔐 Environment Resolver
Load environment variables from .env files or HashiCorp Vault.
import { EnvResolver } from '@jerald-jesudasan/code-utils';
// Load from .env (default)
await EnvResolver.Instance.loadEnvVariables();
// Load from Vault (production)
process.env.ENV_PROVIDER = 'vault';
process.env.VAULT_URL = 'https://vault.example.com';
process.env.VAULT_KEY = 'token';
process.env.VAULT_PATH = 'secret/data/myapp/prod';
await EnvResolver.Instance.loadEnvVariables();Features:
- dotenv support
- HashiCorp Vault integration
- Automatic provider detection
- Error handling and validation
📨 Response Utility
Standardized response entities for HTTP responses with multiple content types.
import { ResultEntity, ErrorEntity, HttpStatus } from '@jerald-jesudasan/code-utils';
const result = new ResultEntity({});
// Success response
result.setData({
code: HttpStatus.OK,
data: { message: 'Success' }
});
result.sendResponse(res);
// Error response
result.setError({
error: new ErrorEntity({
http_code: HttpStatus.BAD_REQUEST,
error: 'validation_error',
error_description: 'Invalid input'
})
});
result.sendResponse(res);Features:
- JSON, HTML, XML, redirects
- File downloads
- Cookie management
- Custom headers
- Request context tracking
📁 Config Path Resolver
Resolve file paths for resources and configuration files.
import { ConfigPathResolver } from '@jerald-jesudasan/code-utils';
const resolver = ConfigPathResolver.Instance;
const templatePath = resolver.resolveResourcePath('templates/email.hbs');
const absolutePath = resolver.resolvePath('logs');Features:
- Resource path resolution
- Environment-based configuration
- Cross-platform support
- Absolute path conversion
Additional Utilities
📅 Date Helper
Comprehensive date and time manipulation utility with immutable operations.
import { DateHelper } from '@jerald-jesudasan/code-utils';
const helper = DateHelper.Instance;
// Date arithmetic
const tomorrow = helper.addDays(new Date(), 1);
const nextMonth = helper.addMonths(new Date(), 1);
// Date comparisons
const isBefore = helper.isBefore(date1, date2);
const isWeekend = helper.isWeekend(new Date());
// Format dates
const formatted = helper.formatDate(new Date(), 'YYYY-MM-DD');Features:
- Date arithmetic (add/subtract days, months, years)
- Date comparisons and validation
- Format conversion
- Week number calculations
- Immutable operations
🎲 Random Number Generator
Cryptographically secure random ID and OTP generation.
import { RandomNumberGenerator } from '@jerald-jesudasan/code-utils';
// Generate OTPs
const numericOTP = RandomNumberGenerator.getNumericOTP(6); // "123456"
const alphanumericOTP = RandomNumberGenerator.getAlphanumericOTP(8); // "A5B9C2D7"
// Generate passwords
const password = RandomNumberGenerator.generatePassword(16);
// Generate reference numbers
const refNumber = RandomNumberGenerator.generateReferenceNumber('ORD'); // "ORD-A5B9C2D7"Features:
- Numeric, alphanumeric, and letters-only OTPs
- Secure password generation
- Reference number generation
- Crypto-secure random values
- Custom character sets
🔄 Object Util
Advanced object manipulation and transformation utilities.
import { ObjectUtil } from '@jerald-jesudasan/code-utils';
// Deep clone
const cloned = ObjectUtil.deepClone(originalObject);
// Deep merge
const merged = ObjectUtil.deepMerge(obj1, obj2);
// Nested operations
const value = ObjectUtil.get(obj, 'user.profile.name', 'default');
ObjectUtil.set(obj, 'user.profile.age', 25);
// Transform objects
const flattened = ObjectUtil.flatten({ user: { name: 'John', age: 30 } });
// { 'user.name': 'John', 'user.age': 30 }Features:
- Deep clone and merge
- Nested property access with dot notation
- Object flattening and unflattening
- Pick, omit, and rename properties
- Type checking utilities
🎨 Template Engine
Handlebars-based template rendering with 30+ built-in helpers.
import { TemplateEngine } from '@jerald-jesudasan/code-utils';
// Render inline templates
const html = TemplateEngine.render(
'Hello {{uppercase name}}!',
{ name: 'john' }
); // "Hello JOHN!"
// Render from files with caching
const email = TemplateEngine.renderFile(
'templates/welcome-email.hbs',
{ username: 'John', verifyLink: 'https://...' }
);
// Register custom helpers
TemplateEngine.registerHelper('currency', (amount) => {
return `$${amount.toFixed(2)}`;
});Features:
- File-based template rendering
- Template caching for performance
- 30+ built-in helpers (string, number, date, array, comparison)
- Custom helper registration
- Partial template support
🌍 IP to Location Utils
IP geolocation with geographic calculations and filtering.
import { IPToLocationUtils } from '@jerald-jesudasan/code-utils';
const ipUtils = IPToLocationUtils.Instance;
// Lookup IP address
const address = ipUtils.findAddressByIp('8.8.8.8');
console.log(address.country); // "United States"
console.log(address.locality); // "Mountain View"
// Calculate distances
const distance = ipUtils.getDistanceBetweenIPs('8.8.8.8', '1.1.1.1', 'km');
// Check proximity
const isNearby = ipUtils.isIPNearLocation('8.8.8.8', 37.7749, -122.4194, 100, 'km');
// Filter by country
const usIPs = ipUtils.filterByCountry(['8.8.8.8', '1.1.1.1'], ['US']);Features:
- IP to location lookup with caching
- IPv4 and IPv6 validation
- Haversine distance calculations
- Country and region filtering
- Private/loopback IP detection
- Batch processing
🌐 Locale Util
Internationalization (i18n) and locale management for multilingual applications.
import { LocaleUtil } from '@jerald-jesudasan/code-utils';
// Parse Accept-Language headers
const locale = LocaleUtil.fromAcceptLanguage('en-US,en;q=0.9,de;q=0.8');
console.log(locale?.DisplayName); // "English (United States)"
// Query locales
const englishLocales = LocaleUtil.getLocalesByLanguage('en'); // 8 variants
// RTL/LTR detection
console.log(LocaleUtil.isRTL('ar-SA')); // true (Arabic)
console.log(LocaleUtil.getTextDirection('en-US')); // "ltr"
// Get locale information
console.log(LocaleUtil.getDisplayName('fr-FR')); // "French (France)"Features:
- 100+ supported locales
- Accept-Language header parsing
- RTL/LTR text direction detection
- Locale validation and querying
- Format conversion (hyphen ↔ underscore)
- ISO-3 code lookups
📱 User Agent Helper
User agent parsing and comprehensive device detection.
import { UserAgentHelper } from '@jerald-jesudasan/code-utils';
const helper = UserAgentHelper.Instance;
// Parse user agent
const deviceInfo = helper.getDeviceInfo(userAgent);
console.log(deviceInfo.browser.name); // "Chrome"
console.log(deviceInfo.os.name); // "Windows"
// Device detection
const isMobile = helper.isMobile(userAgent);
const isTablet = helper.isTablet(userAgent);
const isBot = helper.isBot(userAgent);
// Browser detection
const isChrome = helper.isChrome(userAgent);
const isSafari = helper.isSafari(userAgent);
// OS detection
const isWindows = helper.isWindows(userAgent);
const isIOS = helper.isIOS(userAgent);Features:
- Device type detection (mobile, tablet, desktop, TV, wearable)
- Browser identification (Chrome, Firefox, Safari, Edge, etc.)
- OS detection (Windows, macOS, iOS, Android, Linux)
- Bot detection and filtering
- Feature detection (touch, webview)
📋 Common Entity Util
Request context management and CloudFlare integration.
import { RequestContext } from '@jerald-jesudasan/code-utils';
// Express middleware
app.use((req, res, next) => {
req.context = new RequestContext(req);
next();
});
// Access context
app.get('/api/data', (req, res) => {
const context = req.context;
console.log(context.request_id);
console.log(context.ip);
console.log(context.locale);
console.log(context.device_type);
});Features:
- Request ID tracking
- Device detection integration
- IP geolocation
- Locale resolution
- CloudFlare header parsing
- Multi-tenant support
🔗 URL Helper
URL manipulation and formatting utilities.
import { URLFormater } from '@jerald-jesudasan/code-utils';
// Join URL parts
const url = URLFormater.urljoin('https://api.example.com', '/v1', '/users');
// "https://api.example.com/v1/users"
// Build URL with query params
const fullUrl = URLFormater.buildURL('https://api.example.com/search', {
q: 'test',
page: 1
});
// "https://api.example.com/search?q=test&page=1"
// Parse URL
const components = URLFormater.parseURL('https://api.example.com:443/v1/users?page=1');
console.log(components.hostname); // "api.example.com"
console.log(components.pathname); // "/v1/users"
// Validate URL
const isValid = URLFormater.isValidURL('https://example.com'); // trueFeatures:
- URL joining with proper slash handling
- Query parameter building
- URL parsing and validation
- Component encoding/decoding
- Query parameter extraction
Communication & Integration Utilities
📱 SMS Helper
Multi-provider SMS sending with support for 8 different providers.
import { TwilioService, CommonSMSSendEntity } from '@jerald-jesudasan/code-utils';
const smsEntity: CommonSMSSendEntity = {
to: "+1234567890",
message: "Your verification code is 123456",
sms_config: {
provider: "TWILIO",
base_url: "https://api.twilio.com",
client_id: process.env.TWILIO_ACCOUNT_SID,
client_secret: process.env.TWILIO_AUTH_TOKEN,
from: "+9876543210"
}
};
const twilioService = TwilioService.Instance;
await twilioService.sendSMSV2(requestContext, smsEntity);Supported Providers:
- Twilio
- MSG91
- Unifonic
- BigTGS
- Pronto
- SBT
- OMNI
- REST API
- WhatsApp (Meta Business API)
Features:
- Multiple provider support
- Template-based messaging
- WhatsApp integration
- Unified interface
- Provider-specific configuration
✉️ Email Helper
Multi-provider email sending with SMTP, AWS SES, and SendGrid support.
import { SMTPEmailer, CommonEmailSendEntity } from '@jerald-jesudasan/code-utils';
const emailEntity: CommonEmailSendEntity = {
to: ["[email protected]"],
subject: "Welcome to Our Service",
body: "<h1>Welcome!</h1><p>Thank you for signing up.</p>",
email_config: {
provider: "SMTP",
host_name: "smtp.gmail.com",
port: 587,
username: process.env.SMTP_USER,
password: process.env.SMTP_PASS,
from_email: "[email protected]"
}
};
const smtpEmailer = SMTPEmailer.Instance;
await smtpEmailer.sendEmail(emailEntity);Supported Providers:
- SMTP (Gmail, Outlook, custom servers)
- AWS SES
- SendGrid
- REST API
Features:
- HTML and plain text emails
- File attachments
- CC and BCC support
- Template support
- Multiple recipients
🔔 Push Helper
Web push notifications using OneSignal.
import { OneSignalService, CommonWebPushSendEntity } from '@jerald-jesudasan/code-utils';
const pushEntity: CommonWebPushSendEntity = {
external_user_id: "user-123",
title: "New Message",
body: "You have a new message from John",
push_config: {
provider: "ONESIGNAL",
api_key: process.env.ONESIGNAL_API_KEY,
app_id: process.env.ONESIGNAL_APP_ID
}
};
const pushService = OneSignalService.Instance;
await pushService.sendPushNotification(pushEntity);Features:
- External ID-based targeting
- OneSignal integration
- Custom notification data
- Delivery tracking
📄 File Helper
PDF generation from HTML content.
import { PDFHelper } from '@jerald-jesudasan/code-utils';
const htmlContent = `
<html>
<head>
<style>
body { font-family: Arial, sans-serif; }
h1 { color: #333; }
</style>
</head>
<body>
<h1>Invoice</h1>
<p>Order #12345</p>
<p>Total: $99.99</p>
</body>
</html>
`;
const pdfBuffer = await PDFHelper.convertHTMLToPDF(htmlContent);
// Save to file
const fs = require('fs');
fs.writeFileSync('invoice.pdf', pdfBuffer);Features:
- HTML to PDF conversion
- Customizable page size and margins
- Background printing
- High-quality rendering
- Puppeteer-based
🔐 JWT Helper
JWT parsing, validation, and verification with multi-algorithm support.
import { JWTHelper } from '@jerald-jesudasan/code-utils';
const jwtHelper = JWTHelper.Instance;
// Parse JWT (with signature verification)
const claims = await jwtHelper.parseJWT(
token,
'https://auth.example.com/.well-known/jwks.json',
'', // password for HS256
false // don't ignore expiration
);
// Simple parse (no verification)
const payload = jwtHelper.simpleParseJWT(token);
// Get token hash (for storage/comparison)
const hash = jwtHelper.getTokenHash(token);Features:
- RS256, HS256, ES256 algorithm support
- JWK fetching and caching
- Token hash generation
- Expiration validation
- kid-based key lookup
🔑 HOTP Helper
HMAC-based One-Time Password generation and validation.
import { HOTPHelper } from '@jerald-jesudasan/code-utils';
const hotpHelper = HOTPHelper.Instance;
// Generate secret
const secret = hotpHelper.generate();
// Generate HOTP for specific counter
const otp = hotpHelper.getHOTP(secret, counter);
// Validate HOTP
const isValid = hotpHelper.validate(secret, userEnteredOTP, counter);Features:
- Secret generation
- Counter-based OTP generation
- OTP validation
- Speakeasy library integration
⏰ TOTP Helper
Time-based One-Time Password generation and validation for 2FA.
import { TOTPHelper } from '@jerald-jesudasan/code-utils';
const totpHelper = TOTPHelper.Instance;
// Generate secret
const secret = totpHelper.generate();
// Generate OTP auth URL for QR code
const otpAuthUrl = totpHelper.createOTPAuthURL(
secret,
'[email protected]',
'base32',
'MyApp'
);
// Generate current TOTP
const currentOTP = totpHelper.getTOTP(secret);
// Validate user-entered TOTP
const isValid = totpHelper.validate(userEnteredOTP, secret);
// Validate with time window (for clock skew)
const isValidWithWindow = totpHelper.validateWithWindow(userEnteredOTP, secret, 1);Features:
- Secret generation
- Time-based OTP generation
- QR code URL generation
- Time window validation
- Authenticator app compatible
🛡️ PKCE Helper
OAuth 2.0 Proof Key for Code Exchange (PKCE) validation.
import { PKCEValidator } from '@jerald-jesudasan/code-utils';
const pkceValidator = PKCEValidator.Instance;
// Verify plain method
const isValidPlain = pkceValidator.verify(
savedCodeChallenge,
codeVerifier,
'plain'
);
// Verify S256 method
const isValidS256 = pkceValidator.verify(
savedCodeChallenge,
codeVerifier,
'S256'
);Features:
- Plain and S256 challenge methods
- Code challenge verification
- OAuth 2.0 compliant
- Crypto-secure validation
✅ Validation Helper
Email and mobile number validation with provider integration.
import { EmailValidationService, MobileValidatorService } from '@jerald-jesudasan/code-utils';
// Email validation
const emailService = EmailValidationService.Instance;
const isValid = await emailService.validate(
'[email protected]',
'[]', // allowed domains
undefined // SendGrid config (optional)
);
// Mobile validation with Twilio
const mobileService = MobileValidatorService.Instance;
const phoneInfo = await mobileService.validate(
'+1234567890',
mobileConfig,
'carrier' // lookup type
);
console.log(phoneInfo.carrier_name);
console.log(phoneInfo.E164_format);
console.log(phoneInfo.international_format);Features:
- Email format validation
- MX record checking
- Disposable email detection
- SendGrid integration
- Mobile number validation with Twilio
- Carrier lookup
- International format conversion
- Google libphonenumber integration
Environment Variables Reference
Cache Configuration
CACHE_STATUS="ENABLED|DISABLED"
CACHE_TYPE="REDIS|MAP"
REDIS_CONNECTION_STRING="redis://localhost:6379"
REDIS_HOST="redis.example.com"Logging Configuration
LOG_LEVEL="info|error|warn|debug|verbose"
CONSOLE_LOG="true|false"
FILE_LOGGER_ENABLED="true|false"
LOGGER_SERVICE_NAME="my-app"
GOOGLE_CLOUD_LOGGER_ENABLED="true|false"
GOOGLE_CLOUD_LOGGER_PROJECT_ID="gcp-project"Queue Configuration
QUEUE_TYPE="BULLMQ|KAFKA|QSTASH|PUBSUB"
# BullMQ
REDIS_CONNECTION_STRING="redis://localhost:6379"
# Kafka
KAFKA_CLIENT_ID="my-app"
KAFKA_BROKERS="localhost:9092"
KAFKA_USER_NAME="username"
KAFKA_PASSWORD="password"
AWS_REGION="us-east-1" # For MSK IAM
# QStash
QSTASH_TOKEN="token"
QSTASH_CURRENT_SIGNING_KEY="sig_xxxxx"
QSTASH_NEXT_SIGNING_KEY="sig_xxxxx"
# Google Pub/Sub
GOOGLE_CLOUD_PROJECT_ID="gcp-project"
GOOGLE_APPLICATION_CREDENTIALS="/path/to/key.json"Environment Resolution
ENV_PROVIDER="dotenv|vault"
VAULT_URL="https://vault.example.com"
VAULT_KEY="hvs.xxxxx"
VAULT_PATH="secret/data/app/env"Resource Paths
RESOURCE_PATH="/var/app/resources"Complete Example
import express from 'express';
import {
EnvResolver,
LoggerHelper,
CacheHelper,
QueueHelper,
ResultEntity,
ErrorEntity,
HttpStatus
} from '@jerald-jesudasan/code-utils';
async function bootstrap() {
// 1. Load environment variables
await EnvResolver.Instance.loadEnvVariables();
// 2. Initialize logger
const logger = LoggerHelper.Instance;
logger.info('system', 'Application starting');
// 3. Initialize cache
const cache = await CacheHelper.getInstance();
logger.info('system', 'Cache initialized');
// 4. Initialize queue
const queue = await QueueHelper.getInstance();
await queue.ensureTopics(['user-events', 'order-events']);
logger.info('system', 'Queue initialized');
// 5. Create Express app
const app = express();
app.use(express.json());
// 6. Add routes
app.post('/api/users', async (req, res) => {
const result = new ResultEntity({ body: req.body });
const requestId = req.headers['x-request-id'] as string || 'req-' + Date.now();
try {
logger.info(requestId, 'Creating user', { email: req.body.email });
// Business logic
const user = {
id: Math.random().toString(36),
...req.body,
createdAt: new Date()
};
// Cache user
await cache.set('users', user.id, JSON.stringify(user));
// Publish event
await queue.add('user-events', {
type: 'user.created',
userId: user.id,
timestamp: new Date()
});
logger.info(requestId, 'User created successfully', { userId: user.id });
result.setData({
code: HttpStatus.CREATED,
data: user,
description: 'User created successfully'
});
} catch (error: any) {
logger.error(requestId, 'User creation failed', {
error: error.message,
stack: error.stack
});
result.setError({
error: new ErrorEntity({
http_code: HttpStatus.INTERNAL_SERVER_ERROR,
error: 'server_error',
error_description: 'Failed to create user'
})
});
}
result.sendResponse(res);
});
app.get('/api/users/:id', async (req, res) => {
const result = new ResultEntity({});
const requestId = req.headers['x-request-id'] as string || 'req-' + Date.now();
try {
// Check cache first
const cached = await cache.get('users', req.params.id);
if (cached) {
logger.info(requestId, 'Cache hit', { userId: req.params.id });
result.setData({
code: HttpStatus.OK,
data: JSON.parse(cached)
});
} else {
logger.info(requestId, 'Cache miss', { userId: req.params.id });
result.setError({
error: new ErrorEntity({
http_code: HttpStatus.NOT_FOUND,
error: 'user_not_found',
error_description: 'User not found'
})
});
}
} catch (error: any) {
logger.error(requestId, 'Error fetching user', { error: error.message });
result.setError({
error: new ErrorEntity({
http_code: HttpStatus.INTERNAL_SERVER_ERROR,
error: 'server_error',
error_description: 'Failed to fetch user'
})
});
}
result.sendResponse(res);
});
// 7. Process queue events
queue.process('user-events', async (topic, partition, message, heartbeat, pause, commitOffsets) => {
logger.info('queue-processor', 'Processing user event', {
type: message.data.type,
userId: message.data.userId
});
// Process event logic here
await commitOffsets(topic, partition, message.offset);
});
// 8. Start server
const PORT = parseInt(process.env.PORT || '3000');
app.listen(PORT, () => {
logger.info('system', 'Server started', { port: PORT });
});
// 9. Graceful shutdown
process.on('SIGTERM', async () => {
logger.info('system', 'SIGTERM received, shutting down gracefully');
await cache.disconnect();
await queue.disconnectProducer();
await queue.disconnectConsumers();
process.exit(0);
});
}
bootstrap().catch(error => {
console.error('Bootstrap failed:', error);
process.exit(1);
});Architecture
Design Patterns
- Singleton Pattern: Core helpers use singleton instances for resource efficiency
- Factory Pattern: Dynamic import and instantiation based on configuration
- Strategy Pattern: Pluggable implementations (Redis vs Map, Axios vs Request)
- Null Object Pattern: Graceful degradation when features are disabled
TypeScript Configuration
- Target: ES2022
- Module: CommonJS
- Strict Mode: Enabled
- Decorators: Supported
Publishing
This package is published to a private GitLab npm registry:
npm publishRegistry URL: https://gitlab.com/jerald-jesudasan/projects/packages/npm/code-utils
Development
Build
npm run buildTest
npm test # Run all tests
npm run test:watch # Watch mode
npm run test:cov # With coverage
npm run test:debug # Debug modePrepare for Publishing
npm run prepareBest Practices
- Environment Variables: Use environment-based configuration for all utilities
- Error Handling: Always handle errors gracefully with proper logging
- Request IDs: Pass request IDs through the entire request flow for tracing
- Resource Cleanup: Always disconnect/cleanup resources on shutdown
- Type Safety: Leverage TypeScript for better development experience
- Modular Usage: Import only the utilities you need
- Documentation: Refer to individual utility documentation for detailed usage
Support
For issues, feature requests, or questions:
- Check individual utility documentation
- Review the CLAUDE.md file for architectural details
- Contact the Jerald
License
ISC - Jerald
Made with ❤️ by the Jerald
