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