{"_id":"access","_rev":"14-b511d9818d8ecab0eb2b16ef05ab1a4f","name":"access","description":"Get deeply nested values from unknown shapes with at-runtime type safety.","dist-tags":{"latest":"1.0.2"},"versions":{"0.1.0":{"name":"access","version":"0.1.0","description":"resource access control by id with groups and modes using redis-graph","main":"index.js","bin":{},"directories":{"test":"test"},"dependencies":{"redis-graph":"0.x.x"},"devDependencies":{"tap":"~0.2.5","redis":"~0.7.2"},"scripts":{"test":"tap test/*.js"},"repository":{"type":"git","url":"git://github.com/tblobaum/access.git"},"homepage":"https://github.com/tblobaum/access","keywords":["access","control","groups","modes","resources","redis","graph"],"author":{"name":"Thomas Blobaum","email":"tblobaum@gmail.com","url":"https://github.com/tblobaum/"},"license":"MIT","_id":"access@0.1.0","dist":{"shasum":"ec7cd6cd966d86abca1293f7137613caffb669d0","tarball":"https://registry.npmjs.org/access/-/access-0.1.0.tgz","integrity":"sha512-MrkyfbVCbFkiAsinZ3Lr6O91aYNpRlm+Y7eGIli5qwScxEiW5Y2VLZ7bZSQpaiEwkbKV7sPvsJTj5mGxS//ljA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIC1rSv0Ul1nK3E6QPgbC8oorexvwLvbcD9f6ovSQ2k2wAiAWVwBrfTSXuIenjAnf+IlU+ByFotB6QfxqiGFANJu19A=="}]},"readme":"","maintainers":[{"name":"tblobaum","email":"tblobaum@gmail.com"}]},"0.2.0":{"name":"access","version":"0.2.0","description":"resource access control by id with groups and modes using redis-graph","main":"index.js","bin":{},"directories":{"test":"test"},"dependencies":{"redis-graph":"*","redis-multi-set":"*"},"devDependencies":{"tap":"~0.2.5","redis":"~0.7.2"},"scripts":{"test":"tap test/*.js"},"repository":{"type":"git","url":"git://github.com/tblobaum/access.git"},"homepage":"https://github.com/tblobaum/access","keywords":["access","control","groups","modes","resources","redis","graph"],"author":{"name":"Thomas Blobaum","email":"tblobaum@gmail.com","url":"https://github.com/tblobaum/"},"license":"MIT","_id":"access@0.2.0","dist":{"shasum":"0af74443994c2fad4019ed21a170909da798357e","tarball":"https://registry.npmjs.org/access/-/access-0.2.0.tgz","integrity":"sha512-mfvfrb3jsl77vVfwPhlp25fEteplbZrha5bu261+p7qwP6RWvY61nV7JXPA2r0DV8ls1xh8CF8l2dkuWkZkVJA==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC/w4F9k2ut3UI6ZFYP9d9is02FUlDztkX+fK0rgbNnGAIhAI086fpxa6Cx4zKCKJ5VBb1oi9POXjcbf69n2UDJCssM"}]},"readme":"","maintainers":[{"name":"tblobaum","email":"tblobaum@gmail.com"}]},"0.2.1":{"name":"access","version":"0.2.1","description":"access control resources, groups and modes by id","main":"index.js","bin":{},"directories":{"test":"test"},"dependencies":{"redis-graph":"*","redis-multi-set":"*"},"devDependencies":{"tap":"~0.2.5","redis":"~0.7.2"},"scripts":{"test":"tap test/*.js"},"repository":{"type":"git","url":"git://github.com/tblobaum/access.git"},"homepage":"https://github.com/tblobaum/access","keywords":["access","control","groups","modes","resources","redis","graph"],"author":{"name":"Thomas Blobaum","email":"tblobaum@gmail.com","url":"https://github.com/tblobaum/"},"license":"MIT","_id":"access@0.2.1","dist":{"shasum":"6616096cc30f3cf3ef95441b1631e5c4fa4996b2","tarball":"https://registry.npmjs.org/access/-/access-0.2.1.tgz","integrity":"sha512-HCOMQKyiAkkKSzDvLiErr53JuoyIBXj8l6CDI+ImXlBEGq6FbeXWkR7OANMs9OoySNGbEAZ6tJaM7jJJ1u9Nsg==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCKpwtq7Kkk2h2yMOv000/HjjaporRknMVbZjJJekUUyAIgG6tChAjS0fpZyEvFX6DlM/8sFOUDlvp/tiHjFwqFb2c="}]},"readme":"","maintainers":[{"name":"tblobaum","email":"tblobaum@gmail.com"}]},"1.0.0":{"name":"access","version":"1.0.0","description":"Get deeply nested values from unknown shapes with at-runtime type safety.","main":"./lib/index.js","types":"./lib/index.d.ts","author":{"name":"Conor Davidson","email":"conor@conordavidson.com"},"license":"MIT","scripts":{"build":"tsc --pretty","test":"jest --coverage","test:cover":"jest && codecov"},"jest":{"testRegex":".*/*.test.ts$","moduleFileExtensions":["js","ts"],"transform":{"\\.ts$":"ts-jest"},"coverageDirectory":"./coverage/","collectCoverage":true},"devDependencies":{"@types/jest":"^24.0.15","codecov":"^3.5.0","jest":"^24.8.0","ts-jest":"^24.0.2","typescript":"^3.5.2"},"gitHead":"7250f041b300e577f08ed845c91ea87696eb7c9b","_id":"access@1.0.0","_npmVersion":"5.6.0","_nodeVersion":"8.11.1","_npmUser":{"name":"conordavidson","email":"conor@conordavidson.com"},"dist":{"integrity":"sha512-lsLiWV+IHlPy89LZl6LHl/6PxDVS7goUbY4bcUOxSLlnpaBKQVPSpRkkH3J+Kt+hu4zl6Z6g6/9GYPmyjVMDQQ==","shasum":"fdf5d2358ac7ee70e822c7df670a53c0f2773607","tarball":"https://registry.npmjs.org/access/-/access-1.0.0.tgz","fileCount":13,"unpackedSize":140732,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdQhccCRA9TVsSAnZWagAAjvQQAIQgye5U7REwYyelN5AE\nm7lBjmdApOg4CGk8KsTJ212xrjuUznJHrNpmvh1cT43/pbQnDuV0TQmTHBCh\nnkgL+Dq160tAcpg3DCJEKbdckJHJtx4t/+WbflpQBDGo5zc3t0MnvnGHeUCA\n00i/biO0VoIvqRdNEL67UzCxabYLqaLlr6BjH5pSMZeGizkisUZwiVPkF69c\n+NUGV998XJvO4BqippKlZS2dylMRAvYcAaRlbDko5PcoouCLMMazWUXRG/D8\npR5rcfm8WSJkkdaYA0T/QqnYNLh//LWCtBAc8+CwExI4FluU7F3wUd+3DJKC\nILbWJckSxtjepYzgoOYj1LrKIp8RWtEzGJ4QCEqrWa4ScOwFw2NOk8oNIKHR\n6OxzIzRAUQzNWhN+E4pW8jceIMYm+21oIBbPUw+76yzWE0kuUXigWVyGfn+f\n/J4tPTs/ycpIGsEw7c+3qxZH7oLP4PNbRBozVzS7hoL3brYgHoV/i41oR+47\noeS+BgJ7iSCISah2T2uHeCaE+RVAS+gAveTqmPw8NFLR45zwYgHGl7wzPxs0\n1N0ON8rXKb2oP9XYuYnCqVKHL7GrKo1W9PxMrcpuQMmjx6Qw8b/4m44BnLZH\nBxneZxDimH/jmuLoKXr4ASAUpKfO6tU3qSJDvXg0YyLdcULEw+EjhkLFGF7I\nuJLk\r\n=7CWQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFEQXXxDYnhqxumzGmryBbKSuBTEmn5gDWcbwBDhfuVmAiEAhAP8AM7OSB6ylj6lrVh5GVIoXj7ZaPg+6qbAYsVRrtc="}]},"maintainers":[{"email":"conor@conordavidson.com","name":"conordavidson"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/access_1.0.0_1564612379387_0.3172957614532068"},"_hasShrinkwrap":false},"1.0.1":{"name":"access","version":"1.0.1","description":"Get deeply nested values from unknown shapes with at-runtime type safety.","main":"./lib/index.js","types":"./lib/index.d.ts","author":{"name":"Conor Davidson","email":"conor@conordavidson.com"},"license":"MIT","scripts":{"build":"tsc --pretty","test":"jest --coverage","test:cover":"jest && codecov"},"jest":{"testRegex":".*/*.test.ts$","moduleFileExtensions":["js","ts"],"transform":{"\\.ts$":"ts-jest"},"coverageDirectory":"./coverage/","collectCoverage":true},"devDependencies":{"@types/jest":"^24.0.15","codecov":"^3.5.0","jest":"^24.8.0","ts-jest":"^24.0.2","typescript":"^3.5.2"},"gitHead":"46a82df3f0eaca9890b71bab7f4603dbb80338a7","_id":"access@1.0.1","_npmVersion":"5.6.0","_nodeVersion":"8.11.1","_npmUser":{"name":"conordavidson","email":"conor@conordavidson.com"},"dist":{"integrity":"sha512-OyUfRzmlKfahee/PY+7YTt1ZESOrBo3iBmLkx3YmUI39ZSuBQrAK8IjWfmtPuLl8ZXaxYb0Y4kaHicffvjkCow==","shasum":"0908b6edb21a5572ee6a386542cc8bebdbac8dde","tarball":"https://registry.npmjs.org/access/-/access-1.0.1.tgz","fileCount":24,"unpackedSize":56989,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdQho4CRA9TVsSAnZWagAAX6IP/iPC14Q/XlI9Y7ilvAeB\n5rmDoERVD0QH1O8cqxHfKzgqIXHE43x0iidMTd/gi2xrRYW+HfN9hcRcSvjW\nrTIPHWZwBu4uuC7dXCw512CFVByUYZpCgJJYKgAUkjgQN+6cJz3hL8jGv+NK\nCy7doIqjUUphIifV5B1QyX2dgV2ZMD985xS0q7cths6H+Y6luAAtwVVL4zOz\nxz2I1FwFD22OHx1gFl6+OXNXeVyYIb6onpSOBbV6svM3SycaeU6S+HXD2PXQ\nI4OnGktVf+xWnXmo2gR6Ry+9VERMMKC8bTvi8tIZub0gTzp4C5UUurtaC8Jv\nDpxv/lwdDdG2g+eh+mDNJksoW/J9HBAJUGEYY0gKKH8HKSoXSUzL/yjdiCjC\njkMjyeVRa27wLHUxEyD05TrJ4eidmSxr8soalXSW7nHIpHdnY7Fhy6/+7sNv\nQ8HF3M+ix6O2Q2G3FAg+ePQIFkDphMWGYeVpJTZ35JTCG+sMy+SxHD5S2NfC\nVNEYs9usgLkEF3K/8LagBzHtnHCDflmbdovJEaAoUVm7L6Wu18z6mEJUj3lw\nJBHk64A1IVhD2zelZRqplAKmBbTAChxMF3UVwyWViEPO3Ce1KgSf8t48mdhk\nWi9HJJWTBkx2DoyvXiKNwYO3VpSBVrEyqYMahAI6km9nyAVKe90N83O8eEEV\nB7sO\r\n=EngF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG9AsYbjd/0H0qSm7i5vvZj8aHsTAkz/xhssAu6iTyhTAiEAhvEzDXuhMe9Vg+7qB0CD9oGvcREG8cVj/q6rc14M77o="}]},"maintainers":[{"email":"conor@conordavidson.com","name":"conordavidson"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/access_1.0.1_1564613175026_0.30637283623860734"},"_hasShrinkwrap":false},"1.0.2":{"name":"access","version":"1.0.2","description":"Get deeply nested values from unknown shapes with at-runtime type safety.","main":"./lib/index.js","types":"./lib/index.d.ts","author":{"name":"Conor Davidson","email":"conor@conordavidson.com"},"license":"MIT","scripts":{"build":"tsc --pretty","test":"jest --coverage","test:cover":"jest && codecov"},"jest":{"testRegex":".*/*.test.ts$","moduleFileExtensions":["js","ts"],"transform":{"\\.ts$":"ts-jest"},"coverageDirectory":"./coverage/","collectCoverage":true},"devDependencies":{"@types/jest":"^24.0.15","codecov":"^3.5.0","jest":"^24.8.0","ts-jest":"^24.0.2","typescript":"^3.5.2"},"gitHead":"6a86444cb84e6cc09528355c9da9e3e40fb29e52","_id":"access@1.0.2","_npmVersion":"5.6.0","_nodeVersion":"8.11.1","_npmUser":{"name":"conordavidson","email":"conor@conordavidson.com"},"dist":{"integrity":"sha512-f8nS8zB/1DEXSqJlM+oBYj/DeW6cJB/+7rQNoKHZylaBROCoomApKtUHITCXp7crJvHhviQJQ+cYJ7RdRoIXjA==","shasum":"93a8d2e9452e8a78bfd85b6846d98727592089cd","tarball":"https://registry.npmjs.org/access/-/access-1.0.2.tgz","fileCount":23,"unpackedSize":56678,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdQhrpCRA9TVsSAnZWagAAqr8P/21UHEfZU7FPOvv/pq5z\nBY6hMnIBCw2qUlwK9oBdUoiAVNfzwAZJMmDi+tHmf3dgAy5NJgBIVc6NrIiF\n/ruruvfrYOjt3FOBX+1Gu8+FKyotyrBZZ346i2juD+ppPKdKdg/R4ZPJ98K/\nNTwwzkJVhPEd992Eojo1jDeDEvNBPuGAaW5tbPyb7tFp+ZzfYwQJKK4xhrrN\nuhIJwphSO4Imo5/pEBZxjiaRQDB6MYimYKK8xze5sE0t2aVROLlPRIvxJ7e0\nD6xlMEfkNMwajctOpSYQF1bPWcGpA2vpELpMGzx4kDTzkOtrc47QffpzdBW9\na/xAKR2+0/PGYZ3xKjiHd9SJlkx7ux7YUJO9oAC0m5WoZ33l5aEd8dLKxThl\nJ4OCw/dQ29GqiT3Nx3s4eG5D0/rNiYFVMz25GwPJblBwyNgi84z5sLsUkNXC\nNChP7CWI6m/n065xsYfvmm7d91JJezoyIvpUHeX+5aG5xnCXLFtQJPsjb2kG\nUAAi+ugRSuqIJVEvko+W86GM75trmjwc3AAxUa9xs2R3HAaaMiTI/NigW3+x\nq6k69b/uJZJ1ArLouAnm62fANIPYRlpJ8nQbtjyXEUPlH4O3loQ8TwHsfRqH\ndEK55QVO/yaa2aIgFVfGgNVBZsFDWTa2EaPxhZx/MLzXj2aQvu3nZ0FbqW14\nJKnP\r\n=5uAZ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCID1RZ4bDu/BfHaDEXwzIeReJ2NKbe0Fb97/ZxMYSkqesAiEAjpiVwxI8nAQsaS8eayfAS6+j5q5OYktli/4izZkbdPw="}]},"maintainers":[{"email":"conor@conordavidson.com","name":"conordavidson"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/access_1.0.2_1564613351816_0.33768296794615327"},"_hasShrinkwrap":false}},"readme":"# Access\n\n[![codecov](https://codecov.io/gh/conordavidson/access/branch/master/graph/badge.svg)](https://codecov.io/gh/conordavidson/access)\n\n#### Get deeply nested properties from unknown shapes with at-runtime type safety.\n\nAccess allows you to get values in `unknown` or `any` types and be assured you will get the correct type out. If the value is missing, undefined, or the incorrect type, the given fallback is returned instead. This is achieved with at-runtime type checking. A global callback can also be registered to be called anytime a fallback is returned.\n\n## Installation\n\n###### yarn\n\n```\nyarn add access\n```\n\n###### npm\n\n```\nnpm install access\n```\n\n## Example\n\n```ts\nimport { getString, getNumber } from 'access';\n\nconst apiResponse: unknown = {\n  data: {\n    user: {\n      address: {\n        state: 'MA',\n      },\n    },\n  },\n};\n\ngetString(apiResponse, x => x.data.user.address.state, 'state not found'); // \"MA\"\ngetString(apiResponse, x => x.missing.key, 'fallback'); // fallback\ngetNumber(apiResponse, x => x.data.user.address.state, 999); // 999\n```\n\n---\n\n## API\n\n#### `getString`\n\n```ts\ngetString<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType), fallback: string, callback?: (e: Error) => void): string\n```\n\n#### `getNumber`\n\n```ts\ngetNumber<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: number, callback?: (e: Error) => void): number\n```\n\n#### `getBoolean`\n\n```ts\ngetBoolean<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: boolean, callback?: (e: Error) => void): boolean\n```\n\n#### `getStringArray`\n\n```ts\ngetStringArray<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: string[], callback?: (e: Error) => void): string[]\n```\n\n#### `getNumberArray`\n\n```ts\ngetNumberArray<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: number[], callback?: (e: Error) => void): number[]\n```\n\n#### `getBooleanArray`\n\n```ts\ngetBooleanArray<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: boolean[], callback?: (e: Error) => void): boolean[]\n```\n\n#### `getStringMap`\n\n```ts\ngetStringMap<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: { [key: string]: string }, callback?: (e: Error) => void): { [key: string]: string }\n```\n\n#### `getNumberMap`\n\n```ts\ngetNumberMap<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: { [key: string]: number }, callback?: (e: Error) => void): { [key: string]: number }\n```\n\n#### `getBooleanMap`\n\n```ts\ngetBooleanMap<ObjectType, ReturnType>(obj: ObjectType, accessor: (obj: ObjectType) => ReturnType, fallback: { [key: string]: boolean }, callback?: (e: Error) => void): { [key: string]: boolean }\n```\n\n---\n\n## Configuration\n\nA callback can be registered with the default `access` export. This callback will be called anytime a fallback is returned.\n\nA typical usecase for this is to send a message to some error tracking software signaling that a CMS or some other remote server is no longer returning data in a shape that we expected. See the example below:\n\n#### Configuration Example\n\n#### `getter.ts`\n\n```ts\nimport access from 'access';\n\nconst {\n  getString,\n  getNumber,\n  getBoolean,\n  getStringArray,\n  getNumberArray,\n  getBooleanArray,\n  getStringMap,\n  getNumberArray,\n  getBooleanMap,\n} = access(error => {\n  ErrorTracker.send('ui.fallback.returned', error);\n});\n\nexport { getString, getNumber, getBoolean, getStringArray, getNumberArray, getBooleanArray, getStringMap, getNumberArray, getBooleanMap };\n```\n\n#### `example.ts`\n\n```ts\nimport { getString, getNumber } from './getter.ts';\n\nconst apiResponse: unknown = {\n  data: {\n    players: {\n      1: {\n        userName: 'player one',\n      },\n    },\n  },\n};\n\ngetString(apiResponse, x => x.missing.key, 'fallback text'); // \"fallback text\"\n// error ('ui.fallback.returned', PropertyMissingException...) was sent to ErrorTracker\n```\n\n---\n\n## Related Projects\n\n[`ts-get`](https://github.com/RIP21/ts-get) and [`idx`](https://github.com/facebookincubator/idx) share the same goals and API as this one. The biggest difference is that this library works against `unknown` types, whereas the others require the accessed object to be explicitly typed with optional types. Neither library does runtime checking to prevent against type mismatches either.\n\n## FAQ\n\n#### Why not use a generic type signature?\n\nThe library was originally implemented as one generic `get` function. It looked something like:\n\n```ts\nfunction access<ObjectType, ReturnType extends number>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): number;\nfunction access<ObjectType, ReturnType extends string>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): string;\nfunction access<ObjectType, ReturnType extends boolean>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): boolean;\nfunction access<ObjectType, ReturnType extends number[]>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): number[];\nfunction access<ObjectType, ReturnType extends string[]>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): string[];\nfunction access<ObjectType, ReturnType extends boolean[]>(\n  obj: ObjectType,\n  accessor: (obj: ObjectType) => ReturnType,\n  fallback: ReturnType,\n): boolean[];\nfunction access(object, accessorFn, fallback, fallbackCallback) {\n  try {\n    const result = accessor(object);\n    if (isNumber(fallback) && isNumber(result)) return result;\n    if (isString(fallback) && isString(result)) return result;\n    if (isBoolean(fallback) && isBoolean(result)) return result;\n    if (isNumberArray(fallback) && isNumberArray(result)) return result;\n    if (isStringArray(fallback) && isStringArray(result)) return result;\n    if (isBooleanArray(fallback) && isBooleanArray(result)) return result;\n  } catch (e) {\n    return fallback;\n  }\n}\n```\n\nThis generic implementation — while having a much smaller surface area — had large performance implications, especially when dealing with arrays and maps. Due to the nature of the runtime typechecking, the fallback and return value had to be checked against all possible return types to be able to infer which type to return. Therefor multiple (more specific) methods were chosen over this simpler syntax.\n","maintainers":[{"email":"conor@conordavidson.com","name":"conordavidson"}],"time":{"modified":"2022-06-13T02:21:12.209Z","created":"2012-08-07T09:37:44.054Z","0.1.0":"2012-08-07T09:37:44.895Z","0.2.0":"2012-08-07T12:18:25.104Z","0.2.1":"2012-08-09T09:57:19.124Z","1.0.0":"2019-07-31T22:32:59.543Z","1.0.1":"2019-07-31T22:46:15.186Z","1.0.2":"2019-07-31T22:49:12.874Z"},"author":{"name":"Conor Davidson","email":"conor@conordavidson.com"},"license":"MIT","readmeFilename":"README.md"}