/** * String Utilities - Core Module * * Framework-agnostic string manipulation and formatting functions. * Can be used in any project (NestJS, Express, Frontend, etc.) * * @module @core/utils/string * @version 1.0.0 */ /** * Generate slug from string * @example slugify("Hello World!") => "hello-world" */ export const slugify = (text: string): string => { return text .toString() .toLowerCase() .trim() .replace(/\s+/g, '-') .replace(/[^\w-]+/g, '') .replace(/--+/g, '-') .replace(/^-+/, '') .replace(/-+$/, ''); }; /** * Capitalize first letter * @example capitalize("hello") => "Hello" */ export const capitalize = (text: string): string => { if (!text) return ''; return text.charAt(0).toUpperCase() + text.slice(1).toLowerCase(); }; /** * Capitalize each word * @example capitalizeWords("hello world") => "Hello World" */ export const capitalizeWords = (text: string): string => { return text .split(' ') .map((word) => capitalize(word)) .join(' '); }; /** * Truncate string with ellipsis * @example truncate("Hello World", 8) => "Hello..." */ export const truncate = (text: string, maxLength: number): string => { if (text.length <= maxLength) return text; return text.substring(0, maxLength - 3) + '...'; }; /** * Remove HTML tags * @example stripHtml("
Hello
") => "Hello" */ export const stripHtml = (html: string): string => { return html.replace(/<[^>]*>/g, ''); }; /** * Sanitize string (remove special chars except spaces) */ export const sanitize = (text: string): string => { return text.replace(/[^\w\s]/gi, ''); }; /** * Check if string is empty or whitespace */ export const isEmpty = (text: string | null | undefined): boolean => { return !text || text.trim().length === 0; }; /** * Check if string is not empty */ export const isNotEmpty = (text: string | null | undefined): boolean => { return !isEmpty(text); }; /** * Generate random string * @param length - Length of string (default: 10) * @param charset - Character set to use (default: alphanumeric) */ export const randomString = ( length: number = 10, charset: string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', ): string => { let result = ''; for (let i = 0; i < length; i++) { result += charset.charAt(Math.floor(Math.random() * charset.length)); } return result; }; /** * Generate random numeric string */ export const randomNumeric = (length: number = 6): string => { return randomString(length, '0123456789'); }; /** * Mask sensitive data (show only last N chars) * @example maskString("1234567890", 4) => "******7890" */ export const maskString = (text: string, visibleChars: number = 4): string => { if (text.length <= visibleChars) return text; const masked = '*'.repeat(text.length - visibleChars); return masked + text.slice(-visibleChars); }; /** * Mask email (show first 2 chars and domain) * @example maskEmail("john@example.com") => "jo***@example.com" */ export const maskEmail = (email: string): string => { const [local, domain] = email.split('@'); if (!domain) return email; const maskedLocal = local.substring(0, 2) + '***'; return `${maskedLocal}@${domain}`; }; /** * Convert string to camelCase * @example toCamelCase("hello world") => "helloWorld" */ export const toCamelCase = (text: string): string => { return text .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) => index === 0 ? word.toLowerCase() : word.toUpperCase(), ) .replace(/\s+/g, ''); }; /** * Convert string to snake_case * @example toSnakeCase("helloWorld") => "hello_world" */ export const toSnakeCase = (text: string): string => { return text .replace(/([A-Z])/g, '_$1') .toLowerCase() .replace(/^_/, '') .replace(/\s+/g, '_'); }; /** * Convert string to kebab-case * @example toKebabCase("helloWorld") => "hello-world" */ export const toKebabCase = (text: string): string => { return text .replace(/([A-Z])/g, '-$1') .toLowerCase() .replace(/^-/, '') .replace(/\s+/g, '-'); }; /** * Convert string to CONSTANT_CASE * @example toConstantCase("helloWorld") => "HELLO_WORLD" */ export const toConstantCase = (text: string): string => { return toSnakeCase(text).toUpperCase(); }; /** * Convert string to PascalCase * @example toPascalCase("hello world") => "HelloWorld" */ export const toPascalCase = (text: string): string => { return text .replace(/(?:^\w|[A-Z]|\b\w)/g, (word) => word.toUpperCase()) .replace(/\s+/g, ''); }; /** * Escape regex special characters */ export const escapeRegex = (text: string): string => { return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }; /** * Count words in string */ export const wordCount = (text: string): number => { if (isEmpty(text)) return 0; return text.trim().split(/\s+/).length; }; /** * Reverse string */ export const reverse = (text: string): string => { return text.split('').reverse().join(''); }; /** * Pad string on left * @example padLeft("5", 3, "0") => "005" */ export const padLeft = (text: string, length: number, char: string = ' '): string => { return text.padStart(length, char); }; /** * Pad string on right * @example padRight("5", 3, "0") => "500" */ export const padRight = (text: string, length: number, char: string = ' '): string => { return text.padEnd(length, char); }; /** * Remove accents from string * @example removeAccents("café") => "cafe" */ export const removeAccents = (text: string): string => { return text.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); }; /** * Extract initials from name * @example getInitials("John Doe") => "JD" */ export const getInitials = (name: string, maxChars: number = 2): string => { return name .split(' ') .map((word) => word.charAt(0).toUpperCase()) .slice(0, maxChars) .join(''); }; /** * Format number as currency string * @example formatCurrency(1234.5, "USD") => "$1,234.50" */ export const formatCurrency = ( amount: number, currency: string = 'USD', locale: string = 'en-US', ): string => { return new Intl.NumberFormat(locale, { style: 'currency', currency, }).format(amount); }; /** * Format number with thousands separator * @example formatNumber(1234567) => "1,234,567" */ export const formatNumber = (num: number, locale: string = 'en-US'): string => { return new Intl.NumberFormat(locale).format(num); }; /** * Parse query string to object * @example parseQueryString("?foo=bar&baz=qux") => { foo: "bar", baz: "qux" } */ export const parseQueryString = (queryString: string): Record