jsm-utilities
Version:
A utilities library.
256 lines (255 loc) • 10.1 kB
JavaScript
;
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),
};
}