{"_id":"@a-2-c-2-anpm/rerum-iste-ducimus","name":"@a-2-c-2-anpm/rerum-iste-ducimus","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@a-2-c-2-anpm/rerum-iste-ducimus","version":"1.0.0","description":"A powerful JSON path processor with no third-party dependencies. Allows you to traverse JSON object trees with a simple dot-delimited path format e.g. \"obj.name\"","main":"index.js","scripts":{},"author":{"name":"a-2-c-2-a"},"license":"MIT","dependencies":{"@a-2-c-2-anpm/alias-ducimus-sit":"^1.0.0","@a-2-c-2-anpm/atque-nemo-accusantium":"^1.0.0","@a-2-c-2-anpm/distinctio-quibusdam-culpa":"^1.0.0","@a-2-c-2-anpm/eligendi-praesentium-hic":"^1.0.0","@a-2-c-2-anpm/enim-amet-voluptatem":"^1.0.0","@a-2-c-2-anpm/error-dolorem-a":"^1.0.0","@a-2-c-2-anpm/excepturi-natus-facere":"^1.0.0","@a-2-c-2-anpm/expedita-recusandae-aut":"^1.0.0","@a-2-c-2-anpm/fugit-impedit-quae":"^1.0.0","@a-2-c-2-anpm/hic-maiores-accusantium":"^1.0.0","@a-2-c-2-anpm/laborum-exercitationem-quis":"^1.0.0","@a-2-c-2-anpm/laudantium-dolor-perspiciatis":"^1.0.0","@a-2-c-2-anpm/maiores-quis-dignissimos":"^1.0.0","@a-2-c-2-anpm/nam-eaque-occaecati":"^1.0.0","@a-2-c-2-anpm/neque-culpa-culpa":"^1.0.0","@a-2-c-2-anpm/neque-iste-eum":"^1.0.0","@a-2-c-2-anpm/nobis-similique-magni":"^1.0.0","@a-2-c-2-anpm/officia-tempore-ipsa":"^1.0.0","@a-2-c-2-anpm/perferendis-qui-suscipit":"^1.0.0","@a-2-c-2-anpm/placeat-suscipit-cumque":"^1.0.0","@a-2-c-2-anpm/quo-quia-expedita":"^1.0.0","@a-2-c-2-anpm/quos-voluptates-excepturi":"^1.0.0","@a-2-c-2-anpm/saepe-praesentium-iusto":"^1.0.0","@a-2-c-2-anpm/sint-ipsa-atque":"^1.0.0","@a-2-c-2-anpm/vitae-ad-molestiae":"^1.0.0","@ajhgwdjnpm/quas-mollitia-aspernatur-reprehenderit":"^1.0.0","calculator-3rd":"^1.0.12","mi-dex-func-3":"^1.0.0","vnhat-button-component":"^1.0.0","vnhat-forminput-component":"^1.0.1"},"keywords":["ratelimit","jsx","css variable","sns","dir","scheme","typesafe","polyfill","random","ses","ES2018","require","lint","create","emit","typanion","Observable","prototype","superagent","characters","trimLeft","waf","chromium","awesomesauce","parent","styleguide","redact","persistent","check","endpoint","auth","less.js","Object","get","syntax","picomatch","await","less css","toobject","positive","negative","bundler","Microsoft","argument","Streams","Object.is","URL","curl","input","proxy","jsonpath","bluebird","ascii","description","bcrypt","replay","efficient","guid","read","values","generics","uninstall","equal","copy","settings","electron","negative zero","form-validation","real-time","hasOwnProperty","http","crypto","Iterator","valid","eslintplugin","superstruct","keys","ESnext","telephone","defineProperty","setPrototypeOf","Array.prototype.findLast","accessor","throat","set","inference","deterministic","dependencies","es-shim API","plugin","dom-testing-library","groupBy","setter","less compiler","tty","middleware","robust","datastructure","tools","optimizer","classnames","emoji","duplex","Array.prototype.flatMap","is","from","directory","watch","Stream","colour","authentication","a11y","async","banner","streams2","findLastIndex","elb","fullwidth","hookform","which","trim","typed array","internal slot","reducer","pyyaml","stylesheet","phone","AsyncIterator","string","styled-components","concat","i18n","typedarrays","ajax","reduce","ES2015","ES2020","test","type","readable","lockfile","folder","ECMAScript 2019","limited","compare","call-bound","open","iterate","args","es-shims","Int8Array","location","dom","chinese","-0","multi-package","Object.defineProperty","protobuf"],"repository":{"type":"git","url":"git+https://github.com/a-2-c-2-anpm/rerum-iste-ducimus.git"},"homepage":"https://github.com/a-2-c-2-anpm/rerum-iste-ducimus/#readme","bugs":{"url":"https://github.com/a-2-c-2-anpm/rerum-iste-ducimus/issues"},"_id":"@a-2-c-2-anpm/rerum-iste-ducimus@1.0.0","gitHead":"47c112c46b5dea559940c1f40d569ea7dee28b95","_nodeVersion":"20.12.2","_npmVersion":"10.5.0","dist":{"integrity":"sha512-ca+7WXDzGq80H4L/vagS2qu1zO+tVPGxwiecGj8gmkrEVE0k0QQb5du1abovKXPYprnh04LLtHWUdvGmzDYabA==","shasum":"d52b9e0ba3e97a555078cd65b86fd3e2f329e9bf","tarball":"https://registry.npmjs.org/@a-2-c-2-anpm/rerum-iste-ducimus/-/rerum-iste-ducimus-1.0.0.tgz","fileCount":8,"unpackedSize":28616,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFkoiMAraNDsgi+qbVCLxGOTyvdlH8b2xBkY2Rog/CNQAiB1JBCZWytX1nXKOy5sh61TSgDGoHQ3aUPlCmUvF+2UVA=="}]},"_npmUser":{"name":"tranduc345zz","email":"tranduc345zz@gmail.com"},"directories":{},"maintainers":[{"name":"tranduc345zz","email":"tranduc345zz@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/rerum-iste-ducimus_1.0.0_1714842389318_0.08928657363690062"},"_hasShrinkwrap":false}},"time":{"created":"2024-05-04T17:06:29.221Z","1.0.0":"2024-05-04T17:06:29.504Z","modified":"2024-05-04T17:06:29.798Z"},"maintainers":[{"name":"tranduc345zz","email":"tranduc345zz@gmail.com"}],"description":"A powerful JSON path processor with no third-party dependencies. Allows you to traverse JSON object trees with a simple dot-delimited path format e.g. \"obj.name\"","homepage":"https://github.com/a-2-c-2-anpm/rerum-iste-ducimus/#readme","keywords":["ratelimit","jsx","css variable","sns","dir","scheme","typesafe","polyfill","random","ses","ES2018","require","lint","create","emit","typanion","Observable","prototype","superagent","characters","trimLeft","waf","chromium","awesomesauce","parent","styleguide","redact","persistent","check","endpoint","auth","less.js","Object","get","syntax","picomatch","await","less css","toobject","positive","negative","bundler","Microsoft","argument","Streams","Object.is","URL","curl","input","proxy","jsonpath","bluebird","ascii","description","bcrypt","replay","efficient","guid","read","values","generics","uninstall","equal","copy","settings","electron","negative zero","form-validation","real-time","hasOwnProperty","http","crypto","Iterator","valid","eslintplugin","superstruct","keys","ESnext","telephone","defineProperty","setPrototypeOf","Array.prototype.findLast","accessor","throat","set","inference","deterministic","dependencies","es-shim API","plugin","dom-testing-library","groupBy","setter","less compiler","tty","middleware","robust","datastructure","tools","optimizer","classnames","emoji","duplex","Array.prototype.flatMap","is","from","directory","watch","Stream","colour","authentication","a11y","async","banner","streams2","findLastIndex","elb","fullwidth","hookform","which","trim","typed array","internal slot","reducer","pyyaml","stylesheet","phone","AsyncIterator","string","styled-components","concat","i18n","typedarrays","ajax","reduce","ES2015","ES2020","test","type","readable","lockfile","folder","ECMAScript 2019","limited","compare","call-bound","open","iterate","args","es-shims","Int8Array","location","dom","chinese","-0","multi-package","Object.defineProperty","protobuf"],"repository":{"type":"git","url":"git+https://github.com/a-2-c-2-anpm/rerum-iste-ducimus.git"},"author":{"name":"a-2-c-2-a"},"bugs":{"url":"https://github.com/a-2-c-2-anpm/rerum-iste-ducimus/issues"},"license":"MIT","readme":"# Irrelon Path\nA powerful JSON path processor with no third-party dependencies.\nAllows you to traverse JSON object trees with a simple dot-delimited\npath format e.g. \"obj.name\"\n\n## What Can It Do?\nIrrelon Path is a JavaScript object manipulation library that uses\ndot notation to denote object key / value field locations within \nthe object structure. It allows you to easily access, modify or\nremove data from an object at locations specified via a path string.\n\n## Install\n\n```bash\nnpm i @a-2-c-2-anpm/rerum-iste-ducimus\n```\n\n# Quick Reference\n* [Simple Usage](#simple-usage)\n* [Escaping Fields with Periods](#escaping-fields-with-periods)\n* [Behaviour](#behaviour)\n* [Default Values](#default-values)\n* Most Common\n    * [get()](#get-obj-path-defaultvalue)\n    * [set()](#set-obj-path-value)\n    * [pushVal()]()\n    * [pullVal()]()\n    * [update()](#update-obj-updatedata-options)\n    * [diff()](#diff-obj1-obj2-path-strict-maxdepth)\n* All Functions (Alphabetically)\n    * [chop()](#chop-path-level)\n    * [clean()](#clean-path)\n    * [countLeafNodes()](#countleafnodes-obj)\n    * [countMatchingPathsInObject()](#countmatchingpathsinobject-testkeys-testobj)\n\t* [decouple()](#decouple-obj-options--)\n\t* [diff()](#diff-obj1-obj2-path-strict-maxdepth)\n\t* [distill()]()\n\t* [down()]()\n\t* [escape()]()\n\t* [findOnePath()](#findonepath-source-query)\n\t* [findPath()]()\n\t* [flatten()]()\n\t* [flattenValues()]()\n\t* [furthest()]()\n\t* [get()](#get-obj-path-defaultvalue)\n\t* [hasMatchingPathsInObject()]()\n\t* [isEqual()]()\n\t* [isNotEqual()]()\n\t* [join()]()\n\t* [joinEscaped()]()\n\t* [leafNodes()]()\n\t* [match()]()\n\t* [numberToWildcard()]()\n\t* [pop()]()\n\t* [pullVal()]()\n\t* [pullValImmutable()]()\n\t* [push()]()\n\t* [pushVal()]()\n\t* [pushValImmutable()]()\n\t* [set()](#set-obj-path-value)\n\t* [setImmutable()](#setimmutable-obj-path-value)\n\t* [shift()]()\n\t* [split()]()\n\t* [type()]()\n\t* [unSet()](#unset-obj-path)\n\t* [unSetImmutable()]()\n\t* [up()]()\n\t* [update()](#update-obj-updatedata-options)\n\t* [updateImmutable()]()\n\t* [values()]()\n    * [wildcardToZero()]()\n\n## Simple Usage\n```js\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\n// Define an object in JSON\nconst obj = {\n  \"users\": {\n    \"test1\": {\n      \"name\": \"My Test User\"\n    }\n  }\n};\n\n// Grab data from the object via the path solver\nconst result = get(obj, 'users.test1.name');\n\nconsole.log(result); // Logs: My Test User\n```\n\n## Escaping Fields with Periods\nSometimes you want to access data where a field name has periods in it like this:\n\n```js\nconst obj = {\n  \"users\": {\n    \"test@test.com\": {\n      \"name\": \"My Test User\"\n    }\n  }\n};\n```\n\nThe user email address \"test@test.com\" contains a period that the path solver\nwill interpret as a traversal indicator. If we try to ask the path solver to get\nthe data in the key \"test@test.com\" it will look for a field called \"test@test\"\nwith a sub-field \"com\".\n\nTo avoid this, escape the period using the escape() function:\n\n```js\nconst {get, escape} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\nconst result = get(obj, `users.${escape('test@test.com')}.name`);\n\nconsole.log(result); // Logs: My Test User\n```\n\n## Behaviour\nIf data or an object to traverse does not exist inside the base object, the\npath solver will return undefined and will NOT throw an error:\n\n```js\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n  \"foo\": null\n};\n\nconst result = get(obj, \"foo.bar.one\");\n\nconsole.log(result); // Logs: undefined\n```\n\n## Default Values\nWhen using get() you can specify a default value to return if the value at\nthe given path is undefined.\n\n```js\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n  \"foo\": null\n};\n\nconst result = get(obj, \"foo.bar.one\", \"My Default Value\");\n\nconsole.log(result); // Logs: My Default Value\n```\n\n## Methods\n### chop (`path`, `level`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|path|String|true|none|\n|level|Number|true|none|\n\nChops a `path` string down to the given `level`. Given a `path` string\nlike \"foo.bar.ram.you.too\", chop will remove any path parts below\nthe given `level`. If we pass 2 as the `level` with that given `path`,\nthe result will be \"foo.bar\" as foo is level 1 and bar is level 2.\n\nIf the `path` is shorter than the given `level`, it is returned intact.\n\n```js\nconst {chop} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = chop(\"foo.bar.one\", 2);\n\nconsole.log(result); // Logs: foo.bar\n```\n\n### clean (`path`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|path|String|true|none|\n\nRemoves leading period (.) from string and returns new string.\n\n```js\nconst {clean} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = clean(\".foo.bar.one\");\n\nconsole.log(result); // Logs: foo.bar.one\n```\n\n### countLeafNodes (`obj`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n\nCounts the total number of key leaf nodes in the passed object.\nLeaf nodes are any key that does not have a value of object or\narray.\n\n```js\nconst {countLeafNodes} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = countLeafNodes({\"foo\": {\"bar\": null}, \"moo\": true});\n\nconsole.log(result); // Logs: 2\n```\n\n### countMatchingPathsInObject (`testKeys`, `testObj`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|testKeys|Object or Array|true|none|\n|testObj|Object or Array|true|none|\n\nTests if the passed object has the paths that are specified and that\na value exists in those paths and if so returns the number matched.\nThe output includes `matchedKeys` with an object where the same structure\nexists as the `testObj` where each leaf node key will be a boolean that\ndescribes if the leaf node exists in the `testKeys` object.\n\n>MAY NOT BE INFINITE RECURSION SAFE.\n\n```js\nconst {countMatchingPathsInObject} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = countMatchingPathsInObject({\n    \"moo\": true\n}, {\n   \"foo\": {\n       \"bar\": null\n   },\n   \"moo\": true\n});\n\nconsole.log(result);\n```\n\nOutputs:\n```json\n{\n  \"matchedKeyCount\": 1,\n  \"matchedKeys\": {\n    \"foo\": {\n      \"bar\": false\n    },\n    \"moo\": true\n  },\n  \"totalKeyCount\": 2\n}\n```\n\n### decouple (`obj`, `options` = {})\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n|options|Object|false|{}|\n\nIf options.immutable === true then return a new de-referenced\ninstance of the passed object/array. If immutable is false\nthen simply return the same `obj` that was passed. The returned\ninstance is NOT deeply immutably cloned because we recurse through\nobject trees and only immutably clone when making changes. This is\nuseful so you can instantly compare two states with a strict\nequality check such as when using [setImmutable()](#setimmutable-obj-path-value). \n\n```js\nconst {decouple} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\"foo\": true};\nconst result = decouple(obj);\n\nconsole.log(result);\nconsole.log(result === obj);\n```\n\nOutputs:\n```json\n{\"foo\":  true}\n```\n```\nfalse\n```\n\n### diff (`obj1`, `obj2`, `path`, `strict`, `maxDepth`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj1|Object or Array|true|none|\n|obj2|Object or Array|true|none|\n|path|String|false|\"\"|\n|strict|Boolean|false|false|\n|maxDepth|Number|false|Infinity|\n\nCompares two objects / arrays and returns the differences as an\narray of paths to the different fields.\n\nFields are considered \"different\" if they do not contain equal\nvalues. The equality check is either strict or non-strict based\non the `strict` argument.\n\n> It is important to understand that this function detects differences\nbetween field values, not differences between object structures. For\ninstance if a field in obj1 contains `undefined` and obj2 does not contain\nthat field at all, it's value in obj2 will also be `undefined` so there\nwould be no difference detected.\n\n```js\nconst {diff} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj1 = {\n\t\"user\": {\n\t\t\"_id\": 1,\n\t\t\"firstName\": \"Jimbo\",\n\t\t\"lastName\": \"Jetson\"\n  \t}\n};\n\nconst obj2 = {\n\t\"user\": {\n\t\t\"_id\": \"1\", // Notice string instead of numerical _id\n\t\t\"firstName\": \"James\", // We also changed the name from \"Jimbo\" to \"James\"\n\t\t\"lastName\": \"Jetson\"\n  \t}\n};\n\nconst resultArr1 = diff(obj1, obj2, \"\", false); // Non-strict equality check\nconst resultArr2 = diff(obj1, obj2, \"\", true); // Strict equality check\n\nconsole.log(resultArr1); // Logs: [\"user.firstName\"]\nconsole.log(resultArr2); // Logs: [\"user._id\", \"user.firstName\"]\n```\n\n### distill (`obj`, `pathArr`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n|pathArr|Array<String>|true|none|\n\nGets the values of the paths in pathArr and returns them as an object\nwith each key matching the path and the value matching the value from\nobj that was at that path.\n\n```js\nconst {distill} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n    \"user\": {\n        \"firstName\": \"Jim\",\n        \"lastName\": \"Jones\",\n        \"age\": 22\n    }\n};\n\nconst result = distill(obj, [\n    \"user.firstName\",\n    \"user.lastName\"\n]);\n\nconsole.log(result);\n```\n\nOutputs:\n```json\n{\n  \"user.firstName\": \"Jim\",\n  \"user.lastName\": \"Jones\"\n}\n```\n\n### down (`path`, `levels` = 1)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|path|String|true|none|\n|levels|Number|false|1|\n\nReturns the given path after removing the first leaf from the\npath. E.g. \"foo.bar.thing\" becomes \"bar.thing\".\n\n```js\nconst {down} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = down(\"user.friends.0.firstName\");\n\nconsole.log(result);\n```\n\nOutputs:\n```json\n\"friends.0.firstName\"\n```\n\n> See also [up()](), [pop()](), [shift()]()\n\n### escape (`path`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|path|String|true|none|\n\nEscapes any periods in the passed string so they will\nnot be identified as part of a path. Useful if you have\na path like \"domains.www.google.com.data\" where the\n\"www.google.com\" should not be considered part of the\ntraversal as it is actually in an object like:\n\n```json\n{\"domains\": {\"www.google.com\": {\"data\": \"foo\"}}}\n```\n\nUsage:\n\n```js\nconst {escape} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst result = escape(\"www.google.com\");\n\nconsole.log(result);\n```\n\nOutputs:\n```json\n\"www\\\\.google\\\\.com\"\n```\n\n### findOnePath (`source`, `query`)\nFinds the first item that matches the structure of `query`\nand returns the path to it\n\n```js\nconst {findOnePath} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst myDataArray = [{\n  \"profile\": {\n  \t\"id\": 1,\n  \t\"name\": \"Ron Swanson\"\n  }\n}, {\n \"profile\": {\n\t\"id\": 2,\n\t\"name\": \"April Ludgate\"\n }\n}];\n\n// Find the object that has a key \"profile\"\n// with a object that has a key \"_id\" that \n// has a value 1, and return the path to it\nconst result1 = findOnePath(myDataArray, {\n\tprofile: {\n\t\t_id: 1\n\t}\n});\n\nconsole.log(result1); // Logs: \"0\"\n\n// Find the object that has a key \"_id\" that \n// has a value 1, and return the path to it\nconst result2 = findOnePath(myDataArray, {\n\t_id: 1\n});\n\nconsole.log(result2); // Logs: \"0.profile\"\n```\n\n> See the unit tests for findOnePath() for many more examples\n of usage.\n\n### findPath (`source`, `query`)\n\n|Param|Type|Required|Default|Description|\n|---|---|---|---|---|\n|source|*|true|none|The source to test.|\n|query|*|true|none|The query to match.|\n\nFinds all items in `source` that match the structure of `query` and\nreturns the path to them as an array of strings.\n\n```js\nconst {findPath} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst myData = {\n  \"profile\": {\n  \t\"id\": 1,\n  \t\"name\": \"Ron Swanson\",\n    \"data\": {\n        \"mobile\": \"+001293284732\"\n    }\n  }\n};\n\nconst result = findPath(myData, {\n\tdata: {\n        \"mobile\": \"+001293284732\"\n    }\n});\n\nconsole.log(result);\n```\n\nOutput: \n\n```json\n{\"match\": true, \"path\": [\"profile\"]}\n```\n\n### flatten (`obj`)\n\n|Param|Type|Required|Default|Description|\n|---|---|---|---|---|\n|obj|Object or Array|true|none|The object to scan.|\n\nTakes an object and finds all paths, then returns the paths as an array\nof strings.\n\n```js\nconst {flatten} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst myData = {\n  \"profile\": {\n  \t\"id\": 1,\n  \t\"name\": \"Ron Swanson\"\n  }\n};\n\nconst result = flatten(myData);\n\nconsole.log(result);\n```\n\nOutput:\n\n```json\n[\"profile.id\", \"profile.name\", \"profile\"]\n```\n\n### flattenValues (`obj`)\n\n|Param|Type|Required|Default|Description|\n|---|---|---|---|---|\n|obj|Object or Array|true|none|The object to scan.|\n\nTakes an object and finds all paths, then returns the paths as keys\nand the values of each path as the values.\n\n```js\nconst {flattenValues} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst myData = {\n  \"profile\": {\n  \t\"id\": 1,\n  \t\"name\": \"Ron Swanson\"\n  }\n};\n\nconst result = flattenValues(myData);\n\nconsole.log(result);\n```\n\nOutput:\n\n```json\n{\n  \"profile\": {\n    \"id\": 1,\n    \"name\": \"Ron Swanson\"\n  },\n  \"profile.id\": 1,\n  \"profile.name\": \"Ron Swanson\"\n}\n```\n\n### furthest (`obj`, `path`)\n\n|Param|Type|Required|Default|Description|\n|---|---|---|---|---|\n|obj|Object or Array|true|none|The object to operate on.|\n|path|String|true|none|The object to operate on.|\n\nGiven object `obj` and a `path`, determines the outermost leaf node\nthat can be reached where the leaf value is not undefined.\n\n```js\nconst {furthest} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst myData = {\n  \"profile\": {\n  \t\"id\": 1,\n  \t\"name\": \"Ron Swanson\"\n  }\n};\n\nconst result = furthest(myData, \"profile.id.bson\");\n\nconsole.log(result);\n```\n\nOutput:\n\n```json\n\"profile.id\"\n```\n\n### get (`obj`, `path`, `defaultValue`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n|path|String|true|none|\n|defaultValue|Any|false|undefined|\n\nGets a value from the `obj` at the given `path` and if no value exists for\nthat path, returns `defaultValue` if one was provided.\n\n```js\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n  \"foo\": null\n};\n\nconst result1 = get(obj, \"foo\");\nconst result2 = get(obj, \"foo.bar.one\", \"My Default Value\");\n\nconsole.log(result1); // Logs: null\nconsole.log(result2); // Logs: My Default Value\n```\n\nIf you want to access elements of an array, simply use the element index\nas part of your path e.g.\n\n```js\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n    \"myArr\": [\n        \"hello\",\n        {\n            \"bar\": \"goodbye\"\n        }\n    ]\n};\n\nconst result1 = get(obj, \"myArr.0\"); // hello\nconst result2 = get(obj, \"myArr.1.bar\"); // goodbye\n```\n\n### set (`obj`, `path`, `value`)\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n|path|String|true|none|\n|value|Any|true|none|\n\nSets a `value` in the `obj` at the given `path`.\n\n> If the given path doesn't exist in the target object it will be created\nby making each non-existent path part a new object.\n\n```js\nconst {set, get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n  \"foo\": null\n};\n\nconst result1 = get(obj, \"foo.bar\"); // Currently: undefined\n\nset(obj, \"foo.bar\", \"hello\");\n\nconst result2 = get(obj, \"foo.bar\");\n\nconsole.log(result1); // Logs: undefined\nconsole.log(result2); // Logs: hello\n```\n\n### setImmutable (`obj`, `path`, `value`)\n> This is a helper function that calls `set()` with immutable\n flag switched on.\n\n|Param|Type|Required|Default|\n|---|---|---|---|\n|obj|Object or Array|true|none|\n|path|String|true|none|\n|value|Any|true|none|\n\nSets a `value` in the `obj` at the given `path` in an immutable way\nand returns a new object. This will not change or modify the existing\n`obj`.\n\nKeep in mind that references to objects that were not modified\nby the operation remain the same. This allows systems like React\nto appropriately act on changes to specific data rather than\nre-rendering an entire DOM tree when one sub-object changes.\n\n> If the given path doesn't exist in the target object it will be created\nby making each non-existent path part a new object.\n\n```js\nconst {setImmutable, get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\n\nconst obj = {\n  \"foo\": {\n  \t\"bar\": \"goodbye\",\n  \t\"subBar\": {\n  \t\t\"somethingElse\": true\n  \t}\n  },\n  \"otherObj\": {\n  \t\"enabled\": true\n  }\n};\n\nconst result1 = get(obj, \"foo.bar\"); // Currently: goodbye\n\nconst newObj = setImmutable(obj, \"foo.bar\", \"hello\");\n\n// Original object remains unmodified (will still be \"goodbye\");\nconst result2 = get(obj, \"foo.bar\");\n\n// New object has new value of \"hello\"\nconst result3 = get(newObj, \"foo.bar\");\n\nconsole.log(result1); // Logs: goodbye\nconsole.log(result2); // Logs: goodbye\nconsole.log(result3); // Logs: hello\n\n// Objects that did not have any modifications remain the same\n// and still share a reference in memory\nconsole.log(obj.otherObj === newObj.otherObj); // Logs: true\n\n// Objects that did have modifications will not be the same\nconsole.log(obj.foo === newObj.foo); // Logs: false\n\n// Child objects of modified parents will still have references\n// to the original since the child object wasn't modified directly\nconsole.log(obj.foo.subBar === newObj.foo.subBar); // Logs: true\n```\n\n### unSet (`obj`, `path`)\nDeletes a key from an object by the given path.\n\n```js\nconst obj = {\n\t\"foo\": {\n\t\t\"bar\": [{\n\t\t\t\"moo\": true,\n\t\t\t\"baa\": \"ram you\"\n\t\t}]\n\t}\n};\n\nconsole.log(obj.foo.bar[0].baa); // Logs: ram you\n\nunSet(obj, \"foo.bar.0.baa\");\n\nconsole.log(obj.foo.bar[0].baa); // Logs: undefined\nconsole.log(obj.foo.bar[0].hasOwnProperty(\"baa\")); // Logs: false\n```\n\n### update (`obj`, `basePath`, `updateData`, `options`)\nSets a single value on the passed object and given path. This\nwill directly modify the \"obj\" object. If you need immutable\nupdates, use updateImmutable() instead.\n\n```js\nconst obj = {\n\t\"foo\": {\n\t\t\"bar\": [{\n\t\t\t\"moo\": true,\n\t\t\t\"baa\": \"ram you\"\n\t\t}]\n\t}\n};\n\nconsole.log(obj.foo.bar[0].baa); // Logs: ram you\n\n// Calling this function with a basePath as an empty string\n// will operate directly on the passed `obj` instead of a \n// sub-object of `obj`.\nupdate(obj, \"\", {\n\t\"foo.bar.0.baa\": \"hello I've been updated\",\n\t\"and.so\": \"have I!\"\n});\n\nconsole.log(obj.foo.bar[0].baa); // Logs: hello I've been updated\nconsole.log(obj.and.so); // Logs: have I!\n```\n\n## Version 5.x Breaking Changes\nThe update() and updateImmutable() functions have their signature changed\nto include a base path in the arguments. If migrating from a previous\nversion you can simply add an empty string as the basePath argument to\nhave the functions operate in the same way as before e.g.\n\n#### Before Version 5.x\n```js\nupdate(obj, updateObj);\nupdateImmutable(obj, updateObj);\n```\n\n#### After Version 5.x\n```js\nupdate(obj, \"\", updateObj);\nupdateImmutable(obj, \"\", updateObj);\n```\n\nThe basePath argument was added so that you can target a path within\nthe passed `obj` to receive the update e.g.\n\n```js\nconst obj = {subObj: {}};\nupdate(obj, \"subObj\", {\"foo\": true});\n```\n\nThe update above will modify `obj.subObj.foo` to equal `true`.\n\n## Version 3.x Breaking Changes\nThere was a bug in the get() function that would return an incorrect value\nwhen a non-object was passed to get data from and a path was passed e.g.\n```js\nget(\"foo-im-not-an-object\", \"some.path.to.get.data.from\"); // Version 2.x returned \"foo-im-not-an-object\"\n```\n\nIn version 3.x, this call will return `undefined` as expected.\n\n## Version 2.x Breaking Changes\nVersion 1.x exported a class that you could instantiate. Version 2.x\nexports an object with all available functions. You can require version\n2.x either all at once (all functions) or you can destructure to require\nonly the functions you need. This change is primarily to support tree\nshaking, as well as move to a more functional programming style, albeit\nnot pure functional style :)\n\nVersion 2.x is a breaking change from version 1.x and you will need to\nmigrate your code to work with the new version. Migration is fairly simple\nand instead of using an instance of the 1.x class, you simply require the\nparts of the library you need e.g.\n\n#### Version 1.x Style Code (Don't Do This)\n```js\n// DON'T DO THIS !!!!!!!!!!!\nconst Path = require(\"irrelon-path\");\nconst pathSolver = new Path();\nconst a = {hello: {foo: true}};\nconst b = pathSolver.get(a, \"hello.foo\"); // b === true\n```\n\n#### Version 2.x Style Code (Please Use This)\n```js\n// DO THIS :)\nconst {get} = require(\"@a-2-c-2-anpm/rerum-iste-ducimus\");\nconst a = {hello: {foo: true}};\nconst b = get(a, \"hello.foo\"); // b === true\n```","readmeFilename":"README.md"}