UNPKG

jsm-utilities

Version:
256 lines (255 loc) 10.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.unflattenObjectArray = exports.extractPartialObject = exports.flattenObject = exports.flattenObjectKeys = exports.transformObjectToString = void 0; exports.deepSanitizeObjectValues = deepSanitizeObjectValues; exports.unflattenObject = unflattenObject; exports.deletePropertyRecursively = deletePropertyRecursively; exports.deepMergeUnlessNull = deepMergeUnlessNull; exports.replaceNullAndUndefined = replaceNullAndUndefined; exports.mergeAddresses = mergeAddresses; /** * @generator Jsm * @author dr. Salmi <reevosolutions@gmail.com> * @since 24-02-2024 20:47:22 */ const moment_1 = __importDefault(require("moment")); const lodash_1 = require("lodash"); const transformObjectToString = (obj) => { if (obj === undefined) { return 'undefined'; } if (obj === null) { return 'null'; } else if (typeof obj === 'string') { return obj; } else if (Array.isArray(obj)) { return obj.map(v => (0, exports.transformObjectToString)(v)).join(', '); } else if (typeof obj === 'object') { if (Object.prototype.hasOwnProperty.call(obj, 'start') && Object.prototype.hasOwnProperty.call(obj, 'end')) { return `${(0, moment_1.default)(obj.start).format('DD-MM-YYYY')} - ${(0, moment_1.default)(obj.end).format('DD-MM-YYYY')}`; } else { return (0, exports.transformObjectToString)(Object.keys(obj).map(k => `${k}: ${(0, exports.transformObjectToString)(obj[k])}`)); } } return obj; }; exports.transformObjectToString = transformObjectToString; function deepSanitizeObjectValues(value) { // Check if the value is an object or array, and recursively process each property or element if (value !== null && typeof value === 'object') { Object.keys(value).forEach(key => { value[key] = deepSanitizeObjectValues(value[key]); }); return value; } // Convert 'null' strings to null values if (value === 'null') { return null; } // Convert strings that are numeric to numbers if (typeof value === 'string' && !isNaN(Number(value)) && value.trim() !== '') { return Number(value); } // Return the value unchanged if none of the above conditions apply return value; } /** * @since 11-12-2023 15:41:03 */ const flattenObjectKeys = (obj, prefix = '') => Object.keys(obj).reduce((acc, k) => { const pre = prefix.length ? prefix + '.' : ''; if (typeof obj[k] === 'object' && obj[k]) { if (obj[k] instanceof Array) for (let idx = 0; idx < obj[k].length; idx++) { if (typeof obj[k][idx] === 'object' && obj[k][idx]) acc.push(...(0, exports.flattenObjectKeys)(obj[k][idx], pre + k)); } else acc.push(...(0, exports.flattenObjectKeys)(obj[k], pre + k)); } else { if (!(0, lodash_1.isNumber)(k)) acc.push(pre + k); } return acc; }, []); exports.flattenObjectKeys = flattenObjectKeys; /** * @since 11-12-2023 15:41:10 */ const flattenObject = (obj, prefix = '') => Object.keys(obj).reduce((acc, k) => { const pre = prefix.length ? prefix + '.' : ''; if (typeof obj[k] === 'object' && obj[k]) Object.assign(acc, (0, exports.flattenObject)(obj[k], pre + k)); else acc[pre + k] = obj[k]; return acc; }, {}); exports.flattenObject = flattenObject; /** * Unflattens a flat object with dot notation keys into a nested object. * Handles arrays with indices (e.g., "users[0].name"). * @param {Record<string, any>} flatObj - The flat object to unflatten. * @returns {Record<string, any>} - The unflattened nested object. */ function unflattenObject(flatObj) { if (!flatObj || typeof flatObj !== 'object' || Array.isArray(flatObj)) { return flatObj; } const result = {}; for (const key in flatObj) { if (Object.prototype.hasOwnProperty.call(flatObj, key)) { const parts = key.split('.'); let current = result; for (let i = 0; i < parts.length; i++) { const part = parts[i]; const isLast = i === parts.length - 1; // Handle array indices (e.g., "users[0].name") const arrayMatch = part.match(/^(\w+)\[(\d+)\]$/); if (arrayMatch) { const arrayName = arrayMatch[1]; const index = parseInt(arrayMatch[2]); current[arrayName] = current[arrayName] || []; current[arrayName][index] = current[arrayName][index] || (isLast ? flatObj[key] : {}); current = current[arrayName][index]; } else { if (isLast) { current[part] = flatObj[key]; } else { current[part] = current[part] || {}; current = current[part]; } } } } } return result; } const extractPartialObject = (obj, properties) => { const subObject = {}; properties.forEach(property => { if (Object.prototype.hasOwnProperty.call(obj, property)) { subObject[property] = obj[property]; } }); return subObject; }; exports.extractPartialObject = extractPartialObject; function deletePropertyRecursively(obj, property) { for (const key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { if (key === property) { delete obj[key]; } else if (typeof obj[key] === "object" && obj[key] !== null) { deletePropertyRecursively(obj[key], property); } } } } /** * Update : added * @author dr. Salmi <reevosolutions@gmail.com> * @since 18-07-2024 21:24:07 */ const unflattenObjectArray = (items) => { const itemMap = new Map(); // Initialize each item with a children array and map them by _id items.forEach((item) => { item.children = []; itemMap.set(item._id, Object.assign(Object.assign({}, item), { children: [] })); }); // Link children to their parent, and find root items const roots = []; items.forEach((item) => { if (item.parent) { const parentItem = itemMap.get(item.parent); parentItem === null || parentItem === void 0 ? void 0 : parentItem.children.push(itemMap.get(item._id)); } else { roots.push(itemMap.get(item._id)); } }); return roots; }; exports.unflattenObjectArray = unflattenObjectArray; /** * Merges two objects deeply, excluding properties with null or undefined values. * @param x - The first object to merge. * @param y - The second object to merge. * @returns The merged object. */ function deepMergeUnlessNull(x, y) { const result = Object.assign({}, x); for (const key in y) { if (Object.prototype.hasOwnProperty.call(y, key)) { if (y[key] === null || y[key] === undefined) { continue; } else if (typeof y[key] === "object" && y[key] !== null && !Array.isArray(y[key])) { if (typeof result[key] === "object" && result[key] !== null) { result[key] = deepMergeUnlessNull(result[key], y[key]); } else { result[key] = deepMergeUnlessNull({}, y[key]); } } else { result[key] = y[key]; } } } return result; } /** * Replaces null and undefined properties in the first object with values from the second object. * @param x - The target object to modify. * @param y - The source object with new values. * @returns The modified target object. */ function replaceNullAndUndefined(x, y) { const isObject = (object) => object && typeof object === "object"; x = Object.assign({}, (x || {})); for (const key in y) { if (isObject(y[key]) && y[key] !== null && !Array.isArray(y[key])) { if (!isObject(x[key])) { x[key] = {}; } x[key] = replaceNullAndUndefined(x[key], y[key]); } else { if (x[key] === undefined || x[key] === null) { x[key] = y[key]; } } } return x; } /** * Merge address data */ function mergeAddresses(address1, address2) { if (!address1 && !address2) return undefined; return { country_code: (address1 === null || address1 === void 0 ? void 0 : address1.country_code) || (address2 === null || address2 === void 0 ? void 0 : address2.country_code) || '', country_name: (address1 === null || address1 === void 0 ? void 0 : address1.country_name) || (address2 === null || address2 === void 0 ? void 0 : address2.country_name) || '', state_code: (address1 === null || address1 === void 0 ? void 0 : address1.state_code) || (address2 === null || address2 === void 0 ? void 0 : address2.state_code) || '', state_name: (address1 === null || address1 === void 0 ? void 0 : address1.state_name) || (address2 === null || address2 === void 0 ? void 0 : address2.state_name) || '', city_code: (address1 === null || address1 === void 0 ? void 0 : address1.city_code) || (address2 === null || address2 === void 0 ? void 0 : address2.city_code) || '', city_name: (address1 === null || address1 === void 0 ? void 0 : address1.city_name) || (address2 === null || address2 === void 0 ? void 0 : address2.city_name) || '', street_address: (address1 === null || address1 === void 0 ? void 0 : address1.street_address) || (address2 === null || address2 === void 0 ? void 0 : address2.street_address), }; }