JSPM

  • Created
  • Published
  • Downloads 128
  • Score
    100M100P100Q80556F
  • License ISC

Production-ready TypeScript utilities for Node.js: multi-tenant database management, NoSQL injection protection, error handling, validation, caching, and more. Battle-tested with 188/188 tests.

Package Exports

  • @hiennc24/common
  • @hiennc24/common/lib/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@hiennc24/common) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Stop Writing Boilerplate. Start Shipping Features.

Production-ready TypeScript utilities that eliminate 1000+ lines of repetitive code from your Node.js projects.

npm version tests TypeScript license

๐Ÿš€ Quick Start

import { NotFoundError, sanitizeMongoFilter, CacheManager } from '@hiennc24/common';

// Production-ready error handling in one line
throw new NotFoundError('User not found', 'USER_NOT_FOUND', { userId: '123' });

// NoSQL injection protection built-in
const safeFilter = sanitizeMongoFilter(userInput); // Automatically strips $where, $function, etc.

// Multi-tenant caching without the headache
const cache = new CacheManager(redisClient, logger, 'user-service');

๐ŸŽฏ Why @hiennc24/common?

Because every Node.js project needs the same 80% of utilities, but nobody wants to write them twice.

  • Zero compromises on security - Built-in NoSQL injection prevention with circular reference protection
  • Battle-tested reliability - 188/188 tests passing, production-ready since v1.0
  • Type-safe by design - Full TypeScript definitions with intelligent autocomplete
  • Multi-tenant ready - Database connections and caching with tenant isolation out of the box
  • Actually maintained - Regular security audits, zero known vulnerabilities
  • Tree-shakeable - Import only what you need, ESM + CommonJS support

๐Ÿ“ฆ Installation

npm install @hiennc24/common

No peer dependencies. Works with Express, NestJS, Fastify, or any Node.js framework.


๐Ÿ’ก Core Features

๐Ÿ›ก๏ธ Production-Ready Error Handling

Stop writing custom error classes. Get 10 HTTP-aware errors with proper TypeScript types and prototype chains.

Before @hiennc24/common:

// 30+ lines of boilerplate per error class
class NotFoundError extends Error {
  public code: number;
  public details?: any;
  constructor(message: string, details?: any) {
    super(message);
    this.name = 'NotFoundError';
    this.code = 404;
    this.details = details;
    Object.setPrototypeOf(this, NotFoundError.prototype);
  }
}
// Repeat for ValidationError, UnauthorizedError, ServerError...

After @hiennc24/common:

import {
  NotFoundError,
  ValidationError,
  UnauthorizedError,
  ErrorFactory
} from '@hiennc24/common';

// Use directly
throw new NotFoundError('User not found', 'USER_NOT_FOUND', { userId: '123' });

// Or use the factory for common patterns
throw ErrorFactory.createNotFoundError('User', userId, { requestId });
throw ErrorFactory.createValidationError('Invalid email', ['email'], { value });

Includes: ServerError, NotFoundError, ValidationError, UnauthorizedError, PermissionDeniedError, BadRequestError, ConflictError, AlreadyExistsError, TooManyRequestsError, ServiceUnavailableError


๐Ÿ”’ Built-in Security Against NoSQL Injection

Your MongoDB queries are only as secure as your input sanitization.

import { sanitizeMongoFilter } from '@hiennc24/common';

// Dangerous user input
const maliciousInput = {
  email: 'user@example.com',
  $where: 'this.password.length > 0', // ๐Ÿšจ Injection attempt - blocked
  $function: { body: 'return true' }   // ๐Ÿšจ Code execution - blocked
};

// Automatically strips dangerous operators
const safeFilter = sanitizeMongoFilter(maliciousInput);
// Result: { email: 'user@example.com' } โœ…

// Handles circular references (prevents DoS)
const circular: any = { a: 1 };
circular.self = circular;
sanitizeMongoFilter(circular); // Won't crash your app โœ…

Protects against: $where, $function, $expr, $accumulator, $mapReduce, group, and other code execution operators. Safe query operators like $ne, $regex, $in are allowed.


๐Ÿ—„๏ธ Multi-Tenant Database Management

Managing connections for 100+ tenants? ConnectMultipleDB handles caching, retry logic, and automatic cleanup.

import { ConnectMultipleDB } from '@hiennc24/common';

