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
JavaScript
;
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