ngs-json-utils
Version:
A set of Angular utilities for deep cloning, serialization, and JSON manipulation.
1 lines • 25.9 kB
Source Map (JSON)
{"version":3,"file":"ngs-json-utils.mjs","sources":["../../../projects/ngs-json-utils/src/lib/ngs-json-utils.service.ts","../../../projects/ngs-json-utils/src/public-api.ts","../../../projects/ngs-json-utils/src/ngs-json-utils.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n/**\n * A utility service for performing common JSON-related operations safely and effectively.\n */\n@Injectable({\n providedIn: 'root',\n})\nexport class NgsJsonUtilsService {\n /**\n * Safely converts a JavaScript value to a JSON string.\n * If an error occurs during serialization, returns `undefined` instead of throwing an error.\n *\n * @param data - The value to serialize into a JSON string.\n * @param replacer - Optional function to filter or transform properties.\n * @param space - Optional number of spaces for formatting the output JSON.\n * @returns A JSON string representation of the data, or `undefined` if serialization fails.\n */\n stringify(\n data: unknown,\n replacer?: (key: string, value: any) => any,\n space?: number,\n ): string | undefined {\n try {\n return JSON.stringify(data, replacer, space);\n } catch (error) {\n console.error('Error during JSON.stringify:', error);\n return undefined;\n }\n }\n\n /**\n * Safely parses a JSON string into a JavaScript object or value.\n * If parsing fails, returns the provided default value (or `null` if not provided).\n *\n * @param json - The JSON string to parse.\n * @param defaultValue - A fallback value to return if parsing fails (defaults to `null`).\n * @returns The parsed object/value, or the default value if parsing fails.\n */\n parse<T>(json: string, defaultValue: T | null = null): T | null {\n try {\n return JSON.parse(json) as T;\n } catch (error) {\n console.error('Error during JSON.parse:', error);\n return defaultValue;\n }\n }\n\n /**\n * Creates a deep copy of a given value using JSON serialization.\n * It relies on the JSON.stringify and JSON.parse methods to safely clone an object.\n * This approach doesn't handle cyclic references and non-serializable properties (like functions).\n *\n * @param data - The value to create a deep copy of.\n * @returns A deep copy of the input value, or undefined if cloning fails.\n */\n deepCopy<T>(data: T): T | undefined {\n try {\n // Serializing and immediately deserializing the object to create a deep copy\n const jsonString = JSON.stringify(data);\n return JSON.parse(jsonString) as T;\n } catch (error) {\n console.error('Error during deep copy (JSON serialization)', error);\n return undefined;\n }\n }\n\n /**\n * Safely validates if a given string is in valid JSON format.\n * If the string is invalid, it logs the error and returns `false`.\n *\n * @param jsonString - The string to validate.\n * @returns `true` if the string is valid JSON; otherwise, `false`.\n */\n isValidJSON(jsonString: string): boolean {\n if (!jsonString) {\n console.error('Invalid JSON string: empty or undefined input');\n return false;\n }\n\n try {\n JSON.parse(jsonString);\n return true;\n } catch (error) {\n console.error('Invalid JSON string:', error);\n return false;\n }\n }\n\n /**\n * Compares two JSON-compatible values for equality using serialization.\n * Logs an error to the console if serialization fails.\n *\n * @param obj1 - The first JSON-compatible value to compare.\n * @param obj2 - The second JSON-compatible value to compare.\n * @returns `true` if the two values are equal, `false` otherwise.\n */\n equalJSON<T>(obj1: T, obj2: T): boolean {\n try {\n return JSON.stringify(obj1) === JSON.stringify(obj2);\n } catch (error) {\n console.error('Failed to serialize objects for comparison', {\n obj1,\n obj2,\n error,\n });\n return false;\n }\n }\n\n /**\n * Safely compares two values for deep equality, adhering strictly to JSON-compatible types.\n * It does not handle cyclic references or non-JSON-serializable objects.\n *\n * @param obj1 - The first value to compare.\n * @param obj2 - The second value to compare.\n * @returns `true` if the two values are deeply equal, `false` otherwise.\n */\n deepEqualJSON<T>(obj1: T, obj2: T): boolean {\n const isObject = (val: unknown): val is Record<string, unknown> =>\n typeof val === 'object' && val !== null;\n\n const deepEqualHelper = (a: unknown, b: unknown): boolean => {\n if (a === b) return true;\n\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false;\n return a.every((item, index) => deepEqualHelper(item, b[index]));\n }\n\n if (isObject(a) && isObject(b)) {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n\n if (keysA.length !== keysB.length) return false;\n\n return keysA.every(\n (key) => keysB.includes(key) && deepEqualHelper(a[key], b[key]),\n );\n }\n\n return false;\n };\n\n return deepEqualHelper(obj1, obj2);\n }\n\n /**\n * Safely performs a deep merge of two objects using JSON serialization.\n * Handles cyclic references by catching errors gracefully.\n * Source properties will overwrite corresponding target properties.\n *\n * @param target - The target object to be updated.\n * @param source - The source object providing updates.\n * @returns A new object with merged properties, or the original target if an error occurs.\n */\n deepMerge<T>(target: T, source: Partial<T>): T {\n try {\n const targetClone = JSON.stringify(target);\n const sourceClone = JSON.stringify(source);\n\n const merged = JSON.parse(\n `{${targetClone.slice(1, -1)},${sourceClone.slice(1, -1)}}`,\n );\n\n return merged as T;\n } catch (error) {\n console.error('Error during safe deep merge:', error);\n return target;\n }\n }\n\n /**\n * Safely filters an object's properties, keeping only those specified in the allowed keys.\n * Handles cyclic references and non-serializable objects gracefully.\n * Logs errors if any occur.\n *\n * @param obj - The object to filter.\n * @param allowedKeys - An array of keys to retain in the filtered object.\n * @returns A new object containing only the allowed keys, or an empty object if an error occurs.\n */\n filterKeys<T extends object, K extends keyof T>(\n obj: T,\n allowedKeys: K[],\n ): Partial<Pick<T, K>> {\n try {\n const serializedObj = JSON.stringify(obj, (key, value) => {\n if (typeof value === 'function') {\n return undefined;\n }\n return value;\n });\n const parsedObj = JSON.parse(serializedObj);\n\n return allowedKeys.reduce(\n (acc, key) => {\n if (key in parsedObj) {\n acc[key] = parsedObj[key];\n }\n return acc;\n },\n {} as Partial<Pick<T, K>>,\n );\n } catch (error) {\n console.error('Error during filtering object:', error);\n return {} as Partial<Pick<T, K>>;\n }\n }\n\n /**\n * Safely recursively updates the target object with values from the updates object.\n * Handles serialization of objects and logs errors if any occur (e.g., with non-serializable data).\n * If an error occurs during the update, the target remains unchanged.\n *\n * @param target - The object to be updated.\n * @param updates - The object containing updates to apply.\n * @returns A new object with updated values, or the original target if an error occurs.\n */\n deepUpdate<T>(target: T, updates: Partial<T>): T {\n try {\n const serializedUpdates = JSON.stringify(updates, (key, value) => {\n if (typeof value === 'function' || value === undefined) {\n return undefined;\n }\n return value;\n });\n const parsedUpdates = JSON.parse(serializedUpdates);\n\n return Object.keys(parsedUpdates).reduce(\n (acc, key) => {\n const value = parsedUpdates[key as keyof T];\n if (value && typeof value === 'object' && !Array.isArray(value)) {\n acc[key as keyof T] = this.deepUpdate(\n acc[key as keyof T] || ({} as T),\n value,\n ) as any;\n } else {\n acc[key as keyof T] = value as any;\n }\n return acc;\n },\n { ...target },\n );\n } catch (error) {\n console.error('Error during deep update:', error);\n return target;\n }\n }\n\n /**\n * Searches for a value in a nested object by its key.\n *\n * @param obj - The object to search within.\n * @param key - The key to look for.\n * @returns The value associated with the key, or `undefined` if not found.\n */\n findValueByKey<T extends object, K extends keyof T>(\n obj: T,\n key: K,\n ): T[K] | undefined {\n if (key in obj) {\n return obj[key];\n }\n\n for (const k in obj) {\n if (typeof obj[k] === 'object' && obj[k] !== null) {\n const result = this.findValueByKey(obj[k] as T, key);\n if (result !== undefined) {\n return result;\n }\n }\n }\n\n return undefined;\n }\n\n /**\n * Safely searches for a value in a nested object by its key.\n * If an error occurs during the search, returns `undefined` instead of throwing.\n *\n * @param obj - The object to search within.\n * @param key - The key to look for.\n * @returns The value associated with the key, or `undefined` if not found or an error occurs.\n */\n safeFindValueByKey<T extends object, K extends keyof T>(\n obj: T,\n key: K,\n ): T[K] | undefined {\n try {\n if (key in obj) {\n return obj[key];\n }\n\n for (const k in obj) {\n if (typeof obj[k] === 'object' && obj[k] !== null) {\n const result = this.safeFindValueByKey(obj[k] as T, key);\n if (result !== undefined) {\n return result;\n }\n }\n }\n\n return undefined;\n } catch (error) {\n console.error('Error during object search:', error);\n return undefined;\n }\n }\n\n /**\n * Safely removes all `undefined` values from an object.\n * If an error occurs during the cleaning process, returns the original object.\n *\n * @param obj - The object to clean.\n * @returns A new object without `undefined` values, or the original object if an error occurs.\n */\n removeUndefined<T>(obj: T): T {\n try {\n return JSON.parse(\n JSON.stringify(obj, (_, value) =>\n value === undefined ? undefined : value,\n ),\n );\n } catch (error) {\n console.error('Error during object cleaning:', error);\n return obj;\n }\n }\n\n /**\n * Safely converts a Map object to a plain JSON object.\n * If an error occurs during the conversion, returns an empty object.\n *\n * @param map - The Map to convert.\n * @returns A JSON object with the same key-value pairs as the Map, or an empty object if an error occurs.\n */\n mapToJSON<K, V>(map: Map<K, V>): Record<string, V> {\n try {\n const obj: Record<string, V> = {};\n map.forEach((value, key) => {\n obj[String(key)] = value;\n });\n return obj;\n } catch (error) {\n console.error('Error during Map to JSON conversion:', error);\n return {};\n }\n }\n\n /**\n * Safely converts a plain JSON object to a Map object.\n * If an error occurs during the conversion, returns an empty Map.\n *\n * @param json - The JSON object to convert.\n * @returns A Map containing the key-value pairs from the JSON object, or an empty Map if an error occurs.\n */\n jsonToMap<V>(json: Record<string, V>): Map<string, V> {\n try {\n if (json && typeof json === 'object' && !Array.isArray(json)) {\n return new Map(Object.entries(json));\n }\n return new Map();\n } catch (error) {\n console.error('Error during JSON to Map conversion:', error);\n return new Map();\n }\n }\n\n /**\n * Safely merges multiple arrays of objects, keeping only unique objects based on a specified key.\n * If invalid input is provided (non-array or non-object values), returns an empty array.\n *\n * @param arrays - An array of arrays of objects to merge.\n * @param key - The key used to determine uniqueness (objects with the same key value are considered duplicates).\n * @returns An array of unique objects based on the specified key, or an empty array if the input is invalid.\n */\n mergeUniqueByKey<T extends Record<string, any>>(\n arrays: T[],\n key: string,\n ): T[] {\n // Проверяем, что входные данные являются массивом и ключ - строкой\n if (!Array.isArray(arrays) || typeof key !== 'string') return [];\n\n return arrays.flat().reduce((acc: T[], obj: T) => {\n // Проверяем, что каждый объект содержит заданный ключ\n if (\n obj &&\n obj.hasOwnProperty(key) &&\n !acc.some((item) => item[key] === obj[key])\n ) {\n acc.push(obj);\n }\n return acc;\n }, []);\n }\n\n /**\n * Safely removes all keys from an object that have null or empty values.\n * If the input is not an object, returns an empty object.\n *\n * @param obj - The object from which to remove empty values.\n * @returns A new object with only non-empty values, or an empty object if the input is invalid.\n */\n removeEmptyValues(obj: any): any {\n if (typeof obj !== 'object' || obj === null) return {};\n\n return Object.fromEntries(\n Object.entries(obj).filter(([_, v]) => v != null && v !== ''),\n );\n }\n\n /**\n * Safely retrieves the value from an object based on a specified path (array of keys).\n * Returns undefined if the object or the path is invalid.\n *\n * @param obj - The object to retrieve the value from.\n * @param path - An array of keys representing the path to the value.\n * @returns The value at the specified path, or undefined if the object or path is invalid.\n */\n getByPath(obj: any, path: string[]): any {\n if (typeof obj !== 'object' || obj === null || !Array.isArray(path))\n return undefined;\n\n return path.reduce(\n (acc, key) => (acc && acc[key] !== undefined ? acc[key] : undefined),\n obj,\n );\n }\n\n /**\n * Safely extracts unique values from an array of objects based on a specific key.\n * If the input is invalid (non-array or non-object values), returns an empty array.\n *\n * @param arr - An array of objects from which to extract unique values.\n * @param key - The key used to extract unique values.\n * @returns An array of unique values based on the specified key, or an empty array if the input is invalid.\n */\n uniqueValuesByKey<T extends Record<string, unknown>>(\n arr: T[],\n key: string,\n ): unknown[] {\n if (!Array.isArray(arr) || typeof key !== 'string') return [];\n\n return Array.from(\n new Set(arr.map((item) => (item && key in item ? item[key] : undefined))),\n );\n }\n\n /**\n * Safely flattens a nested object into a single-level object, using dot notation for nested keys.\n * If the input is invalid (non-object or null), returns an empty object.\n *\n * @param obj - The object to flatten.\n * @param prefix - The prefix to prepend to each key (used for nested objects).\n * @returns A flattened object with dot notation keys, or an empty object if the input is invalid.\n */\n flattenObject<T extends Record<string, unknown>>(\n obj: T,\n prefix: string = '',\n ): Record<string, unknown> {\n if (typeof obj !== 'object' || obj === null) return {};\n\n return Object.entries(obj).reduce(\n (acc: Record<string, unknown>, [key, value]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n if (typeof value === 'object' && value !== null) {\n Object.assign(\n acc,\n this.flattenObject(value as Record<string, unknown>, newKey),\n );\n } else {\n acc[newKey] = value;\n }\n return acc;\n },\n {},\n );\n }\n}\n","/*\n * Public API Surface of ngs-json-utils\n */\n\nexport * from './lib/ngs-json-utils.service';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}