### ApiFile Decorator for Documenting File Uploads in NestJS Swagger Source: https://context7.com/bangbang93/node-utils/llms.txt A decorator that configures Swagger documentation for file upload endpoints. It simplifies the process of documenting file upload fields when using libraries like Multer and @nestjs/platform-express. ```typescript import { ApiFile, ApiSummary } from '@bangbang93/utils/nestjs' import { Controller, Post, UploadedFile, UseInterceptors } from '@nestjs/common' import { FileInterceptor } from '@nestjs/platform-express' @Controller('uploads') export class UploadController { @Post('avatar') @ApiSummary('Upload user avatar') @ApiFile('avatar') @UseInterceptors(FileInterceptor('avatar')) async uploadAvatar(@UploadedFile() file: Express.Multer.File) { return this.uploadService.saveAvatar(file) } @Post('document') @ApiFile('document') @UseInterceptors(FileInterceptor('document')) async uploadDocument(@UploadedFile() file: Express.Multer.File) { return this.uploadService.saveDocument(file) } } ``` -------------------------------- ### Jest Mock Factory for NestJS Testing Source: https://context7.com/bangbang93/node-utils/llms.txt The createMocker utility from '@bangbang93/utils/testing' generates a mock factory for creating mock instances of classes, which is particularly useful for testing NestJS applications. It integrates with Jest and provides methods to mock services and reset mocks between tests. ```typescript import { createMocker } from '@bangbang93/utils/testing' import { Test } from '@nestjs/testing' import { UserService } from './user.service' import { UserController } from './user.controller' describe('UserController', () => { const { mock, reset } = createMocker() beforeEach(() => { reset() // Reset all mocks between tests }) it('should get user', async () => { const module = await Test.createTestingModule({ controllers: [UserController], providers: [ { provide: UserService, useFactory: () => mock(UserService) } ] }).compile() const controller = module.get(UserController) const userService = module.get(UserService) // Mock is automatically created with all methods as jest.fn() ;(userService.getById as jest.Mock).mockResolvedValue({ id: '1', name: 'Test' }) const result = await controller.getUser('1') expect(result).toEqual({ id: '1', name: 'Test' }) }) }) ``` -------------------------------- ### Configure Protobuf Type Wrappers and DTO Unwrapping Source: https://context7.com/bangbang93/node-utils/llms.txt Configures protobufjs to handle Date objects and Long numbers automatically. It also provides a utility to unwrap paged DTOs from protobuf responses, ensuring consistent data structures. ```typescript import { applyWrappers, unwrapPagedDto } from '@bangbang93/utils/protobufjs' // Apply wrappers at application startup applyWrappers() // Now protobuf Timestamp fields automatically convert to/from Date const message = MyProtoMessage.fromObject({ createdAt: new Date(), // Converts to Timestamp updatedAt: '2024-01-15T10:00:00' // String also works }) const obj = MyProtoMessage.toObject(message) console.log(obj.createdAt instanceof Date) // true // Unwrap paged DTOs from protobuf responses const pagedResponse = unwrapPagedDto(protoMessage) // { count: number, data: array } with defaults for undefined ``` -------------------------------- ### PagedDto and SortablePagedDto for Pagination Requests in NestJS Source: https://context7.com/bangbang93/node-utils/llms.txt Validated DTO classes for handling pagination parameters. PagedDto includes page, limit, and calculated skip. SortablePagedDto extends PagedDto with sorting capabilities. Both support default values and minimum/maximum constraints. ```typescript import { PagedDto, SortablePagedDto, setDefaultPageLimit } from '@bangbang93/utils/nestjs' import { Controller, Get, Query } from '@nestjs/common' // Configure default limit defaultSetPageLimit(20) @Controller('users') export class UserController { @Get() async list(@Query() query: PagedDto) { // query.page: number (default: 1, min: 1) // query.limit: number (default: 20, min: 1, max: 500) // query.skip: calculated as (page - 1) * limit return this.userService.find({}, query.skip, query.limit) } } // With sorting support @Controller('posts') export class PostController { @Get() async list(@Query() query: SortablePagedDto) { // Includes all PagedDto fields plus: // query.sort: string (e.g., '+createdAt', '-views') const sort = parseSortMongo(query.sort) return this.postService.find({}, query.skip, query.limit, sort) } } ``` -------------------------------- ### MongoDB Utilities Source: https://context7.com/bangbang93/node-utils/llms.txt Helper functions for MongoDB operations including ID conversion, query building, and pagination. ```APIDOC ## POST /mongodb/toObjectId ### Description Safely converts a string or existing ObjectId into a Mongoose ObjectId. ### Parameters - **id** (string | ObjectId) - Required - The value to convert. ### Response - **ObjectId** (Object) - The converted Mongoose ObjectId. --- ## POST /mongodb/buildQuery ### Description Dynamically constructs a MongoDB query object based on a search input object and configuration mapping. ### Parameters - **search** (Object) - Required - The raw search criteria. - **options** (Object) - Required - Configuration for field mapping (equalFields, matchFields, idFields, etc.). ### Response - **query** (Object) - A formatted MongoDB query filter. --- ## POST /mongodb/findAndCount ### Description Executes a paginated find query on a Mongoose model and returns both the result set and the total document count. ### Parameters - **model** (Model) - Required - The Mongoose model. - **query** (Object) - Required - The filter criteria. - **skip** (number) - Required - Number of documents to skip. - **limit** (number) - Required - Max documents to return. ### Response - **data** (Array) - The retrieved documents. - **count** (number) - Total count of documents matching the query. ``` -------------------------------- ### ApiError Decorator for Documenting Error Responses in NestJS Swagger Source: https://context7.com/bangbang93/node-utils/llms.txt A decorator that documents error responses in Swagger based on service error definitions. It allows specifying error codes, messages, and HTTP status codes for consistent API error documentation. ```typescript import { ApiError, ApiSummary } from '@bangbang93/utils/nestjs' import { Controller, Get, Param } from '@nestjs/common' // Define service errors const ServiceErrors = { USER_NOT_FOUND: ['User not found', 404] as const, UNAUTHORIZED: ['Authentication required', 401] as const, FORBIDDEN: ['Access denied', 403] as const, } as const @Controller('users') export class UserController { @Get(':id') @ApiSummary('Get user by ID') @ApiError(ServiceErrors, 'USER_NOT_FOUND', 'User with specified ID not found') @ApiError(ServiceErrors, 'UNAUTHORIZED') async getUser(@Param('id') id: string) { const user = await this.userService.findById(id) if (!user) { throw new NotFoundException(ServiceErrors.USER_NOT_FOUND[0]) } return user } } ``` -------------------------------- ### Bitwise Operations Source: https://context7.com/bangbang93/node-utils/llms.txt Utilities for managing bit flags using either bit positions or enum-based bitmasks. ```APIDOC ## Bitwise Operations ### Description Provides methods to manipulate and check bit flags. Supports both numeric bit positions and enum-based bitmasks. ### Methods - `setBit(flags, pos)` / `setBitEnum(flags, enum)` - `clearBit(flags, pos)` / `clearBitEnum(flags, enum)` - `toggleBit(flags, pos)` / `toggleEnumBit(flags, enum)` - `isBitSet(flags, pos)` / `isBitEnumSet(flags, enum)` ### Request Example ```typescript // Set bit at position 0 const flags = setBit(0, 0); // 1 ``` ### Response - **result** (number) - The updated bitmask value. ``` -------------------------------- ### Create Batched MongoDB Loader getBaseIdLoader Source: https://context7.com/bangbang93/node-utils/llms.txt The `getBaseIdLoader` utility simplifies the creation of DataLoader instances for efficiently fetching MongoDB documents by their IDs. It integrates with Mongoose models to automatically batch requests, reducing the number of database queries. It supports custom ID casting and is commonly used in GraphQL resolvers. ```typescript import { getBaseIdLoader } from '@bangbang93/utils/mongodb-dataloader' import { loadMany } from '@bangbang93/utils/data-loader' import { User, Post } from './models' // Create loaders (typically per-request in GraphQL) const userLoader = getBaseIdLoader(User) const postLoader = getBaseIdLoader(Post) // Single load const user = await userLoader.load('507f1f77bcf86cd799439011') // Multiple loads (automatically batched) const users = await Promise.all([ userLoader.load(id1), userLoader.load(id2), userLoader.load(id3) ]) // Load many with compact results (removes undefined) const postIds = ['id1', 'id2', 'id3', 'nonexistent'] const posts = await loadMany(postIds, postLoader) // Returns only found documents, skips undefined // Custom ID casting (disable for string IDs) const customLoader = getBaseIdLoader(Model, false) // In GraphQL resolver context const resolvers = { Post: { author: (post, _, { loaders }) => loaders.userLoader.load(post.authorId) } } ``` -------------------------------- ### Bitwise Operations - Check, Set, Clear, Toggle Bits (TypeScript) Source: https://context7.com/bangbang93/node-utils/llms.txt Provides utilities for performing bitwise operations on flags. Supports both direct bit positions (0-indexed) and enum values (bitmasks). It includes functions to check if a bit is set or not set, set a bit, clear a bit, and toggle a bit. ```typescript import { isBitSet, isBitNotSet, setBit, clearBit, toggleBit, isBitEnumSet, isBitEnumNotSet, setBitEnum, clearBitEnum, toggleEnumBit } from '@bangbang93/utils/bitwise' // Using bit positions (0-indexed) let flags = 0 flags = setBit(flags, 0) // Set bit 0: flags = 1 (binary: 0001) flags = setBit(flags, 2) // Set bit 2: flags = 5 (binary: 0101) isBitSet(flags, 0) // true isBitSet(flags, 1) // false isBitNotSet(flags, 1) // true flags = clearBit(flags, 0) // Clear bit 0: flags = 4 (binary: 0100) flags = toggleBit(flags, 1) // Toggle bit 1: flags = 6 (binary: 0110) // Using enum values (bitmasks) enum Permission { READ = 1, // 0001 WRITE = 2, // 0010 EXECUTE = 4, // 0100 ADMIN = 8 // 1000 } let userPerms = 0 userPerms = setBitEnum(userPerms, Permission.READ) // 1 userPerms = setBitEnum(userPerms, Permission.WRITE) // 3 isBitEnumSet(userPerms, Permission.READ) // true isBitEnumSet(userPerms, Permission.ADMIN) // false userPerms = clearBitEnum(userPerms, Permission.WRITE) // 1 userPerms = toggleEnumBit(userPerms, Permission.EXECUTE) // 5 ``` -------------------------------- ### MongoDB Transaction Helper withSession Source: https://context7.com/bangbang93/node-utils/llms.txt The `withSession` function executes a given asynchronous callback within a MongoDB transaction. It automatically manages the transaction session, handling commit or rollback based on the callback's outcome. It can optionally reuse an existing session if provided. ```typescript import { withSession } from '@bangbang93/utils/mongodb' import mongoose from 'mongoose' // Automatic transaction handling async function transferFunds(fromId: string, toId: string, amount: number) { return withSession(async (session) => { await Account.updateOne( { _id: fromId }, { $inc: { balance: -amount } }, { session } ) await Account.updateOne( { _id: toId }, { $inc: { balance: amount } }, { session } ) return { success: true } }, mongoose.connection) } // With existing session (reuses it) async function complexOperation(existingSession?: ClientSession) { return withSession(async (session) => { // Operations use the provided or new session await Model1.create([{ data: 'test' }], { session }) await Model2.updateMany({}, { $set: { processed: true } }, { session }) }, mongoose.connection, existingSession) } ``` -------------------------------- ### Class Transformer Decorators for Validation Source: https://context7.com/bangbang93/node-utils/llms.txt The ToBoolean and Trim decorators from '@bangbang93/utils/validator' are used for automatic value transformation during data validation, typically with class-validator. Trim removes leading/trailing whitespace from strings, and ToBoolean converts string representations of booleans to actual boolean types. ```typescript import { ToBoolean, Trim } from '@bangbang93/utils/validator' import { IsString, IsOptional } from 'class-validator' class CreateUserDto { @Trim() @IsString() name: string @Trim() @IsString() email: string @ToBoolean() @IsOptional() isActive?: boolean @Trim() @IsOptional() @IsString() bio?: string } // Incoming data: { name: ' John ', email: ' john@example.com ', isActive: 'true' } // Transformed: { name: 'John', email: 'john@example.com', isActive: true } ``` -------------------------------- ### Normalize Caught Errors Source: https://context7.com/bangbang93/node-utils/llms.txt The caughtError utility from '@bangbang93/utils/errors' normalizes various types of caught exceptions into standard Error instances. This ensures consistent error handling by providing a proper stack trace and message, regardless of the original error format. ```typescript import { caughtError } from '@bangbang93/utils/errors' async function fetchData() { try { const response = await fetch('/api/data') if (!response.ok) { throw { message: 'API Error', status: response.status } } return response.json() } catch (e) { const error = caughtError(e) // Always an Error instance with proper stack trace console.error(error.message) throw error } } // Handles various error types: caughtError(new Error('Standard error')) // Returns as-is caughtError({ message: 'Object with message' }) // new Error('Object with message') caughtError('String error') // new Error('"String error"') caughtError({ code: 500 }) // new Error('{"code":500}') caughtError(null) // new Error('null') ``` -------------------------------- ### Convert Time String to Seconds with ms - TypeScript Source: https://context7.com/bangbang93/node-utils/llms.txt Converts human-readable time strings (e.g., '1h', '30m', '2d') into seconds using the 'ms' library. Useful for setting cache Time-To-Live (TTL) or timeouts. ```typescript import { second } from '@bangbang93/utils' // Convert time strings to seconds const oneHour = second('1h') // 3600 const thirtyMinutes = second('30m') // 1800 const twoDays = second('2d') // 172800 const fiveSeconds = second('5s') // 5 // Useful for setting cache TTLs, timeouts, etc. const cacheTTL = second('15m') redis.setex('user:123', cacheTTL, JSON.stringify(userData)) ``` -------------------------------- ### Abstract CRUD Service for NestJS and MongoDB Source: https://context7.com/bangbang93/node-utils/llms.txt BaseCrudService is an abstract class that provides standard CRUD operations for MongoDB models within a NestJS application. It requires a Mongoose model as a dependency and offers methods for retrieving, creating, updating, and deleting documents. Custom methods can be added to extend its functionality. ```typescript import { BaseCrudService } from '@bangbang93/utils/nestjs/base-crud-service' import { Injectable } from '@nestjs/common' import { InjectModel } from '@nestjs/mongoose' import { User, UserDocument } from './user.schema' import { RichModelType } from 'mongoose-typescript' @Injectable() export class UserService extends BaseCrudService { constructor( @InjectModel(User.name) private userModel: RichModelType ) { super(userModel) } // Inherited methods: // - getById(id: IdType): Promise // - listByIds(ids: IdType[]): Promise // - create(data: object): Promise // - search(query, skip, limit, queryHelper?): Promise> // - update(id: IdType, data: Partial): Promise // - delete(id: IdType): Promise // Add custom methods async findByEmail(email: string): Promise { return this.userModel.findOne({ email }) } } // Usage in controller import { Controller, Get, Param, Query, Post, Body, Patch, Delete } from '@nestjs/common' import { PagedDto } from './paged.dto' import { CreateUserDto } from './create-user.dto' import { UpdateUserDto } from './update-user.dto' @Controller('users') export class UserController { constructor(private userService: UserService) {} @Get(':id') getUser(@Param('id') id: string) { return this.userService.getById(id) } @Get() listUsers(@Query() { skip, limit }: PagedDto) { return this.userService.search({}, skip, limit) } @Post() createUser(@Body() data: CreateUserDto) { return this.userService.create(data) } @Patch(':id') updateUser(@Param('id') id: string, @Body() data: UpdateUserDto) { return this.userService.update(id, data) } @Delete(':id') deleteUser(@Param('id') id: string) { return this.userService.delete(id) } } ``` -------------------------------- ### Parse Sort Strings for Queries parseSort Source: https://context7.com/bangbang93/node-utils/llms.txt The `parseSort` utility, along with its specific variants `parseSortMongo` and `parseSortMysql`, parses human-readable sort strings (e.g., '+name,-createdAt') into objects compatible with database sorting mechanisms. It supports specifying allowed fields for security and provides default sort orders. ```typescript import { parseSort, parseSortMongo, parseSortMysql } from '@bangbang93/utils/parse-sort' // MongoDB format (1/-1) const mongoSort = parseSortMongo('+name,-createdAt') // { name: 1, createdAt: -1 } const mongoDefault = parseSortMongo(undefined, { defaults: { createdAt: -1 } }) // { createdAt: -1 } // MySQL format (ASC/DESC) const mysqlSort = parseSortMysql('-price,+name') // { price: 'DESC', name: 'ASC' } // With allowed fields (security whitelist) const safeSort = parseSortMongo('+name,-password', { allowFields: ['name', 'email', 'createdAt'] }) // { name: 1 } - password field ignored // Generic usage with flavor option const sort = parseSort('+field1,-field2', { flavor: 'mongo' }) // In API endpoint async function listUsers(sortParam: string) { const sort = parseSortMongo(sortParam, { allowFields: ['name', 'email', 'createdAt', 'updatedAt'], defaults: { createdAt: -1 } }) return User.find().sort(sort) } ``` -------------------------------- ### MongoDB - Paginated Find with Total Count (TypeScript) Source: https://context7.com/bangbang93/node-utils/llms.txt Efficiently executes a MongoDB find query with pagination, returning both the requested data and the total count of matching documents. This utility simplifies implementing paginated results in applications. It supports basic pagination, sorting, and advanced query customization using a callback. ```typescript import { findAndCount, Paged } from '@bangbang93/utils/mongodb' import { User } from './models/user' async function searchUsers(query: object, page: number, limit: number): Promise> { const skip = (page - 1) * limit // Basic usage const result = await findAndCount(User, query, skip, limit) // { count: 150, data: [...users] } // With sorting const sorted = await findAndCount(User, query, skip, limit, { createdAt: -1 }) // With query helper for populate, select, etc. const populated = await findAndCount(User, query, skip, limit, { createdAt: -1 }, (q) => { q.populate('profile') q.select('name email profile') }) return result } // Usage const { count, data } = await searchUsers({ status: 'active' }, 1, 20) console.log(`Found ${count} users, showing ${data.length}`) ``` -------------------------------- ### MongoDB - Build Query from Search Input (TypeScript) Source: https://context7.com/bangbang93/node-utils/llms.txt Constructs MongoDB query filters dynamically from search objects. It supports various matching strategies including exact match, case-insensitive regex, ObjectId conversion, range queries (between), and array inclusion ($in). This function simplifies the creation of complex MongoDB queries. ```typescript import { buildQuery } from '@bangbang93/utils/mongodb' interface UserSearch { name?: string email?: string userId?: string age?: [number, number] status?: string[] roleIds?: string[] } const search: UserSearch = { name: 'John', email: 'example.com', userId: '507f1f77bcf86cd799439011', age: [18, 65], status: ['active', 'pending'], roleIds: ['507f1f77bcf86cd799439012', '507f1f77bcf86cd799439013'] } const query = buildQuery(search, { equalFields: ['name'], // Exact match matchFields: ['email'], // Regex match (case-insensitive) idFields: ['userId'], // Convert to ObjectId betweenFields: ['age'], // $gte/$lte range inFields: ['status'], // $in array inIdFields: ['roleIds'], // $in with ObjectId conversion query: { deleted: false } // Base query to extend }) // Result: // { // deleted: false, // name: 'John', // email: { $regex: 'example\.com', $options: 'i' }, // userId: ObjectId('507f1f77bcf86cd799439011'), // age: { $gte: 18, $lte: 65 }, // status: { $in: ['active', 'pending'] }, // roleIds: { $in: [ObjectId('...'), ObjectId('...')] } // } const users = await User.find(query) ``` -------------------------------- ### generateSwagger Function for Generating OpenAPI JSON in NestJS Source: https://context7.com/bangbang93/node-utils/llms.txt Generates a Swagger/OpenAPI JSON file from a NestJS application module. It allows configuration of title, description, version, API prefix, output path, and server information. ```typescript import { generateSwagger } from '@bangbang93/utils/nestjs' import { AppModule } from './app.module' // Generate swagger.json file await generateSwagger(AppModule, { title: 'My API', description: 'API documentation for My Service', version: '1.0.0', prefix: 'api/v1', outputPath: './docs/swagger.json', servers: [ { url: 'https://api.example.com', description: 'Production' }, { url: 'https://staging-api.example.com', description: 'Staging' } ] }) // In package.json scripts // "swagger": "ts-node scripts/generate-swagger.ts" ``` -------------------------------- ### PagedResDto Factory for Paginated Response DTOs in NestJS Source: https://context7.com/bangbang93/node-utils/llms.txt A factory function that creates a paginated response DTO class, useful for Swagger documentation. It takes a DTO class as an argument and returns a new class that includes count and data fields. ```typescript import { PagedResDto, ApiSummary } from '@bangbang93/utils/nestjs' import { Controller, Get } from '@nestjs/common' import { ApiOkResponse } from '@nestjs/swagger' class UserDto { id: string name: string email: string } // Create paginated response type const PagedUserDto = PagedResDto(UserDto) @Controller('users') export class UserController { @Get() @ApiSummary('List all users') @ApiOkResponse({ type: PagedUserDto }) async list(): Promise> { const users = await this.userService.findAll() return { count: users.total, data: users.items } } } ``` -------------------------------- ### Convert Various Types to Boolean with Null/Undefined Preservation - TypeScript Source: https://context7.com/bangbang93/node-utils/llms.txt Converts string, number, or boolean values to a boolean representation. It supports common string truthy/falsy values and preserves null/undefined inputs. Useful for parsing query parameters. ```typescript import { toBoolean } from '@bangbang93/utils' // String conversions toBoolean('true') // true toBoolean('1') // true toBoolean('yes') // true toBoolean('false') // false toBoolean('no') // false // Number conversions toBoolean(1) // true toBoolean(0) // false // Null/undefined preservation toBoolean(null) // null toBoolean(undefined) // undefined // Useful for parsing query parameters const isEnabled = toBoolean(req.query.enabled) ``` -------------------------------- ### Parse Comparison Operators parseNumberQuery Source: https://context7.com/bangbang93/node-utils/llms.txt The `parseNumberQuery` utility converts string representations of comparison operators (like '>', '<=', '=') into MongoDB query operators (e.g., $gt, $lte, $eq). This is useful for parsing user input from query parameters into a format suitable for MongoDB queries. ```typescript import { parseNumberQuery } from '@bangbang93/utils/mongodb' // Parse comparison strings to MongoDB operators parseNumberQuery('>10') // { $gt: 10 } parseNumberQuery('>=5') // { $gte: 5 } parseNumberQuery('<100') // { $lt: 100 } parseNumberQuery('<=50') // { $lte: 50 } parseNumberQuery('=42') // { $eq: 42 } parseNumberQuery('!=0') // { $ne: 0 } parseNumberQuery('>-10') // { $gt: -10 } // Use in queries const ageFilter = parseNumberQuery(req.query.age) // '>18' const users = await User.find({ age: ageFilter }) ``` -------------------------------- ### Multi-Field Array Sorting - TypeScript Source: https://context7.com/bangbang93/node-utils/llms.txt Sorts arrays by multiple fields, supporting different data types (string, number, boolean, date) and ascending/descending order. It can also accept custom comparison functions. ```typescript import { arraySort, generateSortFunction } from '@bangbang93/utils/array' const users = [ { name: 'Alice', age: 30, active: true, createdAt: new Date('2024-01-15') }, { name: 'Bob', age: 25, active: false, createdAt: new Date('2024-01-10') }, { name: 'Charlie', age: 30, active: true, createdAt: new Date('2024-01-20') } ] // Sort by age ascending, then by name descending const sortedByAge = arraySort(users, { age: '+number', name: '-string' }) // Sort by active status descending, then by date ascending const sortedByStatus = arraySort(users, { active: '-boolean', createdAt: '+date' }) // Custom sort function const customSorted = arraySort(users, { name: (a, b) => a.name.length - b.name.length }) // Generate reusable sort function const sortFn = generateSortFunction({ age: '+number', name: '+string' }) const sorted1 = [...users].sort(sortFn) const sorted2 = [...otherUsers].sort(sortFn) ``` -------------------------------- ### Compare ObjectIds isObjectIdEqual Source: https://context7.com/bangbang93/node-utils/llms.txt The `isObjectIdEqual` function provides a safe way to compare two values that might be MongoDB ObjectIds or their string representations. It handles type coercion, ensuring accurate comparisons between ObjectId instances and strings, and returns false for null or undefined inputs. ```typescript import { isObjectIdEqual, IdType } from '@bangbang93/utils/mongodb' import { Types } from 'mongoose' const id1 = new Types.ObjectId('507f1f77bcf86cd799439011') const id2 = '507f1f77bcf86cd799439011' const id3 = new Types.ObjectId('507f1f77bcf86cd799439012') isObjectIdEqual(id1, id2) // true (ObjectId vs string) isObjectIdEqual(id1, id3) // false isObjectIdEqual(null, undefined) // false isObjectIdEqual(id1, null) // false // Useful for authorization checks function canEdit(userId: IdType, resourceOwnerId: IdType): boolean { return isObjectIdEqual(userId, resourceOwnerId) } ``` -------------------------------- ### MongoDB - Convert to ObjectId (TypeScript) Source: https://context7.com/bangbang93/node-utils/llms.txt Safely converts string or ObjectId values to MongoDB ObjectId. This utility ensures type safety when working with MongoDB identifiers. It handles both string representations and existing ObjectId instances, passing them through directly. ```typescript import { toObjectId, IdType } from '@bangbang93/utils/mongodb' import { Types } from 'mongoose' // String conversion const id1 = toObjectId('507f1f77bcf86cd799439011') // Types.ObjectId // ObjectId passthrough const existingId = new Types.ObjectId() const id2 = toObjectId(existingId) // Same ObjectId // Type-safe function parameter async function getUser(id: IdType) { return User.findById(toObjectId(id)) } // Error handling try { toObjectId('') // Throws TypeError: id cannot be empty } catch (e) { console.error(e.message) } ``` -------------------------------- ### Deprecated Method Decorator - TypeScript Source: https://context7.com/bangbang93/node-utils/llms.txt A TypeScript decorator that marks class methods as deprecated. When a decorated method is called, it logs a deprecation warning to the console, indicating an alternative method to use. ```typescript import { Deprecated } from '@bangbang93/utils' class UserService { @Deprecated('Use findById instead') async getUser(id: string) { return this.findById(id) } async findById(id: string) { // New implementation } } const service = new UserService() await service.getUser('123') // Console: DeprecationWarning: Use findById instead ``` -------------------------------- ### Recursively Trim Object Strings - TypeScript Source: https://context7.com/bangbang93/node-utils/llms.txt Recursively trims whitespace from all string values within a JavaScript object, including those in nested objects. This function helps clean up data before processing or storage. ```typescript import { trimDeep } from '@bangbang93/utils' const userData = { name: ' John Doe ', email: ' john@example.com ', profile: { bio: ' Software developer ', location: ' New York ' } } const trimmed = trimDeep(userData) // Result: // { // name: 'John Doe', // email: 'john@example.com', // profile: { // bio: 'Software developer', // location: 'New York' // } // } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.