{"_id":"@4lolo/keypather","name":"@4lolo/keypather","dist-tags":{"latest":"3.1.1"},"versions":{"3.1.1":{"name":"@4lolo/keypather","version":"3.1.1","description":"Get or set a deep value using a keypath string. Supports bracket and dot notation","main":"index.js","scripts":{"lint":"standard","test-watch":"jest --coverage --watch","test":"jest --coverage"},"repository":{"type":"git","url":"git+https://github.com/4lolo/keypather.git"},"keywords":["keypath","deep","get","set","check","existance","value","traversal","dot","bracket","notation","path","array","object","node","module","key","keys","string"],"author":{"name":"Tejesh Mehta"},"license":"MIT","bugs":{"url":"https://github.com/4lolo/keypather/issues"},"homepage":"https://github.com/4lolo/keypather","dependencies":{"debug":"^3.2.7","escape-string-regexp":"^1.0.5","shallow-clone":"^3.0.1","string-reduce":"^1.0.0"},"devDependencies":{"deep-freeze-strict":"^1.1.1","fast-deep-equal":"^3.0.0","jest":"^21.2.1","standard":"^12.0.1"},"_id":"@4lolo/keypather@3.1.1","gitHead":"e82cfae9a2498dcf6099c1c192cc6c39b12c098e","_nodeVersion":"20.8.1","_npmVersion":"10.1.0","dist":{"integrity":"sha512-rlAqWfqwJL9q46grZCKWxwbwxiH6FmjVV1Ecqv/DBZQHUUnkAbItzoQeWS4zCRIWt2SB16Ujj6JvFX7f3cMPFw==","shasum":"0f644d43e6a47752014fc079bca3426c97676fe3","tarball":"https://registry.npmjs.org/@4lolo/keypather/-/keypather-3.1.1.tgz","fileCount":64,"unpackedSize":126895,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBfaFl4/+fQ6HMg2bEBsdEIG7EQ427TVp/Mkl98jzmvbAiEAz2BLX/T9OVGKjPZVI7p5TS20NTEW2q7zNi3NyroyNl0="}]},"_npmUser":{"name":"4lolo","email":"krzysztofwojcicki@gmail.com"},"directories":{},"maintainers":[{"name":"4lolo","email":"krzysztofwojcicki@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/keypather_3.1.1_1699956210293_0.2107985371503125"},"_hasShrinkwrap":false}},"time":{"created":"2023-11-14T10:03:30.182Z","3.1.1":"2023-11-14T10:03:30.545Z","modified":"2023-11-14T10:03:30.833Z"},"maintainers":[{"name":"4lolo","email":"krzysztofwojcicki@gmail.com"}],"description":"Get or set a deep value using a keypath string. Supports bracket and dot notation","homepage":"https://github.com/4lolo/keypather","keywords":["keypath","deep","get","set","check","existance","value","traversal","dot","bracket","notation","path","array","object","node","module","key","keys","string"],"repository":{"type":"git","url":"git+https://github.com/4lolo/keypather.git"},"author":{"name":"Tejesh Mehta"},"bugs":{"url":"https://github.com/4lolo/keypather/issues"},"license":"MIT","readme":"![keypather-logo](https://i.imgur.com/wFm1N25.png)\r\n\r\n# keypather [![Build Status](https://travis-ci.org/tjmehta/keypather.png?branch=master)](https://travis-ci.org/tjmehta/keypather) [![Coverage Status](https://coveralls.io/repos/github/tjmehta/keypather/badge.svg?branch=immutable-methods)](https://coveralls.io/github/tjmehta/keypather?branch=immutable-methods) [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](http://standardjs.com/)\r\n\r\nGet, set, or delete a deep value using a keypath string (supports immutable operations) and more.\r\n\r\nA collection of keypath utilities: get, set, delete, in, has, immutable set/delete, flatten, and expand.\r\n\r\nLightweight and parses keypaths using vanilla JS - No ```eval``` or ```new Function``` hacks!\r\n\r\n# Installation\r\n```bash\r\nnpm install keypather\r\n```\r\n\r\n# Usage\r\n\r\n## Examples\r\n\r\n### Import\r\n```js\r\n// modular imports, so you can keep your bundle lean\r\nconst get = require('keypather/get')\r\nconst set = require('keypather/set')\r\nconst del = require('keypather/del')\r\nconst immutableSet = require('keypather/immutable-set')\r\nconst immutableDel = require('keypather/immutable-del')\r\nconst keypathIn = require('keypather/in')\r\nconst hasKeypath = require('keypather/has')\r\nconst expand = require('keypather/expand')\r\nconst flatten = require('keypather/flatten')\r\n```\r\n\r\n### GET, SET, DEL Example\r\n```js\r\nconst get = require('keypather/get')\r\nconst set = require('keypather/set')\r\nconst del = require('keypather/del')\r\n\r\nlet obj\r\n\r\n// Objects\r\nobj = { foo: { bar: 100 } }\r\nget(obj, 'foo.bar')          // returns 100\r\ndel(obj, '[\"foo\"][\"bar\"]')   // returns true, obj becomes { foo: {} }\r\nset(obj, 'foo.bar.qux', 200) // returns 200, obj becomes { foo: { bar: { qux: 200 } } }\r\nget(obj, 'foo[\"bar\"].qux')   // returns 200\r\n\r\n// Arrays\r\nobj = {}\r\nset(obj, 'foo[0]', 100)      // obj is { foo: [ 100 ] }\r\n```\r\n\r\n### Immutable SET, DEL Example\r\n```js\r\nconst set = require('keypather/immutable-set')\r\nconst del = require('keypather/immutable-del')\r\n\r\nlet obj\r\nlet out\r\n\r\n// Objects\r\nobj = { foo: { bar: 100 } }\r\nout = set(obj, 'foo.bar', 100)     // returns obj\r\n// out === obj,\r\n// since it was not modified\r\nout = set(obj, 'foo.bar.qux', 200) // returns { foo: { bar: { qux: 200 } } }\r\n// out !== obj,\r\n// obj is still { foo: { bar: 100 } }\r\nout = del(obj, 'one.two.three')    // returns obj\r\n// out === obj,\r\n// since it was not modified\r\nout = del(obj, 'foo.bar.qux')     // returns { foo: { bar: {} } }\r\n// out !== obj,\r\n// obj is still { foo: { bar: { qux: 200 } } }\r\n\r\n// Arrays\r\nobj = {}\r\nout = set(obj, 'foo[0]', 100) // returns { foo: [ 100 ] } (new)\r\n// out !== obj, obj is still { foo: { bar: 100 } }\r\n```\r\n\r\n### HAS, IN Example\r\n```js\r\nconst hasKeypath = require('keypather/has')\r\nconst keypathIn = require('keypather/in')\r\n\r\nconst obj = { foo: Object.create({ bar: 100 }) }\r\n\r\nhasKeypath(obj, 'foo.bar') // returns false (bar is on proto)\r\nkeypathIn(obj, 'foo.bar')  // returns true\r\nhasKeypath(obj, 'foo')     // returns true\r\n```\r\n\r\n### FLATTEN, EXPAND Example\r\n```js\r\nconst expand = require('keypather/expand')\r\nconst flatten = require('keypather/flatten')\r\n\r\nconst obj = expand({\r\n  'foo.bar': 1,\r\n  'foo.qux[0]': 100,  \r\n  'foo[\"qux\"][1]': 200,\r\n  'foo.qux.wut': 'val'\r\n})\r\n// obj is { foo { bar: 1, qux: [ 100, 200, wut: 'val' ] } }\r\nconst flat = flatten(obj)\r\n// flat is { 'foo.bar': 1, 'foo.qux': 2 } }\r\n```\r\n\r\n### Errors Example\r\n```js\r\n/* Missing deep values w/ \"force: false\" */\r\nget({}, 'foo.bar', { force: false })\r\nset({}, 'foo.bar', 100, { force: false })\r\ndel({}, 'foo.bar', { force: false })\r\nimmutableSet({}, 'foo.bar', 100, { force: false })\r\nimmutableDel({}, 'foo.bar', { force: false })\r\n// TypeError: Cannot read property 'bar' of undefined (at keypath 'foo' of 'foo.bar')\r\nget({ foo: {} }, 'foo.bar', { force: false })\r\nset({ foo: {} }, 'foo.bar', 100, { force: false })\r\ndel({ foo: {} }, 'foo.bar', { force: false })\r\nimmutableSet({ foo: {} }, 'foo.bar', 100, { force: false })\r\nimmutableDel({ foo: {} }, 'foo.bar', { force: false })\r\n// TypeError: Cannot read property 'bar' of undefined (at keypath 'foo.bar' of 'foo.bar.qux')\r\nhasKeypath({}, 'foo.bar', { force: false })\r\n// TypeError: Cannot read property 'hasOwnProperty' of undefined (hasOwnProperty('bar') errored at keypath 'foo' of 'foo.bar')\r\nkeypathIn({}, 'foo.bar', { force: false })\r\n// TypeError: Cannot use 'in' operator to search for 'bar' in undefined (at 'foo' of 'foo.bar')\r\nkeypathIn({}, 'foo.bar.qux', { force: false })\r\nhasKeypath({}, 'foo.bar.qux', { force: false })\r\n// TypeError: Cannot read property 'bar' of undefined (at keypath 'foo' of 'foo.bar.qux')\r\n\r\n/* Warnings for set and immutable-set */\r\n// by default, set will overwrite primitives (string, number or regexp) to an object or array.\r\n// when overwritePrimitives is set to false, sets will warn when settings a key on a primitive\r\n// to disable all warnings use the option { warn: false }\r\nset({}, '[0]', 'val', { overwritePrimitives: false })\r\n// log: Setting number key (0) on object at keypath '' of '[0]')\r\nset([], 'key', 'val', { overwritePrimitives: false })\r\n// log: Setting string key 'foo' on array at keypath '' of 'foo')\r\nset({ foo: 1 }, 'foo.qux', 'val', { overwritePrimitives: false })\r\n// log: Setting key 'qux' on number 1 at keypath 'foo' of 'foo.qux')\r\nset({ foo: 1 }, 'foo[0]', 'val', { overwritePrimitives: false })\r\n// log: Setting number key (0) on number 1 at keypath 'foo' of 'foo[0]')\r\nset({ foo: 'str' }, 'foo.bar', 'val', { overwritePrimitives: false })\r\n// log: Setting key 'bar' on string 'str' at keypath 'foo' of 'foo.bar')\r\nset({ foo: {} }, 'foo[0]', 'val', { overwritePrimitives: false })\r\n// log: Setting number key (0) on object at keypath 'foo' of 'foo[0]')\r\n\r\n/* Invalid keypaths */\r\nget({}, 'foo.1bar')\r\n// Error: Unexpected token '1' in keypath 'foo.1bar' at position 4 (invalid dot key)\r\nget({}, 'foo[]')       \r\n// Error: Unexpected token ']' in keypath 'foo[]' at position 4 (invalid bracket key)\r\nget({}, 'foo[\"]')\r\n// Error: Unexpected token ']' in keypath 'foo[]' at position 5 (invalid bracket string key)\r\nget({}, 'foo.')\r\n// Error: Unexpected end of keypath 'foo.' (invalid dot key)\r\nget({}, 'foo[')\r\n// Error: Unexpected end of keypath 'foo[' (invalid bracket key)\r\nget({}, \"foo['\")\r\n// Error: Unexpected end of keypath 'foo['' (invalid bracket string key)\r\n```\r\n\r\n## Documentation\r\n\r\n### GET\r\nReturns value at keypath in obj\r\n* @param {any} obj - context to read keypath from\r\n* @param {string} keypath - bracket and/or dot notation keypath string\r\n* @param {?object} opts - optional, defaults to { force: true }\r\n*   opts.force - force specifies whether non-existant keypaths should be ignored, defaults to true\r\n*     if false, `get` will error when reading a key on a non-existant keypath.\r\n* @returns {any} value at keypath\r\n\r\n```js\r\nconst get = require('keypather/get');\r\nconst obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n    }\r\n  }\r\n};\r\nget(obj, \"foo.bar.baz\");           // returns 'val'\r\nget(obj, \"foo['bar'].baz\");        // returns 'val'\r\nget(obj, \"['foo']['bar']['baz']\"); // returns 'val'\r\n\r\nget({}, 'foo.two.three', { force: false }) // throws error\r\n// TypeError: Cannot read property 'three' of undefined (at keypath 'foo.two' of 'foo.two.three')\r\n```\r\n\r\n### SET\r\nSets a value in obj at keypath. If force=true, set will create objects at non-existant keys in the\r\nkeypath. If the non-existant key is a number, its value will be initialized as an array.\r\n* @param {any} obj - context to read keypath from\r\n* @param {string} keypath - bracket and/or dot notation keypath string to read from obj\r\n* @returns {any} value - value to set at keypath\r\n* @param {?object} opts - optional, defaults to { force: true, overwritePrimitives: true, warn: true }\r\n*   opts.force - whether non-existant keys in keypath should be created, defaults to true.\r\n*     if false, `set` will error when reading a key on a non-existant keypath.\r\n*   opts.overwritePrimitives - whether primitive keys (booleans, strings, numbers) should be overwritten.\r\n*     setting a key on a primitive will convert it to an object or array (if key is string or number).\r\n*     if false, `set` will log a warning when setting keys on primitives.\r\n*   opts.silent - specifies whether warning logs should be enabled, defaults to false.\r\n* @returns {any} value set at keypath\r\n\r\n```js\r\nconst set = require('keypather/set');\r\n\r\nlet obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n    }\r\n  }\r\n};\r\nset(obj, \"foo['bar'].baz\", 'val');        // returns 'val'\r\nset(obj, \"foo.bar.baz\", 'val');           // returns 'val'\r\nset(obj, \"['foo']['bar']['baz']\", 'val'); // returns 'val'\r\n\r\n/* By default, set forces creation of non-existant keys */\r\nobj = {}\r\nset(obj, \"foo.bar.baz\", 'val'); // returns 'val'\r\n// obj becomes:\r\n// {\r\n//   foo: {\r\n//     bar: {\r\n//       baz: 'val'\r\n//     }\r\n//   }\r\n// };\r\n\r\n/* By default, overwrites primitives when setting a key on one */\r\nobj = { foo: 1 }\r\nset(obj, \"foo.bar.baz\", 'val'); // returns 'val'\r\n// obj becomes:\r\n// {\r\n//   foo: {\r\n//     bar: {\r\n//       baz: 'val'\r\n//     }\r\n//   }\r\n// };\r\nobj = { foo: 1 }\r\nset(obj, \"foo[0].baz\", 'val'); // returns 'val'\r\n// obj becomes:\r\n// {\r\n//   foo: [{\r\n//     baz: 'val'\r\n//   }]\r\n// };\r\n\r\n/* Errors, force=false */\r\nset({}, \"foo.bar.baz\", 'val', { force: false }); // throw's an error\r\n// TypeError: Cannot read property 'bar' of undefined (at keypath 'foo' of 'foo.bar.baz')\r\n// see more errors above in the 'Errors' section\r\n\r\n/* Warnings, overwritePrimitives=false */\r\nset({ foo: 'str' }, 'foo.bar', 'val', { overwritePrimitives: false })\r\n// log: Setting key 'bar' on string 'str' at keypath 'foo' of 'foo.bar')\r\n// see more warnings above in the 'Errors' section\r\n```\r\n\r\n### DEL\r\nDeletes value a keypath in obj. Similar to `delete obj.key`.\r\n* @param {any} obj - context to read keypath from\r\n* @param {string} keypath - bracket and/or dot notation keypath string to delete from obj\r\n* @param {?object} opts - optional, defaults to { force: true }\r\n*   opts.force - whether non-existant keys in keypath should be created, defaults to true.\r\n*     if false, `del` will error when reading a key on a non-existant keypath.\r\n* @returns {boolean} true except when the property is non-configurable or in non-strict mode\r\n\r\n```js\r\nconst del = require('keypather/del');\r\n\r\nconst obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n    }\r\n  }\r\n};\r\ndel(obj, \"foo['bar'].baz\");        // true\r\ndel(obj, \"foo.bar.baz\");           // true\r\ndel(obj, \"['foo']['bar']['baz']\"); // true\r\n// obj becomes:\r\n// {\r\n//   foo: {\r\n//     bar: {}\r\n//   }\r\n// }\r\n\r\n/* Errors, force=false */\r\ndel(obj, \"one.two.three\", 'val', { force: false }); // throw's an error\r\n// TypeError: Cannot read property 'two' of undefined (at keypath 'one' of 'one.two.three')\r\n// see more errors above in the 'Errors' section\r\n```\r\n\r\n### IMMUTABLE SET\r\nSets a value in obj at keypath. If force=true, set will create objects at non-existant keys in the\r\nkeypath. If the non-existant key is a number, its value will be initialized as an array.\r\n* @param {any} obj - context to read keypath from\r\n* @param {string} keypath - bracket and/or dot notation keypath string to read from obj\r\n* @returns {any} value - value to set at keypath\r\n* @param {?object} opts - optional, defaults to { force: true, overwritePrimitives: true, warn: true }\r\n*   opts.force - whether non-existant keys in keypath should be created, defaults to true.\r\n*     if false, `immutable-set` will error when reading a key on a non-existant keypath.\r\n*   opts.overwritePrimitives - whether primitive keys (booleans, strings, numbers) should be overwritten.\r\n*     setting a key on a primitive will convert it to an object or array (if key is string or number).\r\n*     if false, `immutable-set` will log a warning when setting keys on primitives.\r\n*   opts.silent - specifies whether warning logs should be enabled, defaults to false.\r\n*   opts.shallowClone - provide custom shallowClone, defaults to [shallow-clone](https://npmrepo.com/shallow-clone)\r\n* @returns {any} returns same obj if unmodified, otherwise modified clone of obj\r\n\r\n```js\r\nconst set = require('keypather/immutable-set');\r\n\r\nlet obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n    }\r\n  }\r\n};\r\nlet out\r\nout = set(obj, \"foo['bar'].baz\", 'val');         // returns SAME object, since the value was unchanged\r\n// out === obj\r\nout = set(obj, \"foo.bar.baz\", 'val2');           // returns { foo: { bar: { baz: 'val2' } } } (new object)\r\n// out !== obj\r\nout = set(obj, \"['foo']['bar']['baz']\", 'val3'); // returns { foo: { bar: { baz: 'val3' } } } (new object)\r\n// out !== obj\r\n\r\n/* By default, overwrites primitives when setting a key on one */\r\nobj = { foo: 1 }\r\nout = set(obj, \"foo.bar.baz\", 'val'); // returns new object\r\n// out !== obj\r\n// out is:\r\n// {\r\n//   foo: {\r\n//     bar: {\r\n//       baz: 'val'\r\n//     }\r\n//   }\r\n// };\r\nobj = { foo: 1 }\r\nout = set(obj, \"foo[0].baz\", 'val'); // returns new object\r\n// out !== obj\r\n// out is:\r\n// {\r\n//   foo: [{\r\n//     baz: 'val'\r\n//   }]\r\n// };\r\n\r\n/* Errors, force=false */\r\nobj = {}\r\nset(obj, \"foo.bar.baz\", 'val', { force: false }); // throws error\r\n// Error: Cannot read property 'bar' of undefined (at keypath 'foo' of 'foo.bar.baz')\r\n\r\n/* Warnings, force=false */\r\nobj = { foo: 'str' }\r\nout = set(obj, 'foo.bar', 'val', { overwritePrimitives: false })\r\n// out === obj, since keys cannot be set on strings or numbers\r\n// log: Setting key 'bar' on string 'str' at keypath 'foo' of 'foo.bar')\r\n```\r\n\r\n### IMMUTABLE DEL\r\nDeletes value a keypath in obj. Similar to `delete obj.key`.\r\n* @param {any} obj - context to read keypath from\r\n* @param {string} keypath - bracket and/or dot notation keypath string to delete from obj\r\n* @param {?object} opts - optional, defaults to { force: true }\r\n*   opts.force - whether non-existant keys in keypath should be created, defaults to true.\r\n*     if false, `del` will error when reading a key on a non-existant keypath.\r\n*   opts.shallowClone - provide custom shallowClone, defaults to [shallow-clone](https://npmrepo.com/shallow-clone)\r\n* @returns {any} returns same obj if unmodified, otherwise modified clone of obj\r\n\r\n```js\r\nconst del = require('keypather/immutable-del');\r\nconst obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n    }\r\n  }\r\n};\r\nlet out\r\nout = del(obj, \"foo['bar'].baz\");        // true\r\nout = del(obj, \"foo.bar.baz\");           // true\r\nout = del(obj, \"['foo']['bar']['baz']\"); // true\r\n// obj becomes:\r\n// {\r\n//   foo: {\r\n//     bar: {}\r\n//   }\r\n// }\r\n\r\n/* Errors, force=false */\r\ndel(obj, \"one.two.three\", 'val', { force: false }); // throw's an error\r\n// Error: Cannot read property 'two' of undefined (at keypath 'one' of 'one.two.three')\r\n```\r\n\r\n### IN\r\nReturns true if keypath is \"in\" the obj at the keypath. Similar to \"in\" operator.\r\n* @param {any} obj - context to read keypath in\r\n* @param {string} keypath - bracket and/or dot notation keypath string to read from obj\r\n* @param {?object} opts - optional, defaults to { force: true }\r\n*   opts.force - force specifies whether non-existant keypaths should be ignored, defaults to true\r\n* @returns {boolean} true if the keypath is \"in\" the obj, else false\r\n\r\n```js\r\nconst keypathIn = require('keypather/in');\r\nconst obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n      __proto__: {\r\n        qux: 'val'\r\n      }\r\n    }\r\n  }\r\n};\r\nkeypathIn(obj, \"foo.bar.baz\");           // true\r\nkeypathIn(obj, \"foo.bar.qux\");           // true\r\nkeypathIn(obj, \"foo.bar.bing\");          // false\r\nkeypathIn(obj, \"foo['bar'].baz\");        // true\r\nkeypathIn(obj, \"one.two.three\");         // false\r\n\r\n// Errors, force=false\r\nkeypathIn(obj, \"one.two.three\", { force: false });\r\n// Error: Cannot read property 'two' of undefined (at keypath 'two' of 'one.two.three')\r\nkeypathIn(obj, \"foo.two.three\", { force: false });\r\n// TypeError: Cannot use 'in' operator to search for 'three' in undefined (at 'foo.two' of 'foo.two.three')\r\n```\r\n\r\n### HAS\r\nReturns true if the obj has the keypath. Similar to `obj.hasOwnProperty`.\r\n* @param {any} obj - context to read keypath in\r\n* @param {string} keypath - bracket and/or dot notation keypath string to read from obj\r\n* @param {?object} opts - optional, defaults to { force: true }\r\n*   opts.force - force specifies whether non-existant keypaths should be ignored, defaults to true\r\n* @returns {boolean} true if the keypath is \"in\" the obj, else false\r\n\r\n```js\r\nconst hasKeypath = require('keypather/has');\r\nconst obj = {\r\n  foo: {\r\n    bar: {\r\n      baz: 'val'\r\n      __proto__: {\r\n        qux: 'val'\r\n      }\r\n    }\r\n  }\r\n};\r\nhasKeypath(obj, \"foo.bar.baz\");           // true\r\nhasKeypath(obj, \"foo.bar.qux\");           // false\r\nhasKeypath(obj, \"['foo']['bar']['baz']\"); // true\r\nhasKeypath(obj, \"one.two.three\");         // false\r\n\r\n// Errors, force=false\r\nhasKeypath(obj, \"one.two.three\", { force: false }); // throw's an error\r\n// Error: Cannot read property 'two' of undefined (at keypath 'two' of 'one.two.three\r\nhasKeypath(obj, \"foo.two.three\", { force: false });\r\n// Error: Cannot read property 'hasOwnProperty' of undefined (hasOwnProperty('three') errored at keypath 'foo.two' of 'foo.two.three')\r\n```\r\n\r\n### FLATTEN\r\nFlatten an object or array into a keypath object\r\n* @param {any} obj - object or array to flatten\r\n\r\n```js\r\nconst flatten = require('keypather/flatten');\r\n\r\nflatten({\r\n  foo: {\r\n    qux: 'hello'\r\n  },\r\n  bar: [\r\n    1,\r\n    {\r\n      yolo: [1]\r\n    }\r\n  ]\r\n});\r\n// returns:\r\n// {\r\n//   'foo.qux': 'hello',\r\n//   'bar[0]': 1,\r\n//   'bar[1].yolo[0]': 1\r\n// }\r\n\r\n/* accepts a delimiter other than '.' as second arg */\r\n\r\nflatten({\r\n  foo: {\r\n    qux: 'hello'\r\n  }\r\n}, '_');\r\n// returns:\r\n// {\r\n//   'foo_qux': 'hello',\r\n// }\r\n\r\n```\r\n\r\n### EXPAND\r\nExpand a flattened object back into an object or array\r\n* @param {any} obj - flattened object or array to be expanded\r\n\r\n```js\r\nconst expand = require('keypather/expand');\r\n\r\nexpand({\r\n  'foo.qux': 'hello',\r\n  'bar[0]': 1,\r\n  'bar[1].yolo[0]': 1\r\n});\r\n// returns:\r\n// {\r\n//   foo: {\r\n//     qux: 'hello'\r\n//   },\r\n//   bar: [\r\n//     1,\r\n//     {\r\n//       yolo: [1]\r\n//     }\r\n//   ]\r\n// }\r\n\r\n/* expand will assume an object is an array if any of the keys are numbers */\r\n\r\nexpand({\r\n  '[0]': 1,\r\n  '[1].yolo[0]': 1\r\n});\r\n// returns:\r\n// [\r\n//   1,\r\n//   {\r\n//     yolo: [1]\r\n//   }\r\n// ]\r\n\r\n/* accepts a delimiter other than '.' as second arg */\r\n\r\nexpand({\r\n 'foo_qux': 'hello'\r\n}, '_');\r\n// returns:\r\n// {\r\n//   foo: {\r\n//     qux: 'hello'\r\n//   }\r\n// }\r\n```\r\n\r\n# Changelog\r\n[Changelog history](https://github.com/tjmehta/keypather/blob/master/CHANGELOG.md)\r\n\r\n# License\r\n### MIT\r\n","readmeFilename":"README.md"}