js-upsert
Version:
`js-upsert` is a lightweight JavaScript library designed to simplify updating deeply nested properties within objects. It provides an intuitive and efficient way to manage complex object structures, ensuring non-destructive updates. This makes `js-upsert`
1 lines • 11.1 kB
Source Map (JSON)
{"version":3,"file":"js-upsert.umd.cjs","sources":["../src/set.ts","../src/deepUpdater.ts","../src/keyfinder.ts","../src/upsert.ts"],"sourcesContent":["import { Ignore, SetValueSignature } from \"./types/set.type\";\r\n\r\nfunction getArrayFromStringIndex(str: string) {\r\n // Remove all brackets and quotes, then split by period\r\n return str.replace(/[\\[\\]'\"]/g, \"\").split(\".\");\r\n}\r\n\r\n/**\r\n * Sets a value with a specific index.\r\n * This function internally generates a unique hook, but the hook details are abstracted away.\r\n *\r\n * @param value - The value to set.\r\n * @param index - The index which may specify where to apply the update.\r\n * @returns An object representing the result of the set operation.\r\n */\r\n\r\nexport const set = <T>(\r\n value: T | ((prevValue: T) => T),\r\n index?: null | (string | number)[] | string\r\n): SetValueSignature<T> => {\r\n let r = Math.floor(Math.random() * 1000000);\r\n\r\n let indexParsed =\r\n typeof index == \"string\" ? getArrayFromStringIndex(index) : index;\r\n return {\r\n [\"$$@@@@__upsert_hook_\" + r]: {\r\n value: value as T,\r\n index: indexParsed ?? null,\r\n isFunction: typeof value == \"function\",\r\n },\r\n };\r\n};\r\n\r\nset.at = (...param: any[]) => {\r\n const index = param as any[];\r\n\r\n const final_value = index.pop();\r\n\r\n return set(final_value, index) as unknown as Ignore;\r\n};\r\n\r\nexport default {\r\n set,\r\n};\r\n","export default function deepUpdater(\r\n data: any,\r\n index: any,\r\n value: any,\r\n isFunction: any = false,\r\n config: any,\r\n drilled: any = []\r\n) {\r\n const orignal_index = index;\r\n\r\n if (index.length <= 1) {\r\n /* \r\n \r\n IF INDEX IS PRESENT TO SET:-\r\n\r\n ex:- \r\n INDEX: [1]\r\n DATA: {}\r\n\r\n THEN: DATA = {1: VALUE}\r\n\r\n */\r\n\r\n if (index.length > 0) {\r\n try {\r\n data[index[0]] = isFunction ? value(data[index[0] ?? index]) : value;\r\n\r\n return data;\r\n } catch (e) {\r\n console.error(e);\r\n\r\n throw `Setting Failed at index ${index[0]} of [${drilled.join(\r\n \" => \"\r\n )}] due to the type ${typeof data}, Only array or object is assignable`;\r\n }\r\n }\r\n\r\n if (data === null || typeof data != \"object\") {\r\n throw Error(\r\n \"Initial value is not a object, ERROR: INITITAL_VALUE_PARSE_FAILED\"\r\n );\r\n }\r\n\r\n let _NEW_VALUE = isFunction ? value(data) : value;\r\n\r\n if (config.returnType == \"array\") {\r\n data.push(_NEW_VALUE);\r\n\r\n return data;\r\n }\r\n\r\n if (typeof _NEW_VALUE != \"object\")\r\n throw `Object or array can be setted only as a default value. Type of value is ${typeof _NEW_VALUE}.`;\r\n\r\n for (const key of Object.keys(_NEW_VALUE)) {\r\n data[key] = _NEW_VALUE[key];\r\n }\r\n\r\n return data;\r\n }\r\n\r\n let NEW_VALUE = (data ?? [])[index[0]] ?? false;\r\n\r\n if (!NEW_VALUE) {\r\n let N = createObject(index, value, isFunction);\r\n\r\n try {\r\n data[index[0]] = N;\r\n } catch (e) {\r\n throw `Setting Failed at index ${index[0]} of [${drilled.join(\r\n \" => \"\r\n )}] due to the type ${typeof data}, Only array or object is assignable`;\r\n }\r\n\r\n return data;\r\n }\r\n\r\n index.shift();\r\n return deepUpdater(NEW_VALUE, index, value, isFunction, config, [\r\n ...drilled,\r\n orignal_index[0],\r\n ]);\r\n}\r\n\r\nfunction createObject(index: any, value: any, isFunction: any = false) {\r\n let CLONED_INDEX = [...index];\r\n let NEW_OBJ;\r\n\r\n if (CLONED_INDEX.length == 1) NEW_OBJ = isFunction ? value(null) : value;\r\n else {\r\n NEW_OBJ = {} as any;\r\n CLONED_INDEX.shift();\r\n NEW_OBJ[CLONED_INDEX[0]] = createObject(CLONED_INDEX, value, isFunction);\r\n }\r\n\r\n return NEW_OBJ;\r\n}\r\n","export function keyFinder(\r\n { obj }: any,\r\n targetKey: any,\r\n currentKeys = [] as any,\r\n inner = false\r\n): any {\r\n let result = [] as any;\r\n\r\n // ITERATING ALL KEYS IN OBJECT\r\n\r\n for (let key in obj) {\r\n let ThisKeyValue = obj[key];\r\n if (key.includes(targetKey) && (ThisKeyValue ?? false)) {\r\n result.push({\r\n index: [...currentKeys, ...(ThisKeyValue.index ?? [])],\r\n value: ThisKeyValue.value,\r\n isFunction: ThisKeyValue.isFunction,\r\n });\r\n } else if (typeof ThisKeyValue === \"object\") {\r\n const nestedResult = keyFinder(\r\n { obj: ThisKeyValue },\r\n targetKey,\r\n [...currentKeys, key],\r\n true\r\n );\r\n\r\n result = result.concat(nestedResult.obj);\r\n }\r\n }\r\n\r\n return inner\r\n ? { obj: result }\r\n : {\r\n result,\r\n };\r\n}\r\n","import deepUpdater from \"./deepUpdater\";\r\nimport { keyFinder } from \"./keyfinder\";\r\nimport { typeParam_upsert, UpsertType } from \"./types/upsert.type\";\r\n\r\ntype configType = {\r\n returnType?: \"object\" | \"array\";\r\n};\r\nexport function upserter<HayStackType>(\r\n haystack: HayStackType,\r\n needle: any,\r\n config: configType = { returnType: \"object\" }\r\n) {\r\n let { result } = keyFinder({ obj: needle }, \"$$@@@@__upsert_hook\");\r\n\r\n for (let key = 0; key < result.length; key++) {\r\n let ThisKey = result[key];\r\n\r\n deepUpdater(\r\n haystack,\r\n ThisKey.index,\r\n ThisKey.value,\r\n ThisKey.isFunction,\r\n config\r\n );\r\n }\r\n}\r\n\r\nexport function upsert<HayStackType>(\r\n haystack: HayStackType,\r\n ...needles: typeParam_upsert<HayStackType>[]\r\n): UpsertType<HayStackType> {\r\n let config = {\r\n returnType: \"object\",\r\n } as configType;\r\n const haystackArrayValidation = Array.isArray(haystack);\r\n\r\n if (haystackArrayValidation) config.returnType = \"array\"; // IF INITAL VALUE IS ARRAY THEN RETURN IN ARRAY\r\n\r\n for (let needle of needles) {\r\n upserter(haystack, needle, config);\r\n }\r\n\r\n try {\r\n return new Proxy(haystack as any, {\r\n get(target, prop, receiver) {\r\n target = haystackArrayValidation ? [...haystack] : { ...haystack }; // set updated data\r\n\r\n // If at is given as props\r\n\r\n if (prop === \"get\") {\r\n return () => {\r\n return receiver;\r\n };\r\n }\r\n if (prop === \"at\") {\r\n return (...keys: string[]) => {\r\n if (keys.length <= 1) {\r\n throw `keys.length is less than 2, need atleast 2 values to differentiate index and value`;\r\n }\r\n const value_provided = keys[keys.length - 1];\r\n\r\n const index_provided = keys;\r\n index_provided.pop();\r\n\r\n deepUpdater(\r\n haystack,\r\n index_provided,\r\n value_provided,\r\n typeof value_provided == \"function\",\r\n config\r\n );\r\n return receiver; // default behavior\r\n };\r\n }\r\n return Reflect.get(target, prop, receiver); // default behavior\r\n },\r\n }) as UpsertType<HayStackType>;\r\n } catch (e) {\r\n throw Error(\r\n `Cannot return value as returnType '${config.returnType}'. Please try '${\r\n config.returnType == \"array\" ? \"OBJECT\" : \"ARRAY\"\r\n }' returnType, ERROR: RETURN_ERROR.`\r\n );\r\n }\r\n}\r\n\r\nexport default {\r\n upsert,\r\n};\r\n"],"names":["getArrayFromStringIndex","str","set","value","index","indexParsed","param","final_value","deepUpdater","data","isFunction","config","drilled","orignal_index","e","_NEW_VALUE","key","NEW_VALUE","N","createObject","CLONED_INDEX","NEW_OBJ","keyFinder","obj","targetKey","currentKeys","inner","result","ThisKeyValue","nestedResult","upserter","haystack","needle","ThisKey","upsert","needles","haystackArrayValidation","target","prop","receiver","keys","value_provided","index_provided"],"mappings":"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"}