const dbManager = new ConnectMultipleDB(
  logger,
  redisCache,
  { getConnectionString: async (domain) => fetchFromVault(domain) },
  { maxPoolSize: 10, maxConnecting: 5 }
);

// Automatically caches connections per tenant
const tenantA_DB = await dbManager.getConnection('tenant-a.com');
const tenantB_DB = await dbManager.getConnection('tenant-b.com');

// Auto-closes idle connections after 2 hours (configurable)
// Retry logic with exponential backoff built-in

Features:

  • Connection pooling per tenant
  • Redis-backed caching (1-hour TTL)
  • Automatic idle connection cleanup
  • Configurable retry attempts (default: 5)
  • Domain validation and encryption support

โœ… Type-Safe Validation Service

Stop repeating the same null checks and type guards.

import { ValidationService } from '@hiennc24/common';

// Before: Manual validation everywhere
if (!entity || typeof entity !== 'object') {
  throw new Error('Invalid entity');
}
if (!filter || typeof filter !== 'object') {
  throw new Error('Invalid filter');
}

// After: One-liner validation with context
ValidationService.validateEntity(entity, 'createUser');
ValidationService.validateFilter(filter, 'findUsers');
ValidationService.validateCondition(condition, 'updateUser');
ValidationService.validatePipeline(pipeline, 'aggregateData');

// Throws ValidationError with method context for better debugging

๐ŸŽฏ MongoDB-Style Field Projection

Filter entity fields like MongoDB projections, but for plain JavaScript objects.

import { FieldProjector } from '@hiennc24/common';

const user = {
  id: '123',
  email: 'user@example.com',
  password: 'hashed_password',
  role: 'admin',
  createdAt: new Date()
};

// Include only specific fields (MongoDB-style)
const publicUser = FieldProjector.project(user, 'id email role');
// { id: '123', email: 'user@example.com', role: 'admin' }

// Exclude sensitive fields
const safeUser = FieldProjector.project(user, '-password -createdAt');
// { id: '123', email: 'user@example.com', role: 'admin' }

// Object notation also supported
const projected = FieldProjector.project(user, { email: 1, role: 1 });

Perfect for: API responses, logging sanitization, DTOs, GraphQL resolvers


โšก Smart Caching with Multi-Tenancy

Redis caching that understands your multi-tenant architecture.

import { CacheManager } from '@hiennc24/common';

const cache = new CacheManager<User>(
  redisClient,
  logger,
  'user-service',
  'tenant-a.com' // Automatic tenant isolation
);

// Cache with automatic key generation
await cache.set('user:123', userData, { ttl: 3600 });

// Get with type safety
const user = await cache.get<User>('user:123');

// Tenant-specific keys automatically
// Actual Redis key: "tenant-a.com:user-service:user:123"

Features:

  • Automatic tenant isolation
  • Release version support (cache invalidation on deploy)
  • Reference-based caching for complex objects
  • Type-safe generics
  • Development mode bypass

๐Ÿ” AES Encryption Utilities

Simple, secure encryption for configuration and secrets.

import { Crypto } from '@hiennc24/common';

const encrypted = Crypto.encrypt('sensitive-data', 'your-secret-key');
const decrypted = Crypto.decrypt(encrypted, 'your-secret-key');

// Perfect for: API keys in config, connection strings, tokens

๐Ÿ“ Structured Logging with Winston

Pre-configured Winston logger with context support.

import { logger } from '@hiennc24/common';

logger.info('User created', { userId: '123', email: 'user@example.com' });
logger.error('Database error', { error: err.message, stack: err.stack });
logger.warn('Rate limit approaching', { requests: 95, limit: 100 });

๐Ÿ› ๏ธ Essential Helpers

Utilities you copy-paste between projects.

import {
  isChanged,
  findChangedValue,
  waitByPromise,
  isUndefinedOrNull,
  isStringAndNotEmpty
} from '@hiennc24/common';

// Detect changes between objects
const hasChanges = isChanged(originalUser, updatedUser);

// Find exactly what changed
const delta = findChangedValue(originalUser, updatedUser);
// { email: 'new@example.com', role: 'admin' }

// Async sleep
await waitByPromise(1000); // Wait 1 second

// Type guards
if (isStringAndNotEmpty(value)) {
  // TypeScript knows value is string
}

