UNPKG

nhb-toolbox

Version:

A versatile collection of smart, efficient, and reusable utility functions, classes and types for everyday development needs.

166 lines (165 loc) 5.64 kB
import { isDateLike } from '../date/guards.js'; import { isFileOrBlob } from '../form/guards.js'; import { isEmptyObject, isNotEmptyObject, isObject } from '../guards/non-primitives.js'; import { isDeepEqual } from '../utils/index.js'; import { parseObjectValues } from './sanitize.js'; export const mergeObjects = (...objects) => { const map = new Map(); for (const obj of objects) { for (const key in obj) { const existingValue = map.get(key); if (isNotEmptyObject(obj[key])) { if (isNotEmptyObject(existingValue)) { if (isDateLike(obj[key]) || isFileOrBlob(obj[key])) { map.set(key, obj[key]); } else { map.set(key, mergeObjects(existingValue, obj[key])); } } else { map.set(key, obj[key]); } } else { map.set(key, obj[key]); } } } const result = {}; map?.forEach((value, key) => { result[key] = value; }); return result; }; export const mergeAndFlattenObjects = (...objects) => { const map = new Map(); const _flattenObject = (obj, parentKey = '') => { for (const key in obj) { const newKey = parentKey ? `${String(parentKey)}.${key}` : key; if (isNotEmptyObject(obj[key])) { if (isDateLike(obj[key]) || isFileOrBlob(obj[key])) { map.set(newKey, obj[key]); } else { _flattenObject(obj[key], newKey); } } else { map.set(newKey, obj[key]); } } }; for (const obj of objects) { _flattenObject(obj); } const result = {}; map?.forEach((value, key) => { result[key] = value; }); return result; }; export const flattenObjectKeyValue = (object) => { const flattened = {}; for (const [key, value] of Object.entries(object)) { if (isNotEmptyObject(value)) { const nestedFlattened = flattenObjectKeyValue(value); if (isDateLike(value) || isFileOrBlob(value)) { flattened[key] = value; } else { Object.assign(flattened, nestedFlattened); } } else { flattened[key] = value; } } return flattened; }; export const flattenObjectDotNotation = (object) => { const _flattenObject = (source, prefix = '') => { const flattened = {}; for (const [key, value] of Object.entries(source)) { const newKey = prefix ? `${String(prefix)}.${key}` : key; if (isNotEmptyObject(value) || isFileOrBlob(value)) { if (isDateLike(value)) { flattened[newKey] = value; } else { Object.assign(flattened, _flattenObject(value, newKey)); } } else { flattened[newKey] = value; } } return flattened; }; return _flattenObject(object); }; export const extractUpdatedFields = (baseObject, updatedObject) => { const updatedFields = {}; for (const key in updatedObject) { if (key in baseObject && !isDeepEqual(updatedObject[key], baseObject[key])) { if (updatedObject[key] && isNotEmptyObject(updatedObject[key])) { updatedFields[key] = extractUpdatedFields(baseObject[key], updatedObject[key]); if (updatedFields[key] && isEmptyObject(updatedFields[key])) { delete updatedFields[key]; } } else { updatedFields[key] = updatedObject[key]; } } } return updatedFields; }; export const extractNewFields = (baseObject, updatedObject) => { const newFields = {}; for (const key in updatedObject) { if (!(key in baseObject)) { newFields[key] = updatedObject[key]; } else if (isNotEmptyObject(updatedObject[key]) && isNotEmptyObject(baseObject[key])) { const nestedNewFields = extractNewFields(baseObject[key], updatedObject[key]); if (isNotEmptyObject(nestedNewFields)) { newFields[key] = nestedNewFields; } } } return newFields; }; export const extractUpdatedAndNewFields = (baseObject, updatedObject) => { const updatedFields = {}; const newFields = {}; for (const key in updatedObject) { if (!(key in baseObject)) { newFields[key] = updatedObject[key]; } else if (!isDeepEqual(updatedObject[key], baseObject[key])) { if (updatedObject[key] && isNotEmptyObject(updatedObject[key])) { updatedFields[key] = extractUpdatedAndNewFields(baseObject[key], updatedObject[key]); if (updatedFields[key] && isEmptyObject(updatedFields[key])) { delete updatedFields[key]; } } else { updatedFields[key] = updatedObject[key]; } } } return { ...updatedFields, ...newFields }; }; export const parseJsonToObject = (value, parsePrimitives = true) => { try { const data = JSON.parse(value); if (!isObject(data)) { return {}; } return parsePrimitives ? parseObjectValues(data) : data; } catch { return {}; } };