UNPKG

@alba-cars/common-modules

Version:

A package containing DTOs, validation classes and common modules and interfaces for Alba Cars

191 lines (190 loc) 6.95 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.booleanize = exports.toPlainObject = exports.sanitizeRegexString = exports.getPlural = exports.hasValue = exports.isEmptyArray = exports.isEmptyObject = exports.isEmpty = exports.makeArray = exports.formatNumberWithCommas = exports.safeParseNumber = exports.currencyFormatter = exports.removeKeyFromObject = exports.timeAsSeconds = exports.timeAsMilliseconds = exports.formatValue = exports.generateRandomBase64 = exports.sortBy = exports.isFunction = exports.isPlainObject = exports.deepEqual = void 0; /** * Deeply compares two objects for equality. * * @param obj1 - The first object to compare. * @param obj2 - The second object to compare. * @returns `true` if the objects are deeply equal, `false` otherwise. */ const deepEqual = (obj1, obj2) => { // this handles primitive types if (obj1 === obj2) { return true; } if (typeof obj1 !== "object" || obj1 === null || typeof obj2 !== "object" || obj2 === null) { return false; } const keys1 = Object.keys(obj1); const keys2 = Object.keys(obj2); if (keys1.length !== keys2.length) { return false; } for (const key of keys1) { if (!keys2.includes(key)) { return false; } } for (const key of keys1) { const value1 = obj1[key]; const value2 = obj2[key]; if (!(0, exports.deepEqual)(value1, value2)) { return false; } } return true; }; exports.deepEqual = deepEqual; /** * Checks if a value is a plain object (not an array or null) * * @template T * @param {T} obj * @returns {boolean} */ const isPlainObject = (obj) => typeof obj === "object" && obj !== null && !Array.isArray(obj); exports.isPlainObject = isPlainObject; /** * Checks if a value is a function * * @param {*} value * @returns {boolean} */ const isFunction = (value) => typeof value === "function"; exports.isFunction = isFunction; /** * Function to sort an array by a specific key (for arrays of objects) or a comparator function * * @param {any[]} array * @param {(string | ComparatorFunction)} key * @returns {any[]} */ const sortBy = (array, key) => { const compareFn = typeof key === "function" ? key : (a, b) => a[key] - b[key]; return array.slice().sort(compareFn); }; exports.sortBy = sortBy; function generateRandomBase64(length) { const randomBytes = new Uint8Array(length); crypto.getRandomValues(randomBytes); return btoa(String.fromCharCode(...Array.from(randomBytes))); } exports.generateRandomBase64 = generateRandomBase64; const formatValue = (n) => { return Number(n) .toString() .replace(/\B(?=(\d{3})+(?!\d))/g, ","); }; exports.formatValue = formatValue; /** * Converts a time input to milliseconds */ const timeAsMilliseconds = ({ minutes = 0, hours = 0, seconds = 0 }) => { return minutes * 60 * 1000 + hours * 60 * 60 * 1000 + seconds * 1000; }; exports.timeAsMilliseconds = timeAsMilliseconds; /** * Converts a time input to seconds */ const timeAsSeconds = ({ minutes = 0, hours = 0, seconds = 0 }) => { return minutes * 60 + hours * 60 * 60 + seconds; }; exports.timeAsSeconds = timeAsSeconds; /** * Removes a key from an object or an array of objects (deeply) */ function removeKeyFromObject(obj, keyToRemove) { if (Array.isArray(obj)) { return obj.map((item) => removeKeyFromObject(item, keyToRemove)); } else if (typeof obj === "object" && obj !== null) { return Object.keys(obj).reduce((acc, key) => { if (key !== keyToRemove) { acc[key] = removeKeyFromObject(obj[key], keyToRemove); } return acc; }, {}); } return obj; } exports.removeKeyFromObject = removeKeyFromObject; /** * Formats a number as a currency string (AED) */ const currencyFormatter = ({ isDecimal, decimalPlaces = 2 }) => new Intl.NumberFormat('en-US', { style: "currency", currency: "AED", maximumFractionDigits: isDecimal ? decimalPlaces : 0, }); exports.currencyFormatter = currencyFormatter; /** * Safely parses a string or number into a number */ const safeParseNumber = (value) => { if (typeof value === 'number') return value; if (typeof value !== 'string') return 0; return Number(value.trim().replace(/,/g, '')) || 0; }; exports.safeParseNumber = safeParseNumber; /** * Formats a number with commas */ const formatNumberWithCommas = (value) => { const number = value.replace(/[^\d]/g, ''); return number.replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; exports.formatNumberWithCommas = formatNumberWithCommas; /** * Converts a single value or an array of values into an array */ const makeArray = (value) => { return Array.isArray(value) ? value : [value]; }; exports.makeArray = makeArray; /** * Check if a value is empty (nullable or empty string) */ const isEmpty = (value) => (value === null || value === undefined || value === ''); exports.isEmpty = isEmpty; /** * Check if an object is an empty object */ const isEmptyObject = (value) => Object.keys(value).length === 0 && value.constructor === Object; exports.isEmptyObject = isEmptyObject; /** * Check if a value is an empty array */ const isEmptyArray = (value) => Array.isArray(value) && value.length === 0; exports.isEmptyArray = isEmptyArray; /** * Checks if a value is not empty (null, undefined, or empty string), not an empty object, and not an empty array */ const hasValue = (value) => !(0, exports.isEmpty)(value) && !(0, exports.isEmptyObject)(value) && !(0, exports.isEmptyArray)(value); exports.hasValue = hasValue; /** * Returns a pluralized string based on the value * @example getPlural(1, 'item') => '1 item' * @example getPlural(4, 'item') => '4 items' * @example getPlural(2, 'person', 'people') => '2 people' * @example getPlural(0, 'item') => '0 items' */ const getPlural = (value, singular, plural = null) => value === 1 ? `${value} ${singular}` : plural ? `${value} ${plural}` : `${value} ${singular}s`; exports.getPlural = getPlural; /** * Escapes special characters in a search term to prevent them from being interpreted as regex operators */ const sanitizeRegexString = (input) => input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); exports.sanitizeRegexString = sanitizeRegexString; /** * Converts a value to a plain object by serializing to and from JSON */ const toPlainObject = (value) => JSON.parse(JSON.stringify(value)); exports.toPlainObject = toPlainObject; /** * Converts a Booleanish value (boolean | 'true' | '1' | 'false' | '0') to a boolean */ const booleanize = (value) => ([true, 'true', '1'].includes(value) ? true : false); exports.booleanize = booleanize;