UNPKG

houser-js-utils

Version:

A comprehensive collection of TypeScript utility functions for common development tasks including array manipulation, string processing, date handling, random number generation, validation, and much more.

794 lines (793 loc) 26.2 kB
"use strict"; Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); class AuthenticationError extends Error { constructor(message) { super(message); this.name = "AuthenticationError"; } } class AuthorizationError extends Error { constructor(message) { super(message); this.name = "AuthorizationError"; } } class NetworkError extends Error { constructor(message) { super(message); this.name = "NetworkError"; } } class NotFoundError extends Error { constructor(message) { super(message); this.name = "NotFoundError"; } } class TimeoutError extends Error { constructor(message) { super(message); this.name = "TimeoutError"; } } class ValidationError extends Error { constructor(message) { super(message); this.name = "ValidationError"; } } const ErrorUtils = { /** * Captures and reports an error to DataDog. * * @param error - The error to capture and report * @param options - Options for error capture * @param options.log - Whether to log the error to console (default: true) * @param options.tags - Additional tags to add to the error in DataDog * @param options.context - Additional context to add to the error in DataDog * * @example * ```typescript * try { * // Some risky operation * } catch (error) { * ErrorUtils.captureError(error, { * tags: { component: 'UserService' }, * context: { userId: '123' } * }); * } * ``` */ captureError(error, options = {}) { const { log = true, tags = {}, context = {} } = options; const errorObj = error instanceof Error ? error : new Error(String(error)); if (typeof window !== "undefined" && window.DD_LOGS) { window.DD_LOGS.logger.error(errorObj.message, { error: errorObj, ...context, tags: { error_name: errorObj.name, error_stack: errorObj.stack, ...tags } }); } if (log) { console.error(errorObj); } }, /** * Checks if an error is a specific type of error. * * @param error - The error to check * @param errorType - The type of error to check against * @returns True if the error is of the specified type * * @example * ```typescript * const isAuthError = ErrorUtils.isErrorType(error, AuthenticationError); * ``` */ isErrorType(error, errorType) { return error instanceof errorType; }, /** * Validates that a value is a valid array * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid array */ validateArray(value, message = "Invalid array") { if (!Array.isArray(value)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid array length * @param array - Array to validate * @param minLength - Minimum length * @param maxLength - Maximum length * @param message - Error message to throw if validation fails * @throws ValidationError if array length is invalid */ validateArrayLength(array, minLength, maxLength, message = "Invalid array length") { if (array.length < minLength || array.length > maxLength) { throw new ValidationError(message); } }, /** * Validates that an array is not empty * @param array - Array to validate * @param message - Error message to throw if validation fails * @throws ValidationError if array is empty */ validateArrayNotEmpty(array, message) { if (array.length === 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid bigint * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid bigint */ validateBigInt(value, message = "Invalid bigint") { if (typeof value !== "bigint") { throw new ValidationError(message); } }, /** * Validates that a value is a valid boolean * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid boolean */ validateBoolean(value, message = "Invalid boolean value") { if (typeof value !== "boolean") { throw new ValidationError(message); } }, /** * Validates that a value is a valid credit card number * @param cardNumber - Credit card number to validate * @param message - Error message to throw if validation fails * @throws ValidationError if credit card number is invalid */ validateCreditCard(cardNumber, message = "Invalid credit card number") { const cleanNumber = cardNumber.replace(/[\s-]/g, ""); if (!/^\d+$/.test(cleanNumber)) { throw new ValidationError(message); } let sum = 0; let isEven = false; for (let i = cleanNumber.length - 1; i >= 0; i--) { let digit = parseInt(cleanNumber.charAt(i)); if (isEven) { digit *= 2; if (digit > 9) { digit -= 9; } } sum += digit; isEven = !isEven; } if (sum % 10 !== 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid date * @param date - Date to validate * @param message - Error message to throw if validation fails * @throws ValidationError if date is invalid */ validateDate(date, message = "Invalid date") { const dateObj = new Date(date); if (isNaN(dateObj.getTime())) { throw new ValidationError(message); } }, /** * Validates that a value is a valid date instance * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid date instance */ validateDateInstance(value, message = "Invalid date") { if (!(value instanceof Date) || isNaN(value.getTime())) { throw new ValidationError(message); } }, /** * Validates that a value is a valid date range * @param startDate - Start date * @param endDate - End date * @param message - Error message to throw if validation fails * @throws ValidationError if date range is invalid */ validateDateRange(startDate, endDate, message = "Invalid date range") { const start = new Date(startDate); const end = new Date(endDate); if (isNaN(start.getTime()) || isNaN(end.getTime())) { throw new ValidationError(message); } if (start > end) { throw new ValidationError(message); } }, /** * Validates that a value is a valid email address * @param email - Email address to validate * @param message - Error message to throw if validation fails * @throws ValidationError if email is invalid */ validateEmail(email, message = "Invalid email address") { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; this.validateRegex(email, emailRegex, message); }, /** * Validates that a value is a valid enum value * @param value - Value to validate * @param enumObj - Enum object to validate against * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid enum value */ validateEnum(value, enumObj, message = "Invalid enum value") { if (!Object.values(enumObj).includes(value)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid file size * @param size - File size in bytes * @param maxSize - Maximum file size in bytes * @param message - Error message to throw if validation fails * @throws ValidationError if file size is invalid */ validateFileSize(size, maxSize, message = "File size exceeds maximum allowed size") { if (size < 0 || size > maxSize) { throw new ValidationError(message); } }, /** * Validates that a value is a valid file type * @param file - File to validate * @param allowedTypes - Array of allowed MIME types * @param message - Error message to throw if validation fails * @throws ValidationError if file type is invalid */ validateFileType(file, allowedTypes, message = "Invalid file type") { if (!allowedTypes.includes(file.type)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid function * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid function */ validateFunction(value, message = "Invalid function") { if (typeof value !== "function") { throw new ValidationError(message); } }, /** * Validates that a value is a valid image dimension * @param width - Image width * @param height - Image height * @param maxWidth - Maximum width * @param maxHeight - Maximum height * @param message - Error message to throw if validation fails * @throws ValidationError if image dimension is invalid */ validateImageDimension(width, height, maxWidth, maxHeight, message = "Invalid image dimension") { if (width <= 0 || height <= 0 || width > maxWidth || height > maxHeight) { throw new ValidationError(message); } }, /** * Validates that a value is a valid integer * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid integer */ validateInteger(value, message = "Invalid integer") { this.validateNumber(value, message); if (!Number.isInteger(value)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid IP address * @param ip - IP address to validate * @param version - IP version (4 or 6) * @param message - Error message to throw if validation fails * @throws ValidationError if IP address is invalid */ validateIP(ip, version = 4, message = "Invalid IP address") { const patterns = { 4: /^(\d{1,3}\.){3}\d{1,3}$/, 6: /^([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$/ }; this.validateRegex(ip, patterns[version], message); if (version === 4) { const parts = ip.split("."); for (const part of parts) { const num = parseInt(part); if (num < 0 || num > 255) { throw new ValidationError(message); } } } }, /** * Validates that a value is a valid MAC address * @param mac - MAC address to validate * @param message - Error message to throw if validation fails * @throws ValidationError if MAC address is invalid */ validateMAC(mac, message = "Invalid MAC address") { const macRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/; this.validateRegex(mac, macRegex, message); }, /** * Validates that a value is a valid map * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid map */ validateMap(value, message = "Invalid map") { if (!(value instanceof Map)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid negative number * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid negative number */ validateNegativeNumber(value, message = "Invalid negative number") { this.validateNumber(value, message); if (value >= 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid non-null * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is null */ validateNonNull(value, message = "Value must not be null") { if (value === null) { throw new ValidationError(message); } }, /** * Validates that a value is a valid non-null and non-undefined * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is null or undefined */ validateNonNullOrUndefined(value, message = "Value must not be null or undefined") { if (value === null || value === void 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid non-undefined * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is undefined */ validateNonUndefined(value, message = "Value must not be undefined") { if (value === void 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid null * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not null */ validateNull(value, message = "Value must be null") { if (value !== null) { throw new ValidationError(message); } }, /** * Validates that a value is a valid null or undefined * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not null or undefined */ validateNullOrUndefined(value, message = "Value must be null or undefined") { if (value !== null && value !== void 0) { throw new ValidationError(message); } }, /** * Validates that a value is not null or undefined * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is null or undefined */ validateNotNull(value, message) { if (value === null || value === void 0) { throw new ValidationError(message); } }, /** * Validates that a string is not empty * @param value - String to validate * @param message - Error message to throw if validation fails * @throws ValidationError if string is empty */ validateNotEmpty(value, message) { if (!value.trim()) { throw new ValidationError(message); } }, /** * Validates that a value is a valid number * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid number */ validateNumber(value, message = "Invalid number") { if (typeof value !== "number" || isNaN(value)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid object * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid object */ validateObject(value, message = "Invalid object") { if (typeof value !== "object" || value === null) { throw new ValidationError(message); } }, /** * Validates that a value is a valid object key * @param obj - Object to validate * @param key - Key to validate * @param message - Error message to throw if validation fails * @throws ValidationError if object key is invalid */ validateObjectKey(obj, key, message = "Invalid object key") { if (!(key in obj)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid password * @param password - Password to validate * @param options - Password validation options * @throws ValidationError if password doesn't meet requirements */ validatePassword(password, options = {}) { const { minLength = 8, requireUppercase = true, requireLowercase = true, requireNumber = true, requireSpecialChar = true, message = "Invalid password" } = options; if (password.length < minLength) { throw new ValidationError(`${message}: Minimum length is ${minLength}`); } if (requireUppercase && !/[A-Z]/.test(password)) { throw new ValidationError(`${message}: Must contain uppercase letter`); } if (requireLowercase && !/[a-z]/.test(password)) { throw new ValidationError(`${message}: Must contain lowercase letter`); } if (requireNumber && !/\d/.test(password)) { throw new ValidationError(`${message}: Must contain number`); } if (requireSpecialChar && !/[!@#$%^&*(),.?":{}|<>]/.test(password)) { throw new ValidationError(`${message}: Must contain special character`); } }, /** * Validates that a value is a valid phone number * @param phone - Phone number to validate * @param message - Error message to throw if validation fails * @throws ValidationError if phone number is invalid */ validatePhone(phone, message = "Invalid phone number") { const phoneRegex = /^\+?[\d\s-()]{10,}$/; this.validateRegex(phone, phoneRegex, message); }, /** * Validates that a value is a valid positive number * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid positive number */ validatePositiveNumber(value, message = "Invalid positive number") { this.validateNumber(value, message); if (value <= 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid postal code * @param postalCode - Postal code to validate * @param country - Country code for postal code format * @param message - Error message to throw if validation fails * @throws ValidationError if postal code is invalid */ validatePostalCode(postalCode, country = "US", message = "Invalid postal code") { const patterns = { US: /^\d{5}(-\d{4})?$/, CA: /^[A-Z]\d[A-Z] \d[A-Z]\d$/, UK: /^[A-Z]{1,2}\d[A-Z\d]? ?\d[A-Z]{2}$/ }; this.validateRegex(postalCode, patterns[country], message); }, /** * Validates that a value is a valid promise * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid promise */ validatePromise(value, message = "Invalid promise") { if (!(value instanceof Promise)) { throw new ValidationError(message); } }, /** * Validates that a number is within a range * @param value - Number to validate * @param min - Minimum value (inclusive) * @param max - Maximum value (inclusive) * @param message - Error message to throw if validation fails * @throws ValidationError if number is outside range */ validateRange(value, min, max, message) { if (value < min || value > max) { throw new ValidationError(message); } }, /** * Validates that a value matches a regular expression * @param value - String to validate * @param regex - Regular expression to match against * @param message - Error message to throw if validation fails * @throws ValidationError if value doesn't match regex */ validateRegex(value, regex, message) { if (!regex.test(value)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid regular expression * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid regular expression */ validateRegExp(value, message = "Invalid regular expression") { if (!(value instanceof RegExp)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid set * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid set */ validateSet(value, message = "Invalid set") { if (!(value instanceof Set)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid social security number * @param ssn - Social security number to validate * @param message - Error message to throw if validation fails * @throws ValidationError if SSN is invalid */ validateSSN(ssn, message = "Invalid SSN") { const ssnRegex = /^(?!000|666)[0-8][0-9]{2}-(?!00)[0-9]{2}-(?!0000)[0-9]{4}$/; this.validateRegex(ssn, ssnRegex, message); }, /** * Validates that a value is a valid string * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid string */ validateString(value, message = "Invalid string") { if (typeof value !== "string") { throw new ValidationError(message); } }, /** * Validates that a value is a valid symbol * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid symbol */ validateSymbol(value, message = "Invalid symbol") { if (typeof value !== "symbol") { throw new ValidationError(message); } }, /** * Validates that a value is a valid time string * @param time - Time string to validate * @param format - Time format (12h or 24h) * @param message - Error message to throw if validation fails * @throws ValidationError if time string is invalid */ validateTime(time, format = "24h", message = "Invalid time") { const patterns = { "12h": /^(0?[1-9]|1[0-2]):[0-5][0-9] (AM|PM)$/i, "24h": /^([01]?[0-9]|2[0-3]):[0-5][0-9]$/ }; this.validateRegex(time, patterns[format], message); }, /** * Validates that a value is a valid undefined * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not undefined */ validateUndefined(value, message = "Value must be undefined") { if (value !== void 0) { throw new ValidationError(message); } }, /** * Validates that a value is a valid URL * @param url - URL to validate * @param message - Error message to throw if validation fails * @throws ValidationError if URL is invalid */ validateUrl(url, message = "Invalid URL") { try { new URL(url); } catch { throw new ValidationError(message); } }, /** * Validates that a value is a valid UUID * @param uuid - UUID to validate * @param version - UUID version (1-5) * @param message - Error message to throw if validation fails * @throws ValidationError if UUID is invalid * @example * ```typescript * // Validate a random UUID (version 4) * ErrorUtils.validateUUID('123e4567-e89b-12d3-a456-426614174000', 4); * * // Validate a time-based UUID (version 1) * ErrorUtils.validateUUID('123e4567-e89b-12d3-a456-426614174000', 1); * ``` */ validateUUID(uuid, version = 4, message = "Invalid UUID") { const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i; if (!uuidRegex.test(uuid)) { throw new ValidationError(message); } const versionHex = uuid.charAt(14); const actualVersion = parseInt(versionHex, 16); if (actualVersion !== version) { throw new ValidationError( `${message}: Expected version ${version}, got version ${actualVersion}` ); } const clockSeqHi = parseInt(uuid.charAt(19), 16); switch (version) { case 1: if ((clockSeqHi & 192) !== 128) { throw new ValidationError( `${message}: Invalid version 1 UUID clock sequence` ); } break; case 2: if ((clockSeqHi & 192) !== 128) { throw new ValidationError( `${message}: Invalid version 2 UUID clock sequence` ); } break; case 3: if ((clockSeqHi & 192) !== 64) { throw new ValidationError( `${message}: Invalid version 3 UUID clock sequence` ); } break; case 4: if ((clockSeqHi & 192) !== 64) { throw new ValidationError( `${message}: Invalid version 4 UUID clock sequence` ); } break; case 5: if ((clockSeqHi & 192) !== 64) { throw new ValidationError( `${message}: Invalid version 5 UUID clock sequence` ); } break; } }, /** * Validates that a value is a valid weak map * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid weak map */ validateWeakMap(value, message = "Invalid weak map") { if (!(value instanceof WeakMap)) { throw new ValidationError(message); } }, /** * Validates that a value is a valid weak set * @param value - Value to validate * @param message - Error message to throw if validation fails * @throws ValidationError if value is not a valid weak set */ validateWeakSet(value, message = "Invalid weak set") { if (!(value instanceof WeakSet)) { throw new ValidationError(message); } }, /** * Wraps an async function with error handling * @param fn - Async function to wrap * @param errorHandler - Function to handle errors * @returns Wrapped async function */ withAsyncErrorHandling(fn, errorHandler) { return async (...args) => { try { return await fn(...args); } catch (error) { errorHandler(error); throw error; } }; }, /** * Wraps a function with error handling * @param fn - Function to wrap * @param errorHandler - Function to handle errors * @returns Wrapped function */ withErrorHandling(fn, errorHandler) { return (...args) => { try { return fn(...args); } catch (error) { errorHandler(error); throw error; } }; } }; exports.AuthenticationError = AuthenticationError; exports.AuthorizationError = AuthorizationError; exports.ErrorUtils = ErrorUtils; exports.NetworkError = NetworkError; exports.NotFoundError = NotFoundError; exports.TimeoutError = TimeoutError; exports.ValidationError = ValidationError; //# sourceMappingURL=ErrorUtils.js.map