@cocrepo/toolkit
v1.3.16
Published
Comprehensive toolkit of utility functions and helpers for the Cocrepo monorepo.
Readme
@cocrepo/toolkit
Comprehensive toolkit of utility functions and helpers for the Cocrepo monorepo.
Overview
@cocrepo/toolkit provides a comprehensive collection of utility functions for common tasks including data transformation, validation, date manipulation, logging, and type conversion.
Features
- 🛠️ Utility Functions - Common data manipulation and transformation
- 📅 Date Utilities - Date formatting and manipulation with dayjs
- 🔍 Validation - Class-validator based validation utilities
- 🎯 Type Transformation - Class-transformer for DTO/model conversion
- 📝 Logging - Structured logging utilities
- 🔄 Data Parsing - Path parsing and route matching
Installation
pnpm add @cocrepo/toolkitUsage
Data Transformation
import { transformToDto, transformFromDto } from '@cocrepo/toolkit';
// Transform plain object to DTO instance
const userDto = transformToDto(UserDto, plainObject);
// Transform DTO to plain object
const plainUser = transformFromDto(userDto);Validation
import { validateDto, isValid } from '@cocrepo/toolkit';
async function createUser(data: CreateUserDto) {
const errors = await validateDto(data);
if (errors.length > 0) {
throw new ValidationError('Invalid user data', errors);
}
// Proceed with valid data
}Date Utilities
import {
formatDate,
parseDate,
isAfter,
isBefore,
addDays
} from '@cocrepo/toolkit';
// Format dates
const formatted = formatDate(new Date(), 'YYYY-MM-DD');
// Parse dates
const date = parseDate('2024-01-15');
// Date comparisons
if (isAfter(date1, date2)) {
// date1 is after date2
}
// Date arithmetic
const futureDate = addDays(new Date(), 7);Logging
import { createLogger, logger } from '@cocrepo/toolkit';
// Create namespaced logger
const log = createLogger('[MyComponent]');
log.info('User logged in', { userId: 123 });
log.warn('Rate limit approaching');
log.error('Failed to fetch data', error);
// Use global logger
logger.debug('Debug information');Navigation Utilities
import { navigateTo, parseRoute } from '@cocrepo/toolkit';
// Programmatic navigation
navigateTo('/users/123');
// Parse route with parameters
const { params } = parseRoute('/users/:id', '/users/123');
console.log(params.id); // '123'Array Utilities
import {
chunk,
unique,
groupBy,
sortBy,
flattenDeep
} from '@cocrepo/toolkit';
// Chunk array into smaller arrays
const chunks = chunk([1, 2, 3, 4, 5], 2);
// [[1, 2], [3, 4], [5]]
// Get unique values
const uniqueValues = unique([1, 2, 2, 3, 3, 3]);
// [1, 2, 3]
// Group by property
const grouped = groupBy(users, 'role');
// { admin: [...], user: [...] }
// Sort by property
const sorted = sortBy(users, 'name');Object Utilities
import {
pick,
omit,
merge,
cloneDeep,
isEmpty
} from '@cocrepo/toolkit';
// Pick specific properties
const subset = pick(user, ['id', 'name', 'email']);
// Omit specific properties
const safe = omit(user, ['password', 'token']);
// Deep merge objects
const merged = merge(defaults, options);
// Deep clone
const clone = cloneDeep(original);
// Check if empty
if (isEmpty(obj)) {
// Object is empty
}String Utilities
import {
capitalize,
camelCase,
snakeCase,
kebabCase,
truncate
} from '@cocrepo/toolkit';
// Capitalize first letter
const title = capitalize('hello world'); // 'Hello world'
// Case transformations
const camel = camelCase('hello-world'); // 'helloWorld'
const snake = snakeCase('helloWorld'); // 'hello_world'
const kebab = kebabCase('helloWorld'); // 'hello-world'
// Truncate strings
const short = truncate('Long text here...', 10); // 'Long text...'Type Guards
import {
isString,
isNumber,
isArray,
isObject,
isFunction,
isNil
} from '@cocrepo/toolkit';
if (isString(value)) {
// TypeScript knows value is string
console.log(value.toUpperCase());
}
if (isArray(value)) {
// TypeScript knows value is array
value.forEach(item => console.log(item));
}API Reference
Transformation
transformToDto<T>(cls: Class<T>, plain: any): TtransformFromDto<T>(dto: T): anytransformArray<T>(cls: Class<T>, array: any[]): T[]
Validation
validateDto<T>(dto: T): Promise<ValidationError[]>isValid<T>(dto: T): Promise<boolean>
Date & Time
formatDate(date: Date, format: string): stringparseDate(dateString: string): DateaddDays(date: Date, days: number): DateaddMonths(date: Date, months: number): DateisAfter(date1: Date, date2: Date): booleanisBefore(date1: Date, date2: Date): boolean
Logging
createLogger(namespace: string): Loggerlogger.info/warn/error/debug(message: string, ...args: any[])
Navigation
navigateTo(path: string): voidparseRoute(pattern: string, path: string): RouteMatch
Collections (from remeda & lodash)
- Array:
chunk,unique,flatten,groupBy,sortBy - Object:
pick,omit,merge,clone,isEmpty - String:
capitalize,camelCase,snakeCase,kebabCase
Testing
# Run tests
pnpm test
# Watch mode
pnpm test:watch
# Coverage
pnpm test:coverage
# UI mode
pnpm test:uiBuild
# Build the package
pnpm build
# Development mode with watch
pnpm start:devTypeScript Support
Full TypeScript support with type definitions:
import type { Logger, ValidationError, RouteMatch } from '@cocrepo/toolkit';
const logger: Logger = createLogger('[App]');
function handleValidation(errors: ValidationError[]) {
errors.forEach(error => {
console.log(error.property, error.constraints);
});
}Dependencies
Core Dependencies
Peer Dependencies
class-transformer- Object transformationclass-validator- Validationdayjs- Date manipulationpath-parser- Route parsingreflect-metadata- Metadata reflectionremeda- Functional utilities
Best Practices
- Import Selectively - Tree-shaking optimizes bundle size
- Use Type Guards - Leverage TypeScript narrowing
- Validate Early - Validate at boundaries (API, forms)
- Log Strategically - Use namespaced loggers for context
- Immutable Operations - Prefer immutable transformations
Example: Complete Validation Flow
import {
transformToDto,
validateDto,
createLogger
} from '@cocrepo/toolkit';
const logger = createLogger('[UserService]');
async function createUser(data: unknown) {
// Transform to DTO
const userDto = transformToDto(CreateUserDto, data);
// Validate
const errors = await validateDto(userDto);
if (errors.length > 0) {
logger.error('Validation failed', { errors });
throw new ValidationError('Invalid user data', errors);
}
// Process valid data
logger.info('Creating user', { email: userDto.email });
return await saveUser(userDto);
}Performance
- ✅ Tree-shakeable exports
- ✅ ESM and CommonJS builds
- ✅ Optimized bundle size
- ✅ No runtime overhead for type guards
Contributing
When adding new utilities:
- Group related functions logically
- Add JSDoc comments
- Write unit tests
- Update documentation
- Consider tree-shaking impact
License
ISC