๐Ÿงช Battle-Tested Quality

  • โœ… 188/188 tests passing - Comprehensive test coverage for every feature
  • โœ… 100% TypeScript - Full type definitions with zero any abuse
  • โœ… Zero security vulnerabilities - Regular audits with npm audit
  • โœ… Production-ready - Used in multi-tenant SaaS platforms since v1.0
  • โœ… Actively maintained - Security patches within 48 hours

๐Ÿ“š Full API Reference

Error Classes

  • AppError - Base error class with enhanced details
  • ServerError (500) - Internal server errors
  • NotFoundError (404) - Resource not found
  • ValidationError (400) - Input validation failed
  • UnauthorizedError (401) - Authentication required
  • PermissionDeniedError (403) - Insufficient permissions
  • BadRequestError (400) - Invalid request format
  • ConflictError (409) - Resource conflict
  • AlreadyExistsError (422) - Resource already exists
  • TooManyRequestsError (429) - Rate limit exceeded
  • ServiceUnavailableError (503) - Service unavailable

Error Utilities

  • ErrorUtils.createErrorResponse() - Standardized error responses
  • ErrorUtils.isOperationalError() - Distinguish operational vs programming errors
  • ErrorFactory.createValidationError() - Validation errors with field context
  • ErrorFactory.createAuthError() - Authentication errors
  • ErrorFactory.createNotFoundError() - Resource not found errors

Security

  • sanitizeMongoFilter(filter) - Remove dangerous MongoDB operators
  • Crypto.encrypt(data, key) - AES encryption
  • Crypto.decrypt(data, key) - AES decryption

Database

  • ConnectMultipleDB - Multi-tenant database connection manager
    • getConnection(domain) - Get/create connection for tenant
    • closeConnection(domain) - Close specific connection
    • closeAllConnections() - Cleanup all connections

Validation

  • ValidationService.validateEntity() - Validate entity objects
  • ValidationService.validateFilter() - Validate filter objects
  • ValidationService.validateCondition() - Validate query conditions
  • ValidationService.validatePipeline() - Validate aggregation pipelines

Field Projection

  • FieldProjector.project(entity, projection) - Apply MongoDB-style field filtering

Caching

  • CacheManager<T> - Redis caching with multi-tenancy
    • set(key, value, options) - Cache data
    • get<T>(key) - Retrieve cached data
    • delete(key) - Remove from cache
    • clear() - Clear all cache

Helpers

  • isChanged(source, dest) - Deep equality check
  • findChangedValue(source, dest) - Find changed properties
  • waitByPromise(ms) - Async sleep
  • isUndefinedOrNull(value) - Type guard for null/undefined
  • isStringAndNotEmpty(value) - Type guard for non-empty strings
  • generateTimestamp() - Get current timestamp

Logging

  • logger.info(), logger.error(), logger.warn(), logger.debug() - Winston-based logging

๐Ÿค Contributing

Found a bug? Have a feature request? Contributions welcome!

  1. Fork the repository: https://github.com/hiennc24/common
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Run tests: npm test (all 188 must pass)
  4. Commit changes: git commit -m 'Add amazing feature'
  5. Push to branch: git push origin feature/amazing-feature
  6. Open a Pull Request

Before submitting:

  • Add tests for new features
  • Ensure TypeScript types are correct
  • Update documentation if needed

๐Ÿ› Issues & Support

  • Bug Reports: GitHub Issues
  • Security Issues: Email author directly (see package.json)
  • Questions: Open a discussion on GitHub

๐Ÿ“„ License

ISC License - Copyright (c) Hien Nguyen

See LICENSE for details.


๐ŸŒŸ Support This Project

If @hiennc24/common saves you from writing boilerplate, give it a star on GitHub!

โญ Star on GitHub โญ

Every star helps other developers discover this package and motivates continued maintenance.


๐Ÿ“ฆ Package Stats

  • Bundle Size: Tree-shakeable ESM + CommonJS
  • Dependencies: 6 production dependencies (axios, cron, crypto-js, express, lodash, winston)
  • Node Version: 14+ (TypeScript 4.9+)
  • Framework Agnostic: Works with Express, NestJS, Fastify, Koa, etc.

Stop reinventing the wheel. Start with @hiennc24/common.

npm install @hiennc24/common