pax_global_header00006660000000000000000000000064135017361220014512gustar00rootroot0000000000000052 comment=886b40f394d5b0879a2aa1bee06326a4265459ee cacache-11.3.3/000077500000000000000000000000001350173612200131465ustar00rootroot00000000000000cacache-11.3.3/.github/000077500000000000000000000000001350173612200145065ustar00rootroot00000000000000cacache-11.3.3/.github/FUNDING.yml000066400000000000000000000000761350173612200163260ustar00rootroot00000000000000# These are supported funding model platforms github: [zkat] cacache-11.3.3/.gitignore000066400000000000000000000000471350173612200151370ustar00rootroot00000000000000/node_modules /.nyc_output /test/cache cacache-11.3.3/.travis.yml000066400000000000000000000002041350173612200152530ustar00rootroot00000000000000before_install: - npm i -g npm@latest install: - npm ci language: node_js sudo: false node_js: - "10" - "9" - "8" - "6" cacache-11.3.3/CHANGELOG.md000066400000000000000000000502641350173612200147660ustar00rootroot00000000000000# Changelog All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. ### [11.3.3](https://github.com/zkat/cacache/compare/v11.3.2...v11.3.3) (2019-06-17) ### Bug Fixes * **audit:** npm audit fix ([200a6d5](https://github.com/zkat/cacache/commit/200a6d5)) * **config:** Add ssri config 'error' option ([#146](https://github.com/zkat/cacache/issues/146)) ([47de8f5](https://github.com/zkat/cacache/commit/47de8f5)) * **deps:** npm audit fix ([481a7dc](https://github.com/zkat/cacache/commit/481a7dc)) * **standard:** standard --fix ([7799149](https://github.com/zkat/cacache/commit/7799149)) * **write:** avoid another cb never called situation ([5156561](https://github.com/zkat/cacache/commit/5156561)) ## [11.3.2](https://github.com/zkat/cacache/compare/v11.3.1...v11.3.2) (2018-12-21) ### Bug Fixes * **get:** make sure to handle errors in the .then ([b10bcd0](https://github.com/zkat/cacache/commit/b10bcd0)) ## [11.3.1](https://github.com/zkat/cacache/compare/v11.3.0...v11.3.1) (2018-11-05) ### Bug Fixes * **get:** export hasContent.sync properly ([d76c920](https://github.com/zkat/cacache/commit/d76c920)) # [11.3.0](https://github.com/zkat/cacache/compare/v11.2.0...v11.3.0) (2018-11-05) ### Features * **get:** add sync API for reading ([db1e094](https://github.com/zkat/cacache/commit/db1e094)) # [11.2.0](https://github.com/zkat/cacache/compare/v11.1.0...v11.2.0) (2018-08-08) ### Features * **read:** add sync support to other internal read.js fns ([fe638b6](https://github.com/zkat/cacache/commit/fe638b6)) # [11.1.0](https://github.com/zkat/cacache/compare/v11.0.3...v11.1.0) (2018-08-01) ### Features * **read:** add sync support for low-level content read ([b43af83](https://github.com/zkat/cacache/commit/b43af83)) ## [11.0.3](https://github.com/zkat/cacache/compare/v11.0.2...v11.0.3) (2018-08-01) ### Bug Fixes * **config:** add ssri config options ([#136](https://github.com/zkat/cacache/issues/136)) ([10d5d9a](https://github.com/zkat/cacache/commit/10d5d9a)) * **perf:** refactor content.read to avoid lstats ([c5ac10e](https://github.com/zkat/cacache/commit/c5ac10e)) * **test:** oops when removing safe-buffer ([1950490](https://github.com/zkat/cacache/commit/1950490)) ## [11.0.2](https://github.com/zkat/cacache/compare/v11.0.1...v11.0.2) (2018-05-07) ### Bug Fixes * **verify:** size param no longer lost in a verify ([#131](https://github.com/zkat/cacache/issues/131)) ([c614a19](https://github.com/zkat/cacache/commit/c614a19)), closes [#130](https://github.com/zkat/cacache/issues/130) ## [11.0.1](https://github.com/zkat/cacache/compare/v11.0.0...v11.0.1) (2018-04-10) # [11.0.0](https://github.com/zkat/cacache/compare/v10.0.4...v11.0.0) (2018-04-09) ### Features * **opts:** use figgy-pudding for opts ([#128](https://github.com/zkat/cacache/issues/128)) ([33d4eed](https://github.com/zkat/cacache/commit/33d4eed)) ### meta * drop support for node@4 ([529f347](https://github.com/zkat/cacache/commit/529f347)) ### BREAKING CHANGES * node@4 is no longer supported ## [10.0.4](https://github.com/zkat/cacache/compare/v10.0.3...v10.0.4) (2018-02-16) ## [10.0.3](https://github.com/zkat/cacache/compare/v10.0.2...v10.0.3) (2018-02-16) ### Bug Fixes * **content:** rethrow aggregate errors as ENOENT ([fa918f5](https://github.com/zkat/cacache/commit/fa918f5)) ## [10.0.2](https://github.com/zkat/cacache/compare/v10.0.1...v10.0.2) (2018-01-07) ### Bug Fixes * **ls:** deleted entries could cause a premature stream EOF ([347dc36](https://github.com/zkat/cacache/commit/347dc36)) ## [10.0.1](https://github.com/zkat/cacache/compare/v10.0.0...v10.0.1) (2017-11-15) ### Bug Fixes * **move-file:** actually use the fallback to `move-concurrently` (#110) ([073fbe1](https://github.com/zkat/cacache/commit/073fbe1)) # [10.0.0](https://github.com/zkat/cacache/compare/v9.3.0...v10.0.0) (2017-10-23) ### Features * **license:** relicense to ISC (#111) ([fdbb4e5](https://github.com/zkat/cacache/commit/fdbb4e5)) ### Performance Improvements * more copyFile benchmarks ([63787bb](https://github.com/zkat/cacache/commit/63787bb)) ### BREAKING CHANGES * **license:** the license has been changed from CC0-1.0 to ISC. # [9.3.0](https://github.com/zkat/cacache/compare/v9.2.9...v9.3.0) (2017-10-07) ### Features * **copy:** added cacache.get.copy api for fast copies (#107) ([067b5f6](https://github.com/zkat/cacache/commit/067b5f6)) ## [9.2.9](https://github.com/zkat/cacache/compare/v9.2.8...v9.2.9) (2017-06-17) ## [9.2.8](https://github.com/zkat/cacache/compare/v9.2.7...v9.2.8) (2017-06-05) ### Bug Fixes * **ssri:** bump ssri for bugfix ([c3232ea](https://github.com/zkat/cacache/commit/c3232ea)) ## [9.2.7](https://github.com/zkat/cacache/compare/v9.2.6...v9.2.7) (2017-06-05) ### Bug Fixes * **content:** make verified content completely read-only (#96) ([4131196](https://github.com/zkat/cacache/commit/4131196)) ## [9.2.6](https://github.com/zkat/cacache/compare/v9.2.5...v9.2.6) (2017-05-31) ### Bug Fixes * **node:** update ssri to prevent old node 4 crash ([5209ffe](https://github.com/zkat/cacache/commit/5209ffe)) ## [9.2.5](https://github.com/zkat/cacache/compare/v9.2.4...v9.2.5) (2017-05-25) ### Bug Fixes * **deps:** fix lockfile issues and bump ssri ([84e1d7e](https://github.com/zkat/cacache/commit/84e1d7e)) ## [9.2.4](https://github.com/zkat/cacache/compare/v9.2.3...v9.2.4) (2017-05-24) ### Bug Fixes * **deps:** bumping deps ([bbccb12](https://github.com/zkat/cacache/commit/bbccb12)) ## [9.2.3](https://github.com/zkat/cacache/compare/v9.2.2...v9.2.3) (2017-05-24) ### Bug Fixes * **rm:** stop crashing if content is missing on rm ([ac90bc0](https://github.com/zkat/cacache/commit/ac90bc0)) ## [9.2.2](https://github.com/zkat/cacache/compare/v9.2.1...v9.2.2) (2017-05-14) ### Bug Fixes * **i18n:** lets pretend this didn't happen ([519b4ee](https://github.com/zkat/cacache/commit/519b4ee)) ## [9.2.1](https://github.com/zkat/cacache/compare/v9.2.0...v9.2.1) (2017-05-14) ### Bug Fixes * **docs:** fixing translation messup ([bb9e4f9](https://github.com/zkat/cacache/commit/bb9e4f9)) # [9.2.0](https://github.com/zkat/cacache/compare/v9.1.0...v9.2.0) (2017-05-14) ### Features * **i18n:** add Spanish translation for API ([531f9a4](https://github.com/zkat/cacache/commit/531f9a4)) # [9.1.0](https://github.com/zkat/cacache/compare/v9.0.0...v9.1.0) (2017-05-14) ### Features * **i18n:** Add Spanish translation and i18n setup (#91) ([323b90c](https://github.com/zkat/cacache/commit/323b90c)) # [9.0.0](https://github.com/zkat/cacache/compare/v8.0.0...v9.0.0) (2017-04-28) ### Bug Fixes * **memoization:** actually use the LRU ([0e55dc9](https://github.com/zkat/cacache/commit/0e55dc9)) ### Features * **memoization:** memoizers can be injected through opts.memoize (#90) ([e5614c7](https://github.com/zkat/cacache/commit/e5614c7)) ### BREAKING CHANGES * **memoization:** If you were passing an object to opts.memoize, it will now be used as an injected memoization object. If you were only passing booleans and other non-objects through that option, no changes are needed. # [8.0.0](https://github.com/zkat/cacache/compare/v7.1.0...v8.0.0) (2017-04-22) ### Features * **read:** change hasContent to return {sri, size} (#88) ([bad6c49](https://github.com/zkat/cacache/commit/bad6c49)), closes [#87](https://github.com/zkat/cacache/issues/87) ### BREAKING CHANGES * **read:** hasContent now returns an object with `{sri, size}` instead of `sri`. Use `result.sri` anywhere that needed the old return value. # [7.1.0](https://github.com/zkat/cacache/compare/v7.0.5...v7.1.0) (2017-04-20) ### Features * **size:** handle content size info (#49) ([91230af](https://github.com/zkat/cacache/commit/91230af)) ## [7.0.5](https://github.com/zkat/cacache/compare/v7.0.4...v7.0.5) (2017-04-18) ### Bug Fixes * **integrity:** new ssri with fixed integrity stream ([6d13e8e](https://github.com/zkat/cacache/commit/6d13e8e)) * **write:** wrap stuff in promises to improve errors ([3624fc5](https://github.com/zkat/cacache/commit/3624fc5)) ## [7.0.4](https://github.com/zkat/cacache/compare/v7.0.3...v7.0.4) (2017-04-15) ### Bug Fixes * **fix-owner:** throw away ENOENTs on chownr ([d49bbcd](https://github.com/zkat/cacache/commit/d49bbcd)) ## [7.0.3](https://github.com/zkat/cacache/compare/v7.0.2...v7.0.3) (2017-04-05) ### Bug Fixes * **read:** fixing error message for integrity verification failures ([9d4f0a5](https://github.com/zkat/cacache/commit/9d4f0a5)) ## [7.0.2](https://github.com/zkat/cacache/compare/v7.0.1...v7.0.2) (2017-04-03) ### Bug Fixes * **integrity:** use EINTEGRITY error code and update ssri ([8dc2e62](https://github.com/zkat/cacache/commit/8dc2e62)) ## [7.0.1](https://github.com/zkat/cacache/compare/v7.0.0...v7.0.1) (2017-04-03) ### Bug Fixes * **docs:** fix header name conflict in readme ([afcd456](https://github.com/zkat/cacache/commit/afcd456)) # [7.0.0](https://github.com/zkat/cacache/compare/v6.3.0...v7.0.0) (2017-04-03) ### Bug Fixes * **test:** fix content.write tests when running in docker ([d2e9b6a](https://github.com/zkat/cacache/commit/d2e9b6a)) ### Features * **integrity:** subresource integrity support (#78) ([b1e731f](https://github.com/zkat/cacache/commit/b1e731f)) ### BREAKING CHANGES * **integrity:** The entire API has been overhauled to use SRI hashes instead of digest/hashAlgorithm pairs. SRI hashes follow the Subresource Integrity standard and support strings and objects compatible with [`ssri`](https://npm.im/ssri). * This change bumps the index version, which will invalidate all previous index entries. Content entries will remain intact, and existing caches will automatically reuse any content from before this breaking change. * `cacache.get.info()`, `cacache.ls()`, and `cacache.ls.stream()` will now return objects that looks like this: ``` { key: String, integrity: '-', path: ContentPath, time: Date, metadata: Any } ``` * `opts.digest` and `opts.hashAlgorithm` are obsolete for any API calls that used them. * Anywhere `opts.digest` was accepted, `opts.integrity` is now an option. Any valid SRI hash is accepted here -- multiple hash entries will be resolved according to the standard: first, the "strongest" hash algorithm will be picked, and then each of the entries for that algorithm will be matched against the content. Content will be validated if *any* of the entries match (so, a single integrity string can be used for multiple "versions" of the same document/data). * `put.byDigest()`, `put.stream.byDigest`, `get.byDigest()` and `get.stream.byDigest()` now expect an SRI instead of a `digest` + `opts.hashAlgorithm` pairing. * `get.hasContent()` now expects an integrity hash instead of a digest. If content exists, it will return the specific single integrity hash that was found in the cache. * `verify()` has learned to handle integrity-based caches, and forgotten how to handle old-style cache indices due to the format change. * `cacache.rm.content()` now expects an integrity hash instead of a hex digest. # [6.3.0](https://github.com/zkat/cacache/compare/v6.2.0...v6.3.0) (2017-04-01) ### Bug Fixes * **fixOwner:** ignore EEXIST race condition from mkdirp ([4670e9b](https://github.com/zkat/cacache/commit/4670e9b)) * **index:** ignore index removal races when inserting ([b9d2fa2](https://github.com/zkat/cacache/commit/b9d2fa2)) * **memo:** use lru-cache for better mem management (#75) ([d8ac5aa](https://github.com/zkat/cacache/commit/d8ac5aa)) ### Features * **dependencies:** Switch to move-concurrently (#77) ([dc6482d](https://github.com/zkat/cacache/commit/dc6482d)) # [6.2.0](https://github.com/zkat/cacache/compare/v6.1.2...v6.2.0) (2017-03-15) ### Bug Fixes * **index:** additional bucket entry verification with checksum (#72) ([f8e0f25](https://github.com/zkat/cacache/commit/f8e0f25)) * **verify:** return fixOwner.chownr promise ([6818521](https://github.com/zkat/cacache/commit/6818521)) ### Features * **tmp:** safe tmp dir creation/management util (#73) ([c42da71](https://github.com/zkat/cacache/commit/c42da71)) ## [6.1.2](https://github.com/zkat/cacache/compare/v6.1.1...v6.1.2) (2017-03-13) ### Bug Fixes * **index:** set default hashAlgorithm ([d6eb2f0](https://github.com/zkat/cacache/commit/d6eb2f0)) ## [6.1.1](https://github.com/zkat/cacache/compare/v6.1.0...v6.1.1) (2017-03-13) ### Bug Fixes * **coverage:** bumping coverage for verify (#71) ([0b7faf6](https://github.com/zkat/cacache/commit/0b7faf6)) * **deps:** glob should have been a regular dep :< ([0640bc4](https://github.com/zkat/cacache/commit/0640bc4)) # [6.1.0](https://github.com/zkat/cacache/compare/v6.0.2...v6.1.0) (2017-03-12) ### Bug Fixes * **coverage:** more coverage for content reads (#70) ([ef4f70a](https://github.com/zkat/cacache/commit/ef4f70a)) * **tests:** use safe-buffer because omfg (#69) ([6ab8132](https://github.com/zkat/cacache/commit/6ab8132)) ### Features * **rm:** limited rm.all and fixed bugs (#66) ([d5d25ba](https://github.com/zkat/cacache/commit/d5d25ba)), closes [#66](https://github.com/zkat/cacache/issues/66) * **verify:** tested, working cache verifier/gc (#68) ([45ad77a](https://github.com/zkat/cacache/commit/45ad77a)) ## [6.0.2](https://github.com/zkat/cacache/compare/v6.0.1...v6.0.2) (2017-03-11) ### Bug Fixes * **index:** segment cache items with another subbucket (#64) ([c3644e5](https://github.com/zkat/cacache/commit/c3644e5)) ## [6.0.1](https://github.com/zkat/cacache/compare/v6.0.0...v6.0.1) (2017-03-05) ### Bug Fixes * **docs:** Missed spots in README ([8ffb7fa](https://github.com/zkat/cacache/commit/8ffb7fa)) # [6.0.0](https://github.com/zkat/cacache/compare/v5.0.3...v6.0.0) (2017-03-05) ### Bug Fixes * **api:** keep memo cache mostly-internal ([2f72d0a](https://github.com/zkat/cacache/commit/2f72d0a)) * **content:** use the rest of the string, not the whole string ([fa8f3c3](https://github.com/zkat/cacache/commit/fa8f3c3)) * **deps:** removed `format-number[@2](https://github.com/2).0.2` ([1187791](https://github.com/zkat/cacache/commit/1187791)) * **deps:** removed inflight[@1](https://github.com/1).0.6 ([0d1819c](https://github.com/zkat/cacache/commit/0d1819c)) * **deps:** rimraf[@2](https://github.com/2).6.1 ([9efab6b](https://github.com/zkat/cacache/commit/9efab6b)) * **deps:** standard[@9](https://github.com/9).0.0 ([4202cba](https://github.com/zkat/cacache/commit/4202cba)) * **deps:** tap[@10](https://github.com/10).3.0 ([aa03088](https://github.com/zkat/cacache/commit/aa03088)) * **deps:** weallcontribute[@1](https://github.com/1).0.8 ([ad4f4dc](https://github.com/zkat/cacache/commit/ad4f4dc)) * **docs:** add security note to hashKey ([03f81ba](https://github.com/zkat/cacache/commit/03f81ba)) * **hashes:** change default hashAlgorithm to sha512 ([ea00ba6](https://github.com/zkat/cacache/commit/ea00ba6)) * **hashes:** missed a spot for hashAlgorithm defaults ([45997d8](https://github.com/zkat/cacache/commit/45997d8)) * **index:** add length header before JSON for verification ([fb8cb4d](https://github.com/zkat/cacache/commit/fb8cb4d)) * **index:** change index filenames to sha1s of keys ([bbc5fca](https://github.com/zkat/cacache/commit/bbc5fca)) * **index:** who cares about race conditions anyway ([b1d3888](https://github.com/zkat/cacache/commit/b1d3888)) * **perf:** bulk-read get+read for massive speed ([d26cdf9](https://github.com/zkat/cacache/commit/d26cdf9)) * **perf:** use bulk file reads for index reads ([79a8891](https://github.com/zkat/cacache/commit/79a8891)) * **put-stream:** remove tmp file on stream insert error ([65f6632](https://github.com/zkat/cacache/commit/65f6632)) * **put-stream:** robustified and predictibilized ([daf9e08](https://github.com/zkat/cacache/commit/daf9e08)) * **put-stream:** use new promise API for moves ([1d36013](https://github.com/zkat/cacache/commit/1d36013)) * **readme:** updated to reflect new default hashAlgo ([c60a2fa](https://github.com/zkat/cacache/commit/c60a2fa)) * **verify:** tiny typo fix ([db22d05](https://github.com/zkat/cacache/commit/db22d05)) ### Features * **api:** converted external api ([7bf032f](https://github.com/zkat/cacache/commit/7bf032f)) * **cacache:** exported clearMemoized() utility ([8d2c5b6](https://github.com/zkat/cacache/commit/8d2c5b6)) * **cache:** add versioning to content and index ([31bc549](https://github.com/zkat/cacache/commit/31bc549)) * **content:** collate content files into subdirs ([c094d9f](https://github.com/zkat/cacache/commit/c094d9f)) * **deps:** [@npmcorp](https://github.com/npmcorp)/move[@1](https://github.com/1).0.0 ([bdd00bf](https://github.com/zkat/cacache/commit/bdd00bf)) * **deps:** bluebird[@3](https://github.com/3).4.7 ([3a17aff](https://github.com/zkat/cacache/commit/3a17aff)) * **deps:** promise-inflight[@1](https://github.com/1).0.1 ([a004fe6](https://github.com/zkat/cacache/commit/a004fe6)) * **get:** added memoization support for get ([c77d794](https://github.com/zkat/cacache/commit/c77d794)) * **get:** export hasContent ([2956ec3](https://github.com/zkat/cacache/commit/2956ec3)) * **index:** add hashAlgorithm and format insert ret val ([b639746](https://github.com/zkat/cacache/commit/b639746)) * **index:** collate index files into subdirs ([e8402a5](https://github.com/zkat/cacache/commit/e8402a5)) * **index:** promisify entry index ([cda3335](https://github.com/zkat/cacache/commit/cda3335)) * **memo:** added memoization lib ([da07b92](https://github.com/zkat/cacache/commit/da07b92)) * **memo:** export memoization api ([954b1b3](https://github.com/zkat/cacache/commit/954b1b3)) * **move-file:** add move fallback for weird errors ([5cf4616](https://github.com/zkat/cacache/commit/5cf4616)) * **perf:** bulk content write api ([51b536e](https://github.com/zkat/cacache/commit/51b536e)) * **put:** added memoization support to put ([b613a70](https://github.com/zkat/cacache/commit/b613a70)) * **read:** switched to promises ([a869362](https://github.com/zkat/cacache/commit/a869362)) * **rm:** added memoization support to rm ([4205cf0](https://github.com/zkat/cacache/commit/4205cf0)) * **rm:** switched to promises ([a000d24](https://github.com/zkat/cacache/commit/a000d24)) * **util:** promise-inflight ownership fix requests ([9517cd7](https://github.com/zkat/cacache/commit/9517cd7)) * **util:** use promises for api ([ae204bb](https://github.com/zkat/cacache/commit/ae204bb)) * **verify:** converted to Promises ([f0b3974](https://github.com/zkat/cacache/commit/f0b3974)) ### BREAKING CHANGES * cache: index/content directories are now versioned. Previous caches are no longer compatible and cannot be migrated. * util: fix-owner now uses Promises instead of callbacks * index: Previously-generated index entries are no longer compatible and the index must be regenerated. * index: The index format has changed and previous caches are no longer compatible. Existing caches will need to be regenerated. * hashes: Default hashAlgorithm changed from sha1 to sha512. If you rely on the prior setting, pass `opts.hashAlgorithm` in explicitly. * content: Previously-generated content directories are no longer compatible and must be regenerated. * verify: API is now promise-based * read: Switches to a Promise-based API and removes callback stuff * rm: Switches to a Promise-based API and removes callback stuff * index: this changes the API to work off promises instead of callbacks * api: this means we are going all in on promises now cacache-11.3.3/CODE_OF_CONDUCT.md000066400000000000000000000241551350173612200157540ustar00rootroot00000000000000# Code of Conduct ## When Something Happens If you see a Code of Conduct violation, follow these steps: 1. Let the person know that what they did is not appropriate and ask them to stop and/or edit their message(s) or commits. 2. That person should immediately stop the behavior and correct the issue. 3. If this doesn’t happen, or if you're uncomfortable speaking up, [contact the maintainers](#contacting-maintainers). 4. As soon as available, a maintainer will look into the issue, and take [further action (see below)](#further-enforcement), starting with a warning, then temporary block, then long-term repo or organization ban. When reporting, please include any relevant details, links, screenshots, context, or other information that may be used to better understand and resolve the situation. **The maintainer team will prioritize the well-being and comfort of the recipients of the violation over the comfort of the violator.** See [some examples below](#enforcement-examples). ## Our Pledge In the interest of fostering an open and welcoming environment, we as contributors and maintainers of this project pledge to making participation in our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, technical preferences, nationality, personal appearance, race, religion, or sexual identity and orientation. ## Our Standards Examples of behavior that contributes to creating a positive environment include: * Using welcoming and inclusive language. * Being respectful of differing viewpoints and experiences. * Gracefully accepting constructive feedback. * Focusing on what is best for the community. * Showing empathy and kindness towards other community members. * Encouraging and raising up your peers in the project so you can all bask in hacks and glory. Examples of unacceptable behavior by participants include: * The use of sexualized language or imagery and unwelcome sexual attention or advances, including when simulated online. The only exception to sexual topics is channels/spaces specifically for topics of sexual identity. * Casual mention of slavery or indentured servitude and/or false comparisons of one's occupation or situation to slavery. Please consider using or asking about alternate terminology when referring to such metaphors in technology. * Making light of/making mocking comments about trigger warnings and content warnings. * Trolling, insulting/derogatory comments, and personal or political attacks. * Public or private harassment, deliberate intimidation, or threats. * Publishing others' private information, such as a physical or electronic address, without explicit permission. This includes any sort of "outing" of any aspect of someone's identity without their consent. * Publishing private screenshots or quotes of interactions in the context of this project without all quoted users' *explicit* consent. * Publishing of private communication that doesn't have to do with reporting harrassment. * Any of the above even when [presented as "ironic" or "joking"](https://en.wikipedia.org/wiki/Hipster_racism). * Any attempt to present "reverse-ism" versions of the above as violations. Examples of reverse-isms are "reverse racism", "reverse sexism", "heterophobia", and "cisphobia". * Unsolicited explanations under the assumption that someone doesn't already know it. Ask before you teach! Don't assume what people's knowledge gaps are. * [Feigning or exaggerating surprise](https://www.recurse.com/manual#no-feigned-surprise) when someone admits to not knowing something. * "[Well-actuallies](https://www.recurse.com/manual#no-well-actuallys)" * Other conduct which could reasonably be considered inappropriate in a professional or community setting. ## Scope This Code of Conduct applies both within spaces involving this project and in other spaces involving community members. This includes the repository, its Pull Requests and Issue tracker, its Twitter community, private email communications in the context of the project, and any events where members of the project are participating, as well as adjacent communities and venues affecting the project's members. Depending on the violation, the maintainers may decide that violations of this code of conduct that have happened outside of the scope of the community may deem an individual unwelcome, and take appropriate action to maintain the comfort and safety of its members. ### Other Community Standards As a project on GitHub, this project is additionally covered by the [GitHub Community Guidelines](https://help.github.com/articles/github-community-guidelines/). Additionally, as a project hosted on npm, is is covered by [npm, Inc's Code of Conduct](https://www.npmjs.com/policies/conduct). Enforcement of those guidelines after violations overlapping with the above are the responsibility of the entities, and enforcement may happen in any or all of the services/communities. ## Maintainer Enforcement Process Once the maintainers get involved, they will follow a documented series of steps and do their best to preserve the well-being of project members. This section covers actual concrete steps. ### Contacting Maintainers You may get in touch with the maintainer team through any of the following methods: * Through email: * [kzm@sykosomatic.org](mailto:kzm@sykosomatic.org) (Kat Marchán) * [charlottelaspencer@gmail.com](mailto:charlottelaspencer@gmail.com) (Charlotte Spencer) * [me@re-becca.org](mailto:me@re-becca.org) (Rebecca Turner) * Through Twitter: * [@maybekatz](https://twitter.com/maybekatz) (Kat Marchán) * [@charlotteis](https://twitter.com/charlotteis) (Charlotte Spencer) * [@ReBeccaOrg](https://twitter.com/ReBeccaOrg) (Rebecca Turner) ### Further Enforcement If you've already followed the [initial enforcement steps](#enforcement), these are the steps maintainers will take for further enforcement, as needed: 1. Repeat the request to stop. 2. If the person doubles down, they will have offending messages removed or edited by a maintainers given an official warning. The PR or Issue may be locked. 3. If the behavior continues or is repeated later, the person will be blocked from participating for 24 hours. 4. If the behavior continues or is repeated after the temporary block, a long-term (6-12mo) ban will be used. On top of this, maintainers may remove any offending messages, images, contributions, etc, as they deem necessary. Maintainers reserve full rights to skip any of these steps, at their discretion, if the violation is considered to be a serious and/or immediate threat to the health and well-being of members of the community. These include any threats, serious physical or verbal attacks, and other such behavior that would be completely unacceptable in any social setting that puts our members at risk. Members expelled from events or venues with any sort of paid attendance will not be refunded. ### Who Watches the Watchers? Maintainers and other leaders who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. These may include anything from removal from the maintainer team to a permanent ban from the community. Additionally, as a project hosted on both GitHub and npm, [their own Codes of Conducts may be applied against maintainers of this project](#other-community-standards), externally of this project's procedures. ### Enforcement Examples #### The Best Case The vast majority of situations work out like this. This interaction is common, and generally positive. > Alex: "Yeah I used X and it was really crazy!" > Patt (not a maintainer): "Hey, could you not use that word? What about 'ridiculous' instead?" > Alex: "oh sorry, sure." -> edits old comment to say "it was really confusing!" #### The Maintainer Case Sometimes, though, you need to get maintainers involved. Maintainers will do their best to resolve conflicts, but people who were harmed by something **will take priority**. > Patt: "Honestly, sometimes I just really hate using $library and anyone who uses it probably sucks at their job." > Alex: "Whoa there, could you dial it back a bit? There's a CoC thing about attacking folks' tech use like that." > Patt: "I'm not attacking anyone, what's your problem?" > Alex: "@maintainers hey uh. Can someone look at this issue? Patt is getting a bit aggro. I tried to nudge them about it, but nope." > KeeperOfCommitBits: (on issue) "Hey Patt, maintainer here. Could you tone it down? This sort of attack is really not okay in this space." > Patt: "Leave me alone I haven't said anything bad wtf is wrong with you." > KeeperOfCommitBits: (deletes user's comment), "@patt I mean it. Please refer to the CoC over at (URL to this CoC) if you have questions, but you can consider this an actual warning. I'd appreciate it if you reworded your messages in this thread, since they made folks there uncomfortable. Let's try and be kind, yeah?" > Patt: "@keeperofbits Okay sorry. I'm just frustrated and I'm kinda burnt out and I guess I got carried away. I'll DM Alex a note apologizing and edit my messages. Sorry for the trouble." > KeeperOfCommitBits: "@patt Thanks for that. I hear you on the stress. Burnout sucks :/. Have a good one!" #### The Nope Case > PepeTheFrog🐸: "Hi, I am a literal actual nazi and I think white supremacists are quite fashionable." > Patt: "NOOOOPE. OH NOPE NOPE." > Alex: "JFC NO. NOPE. @keeperofbits NOPE NOPE LOOK HERE" > KeeperOfCommitBits: "👀 Nope. NOPE NOPE NOPE. 🔥" > PepeTheFrog🐸 has been banned from all organization or user repositories belonging to KeeperOfCommitBits. ## Attribution This Code of Conduct was generated using [WeAllJS Code of Conduct Generator](https://npm.im/weallbehave), which is based on the [WeAllJS Code of Conduct](https://wealljs.org/code-of-conduct), which is itself based on [Contributor Covenant](http://contributor-covenant.org), version 1.4, available at [http://contributor-covenant.org/version/1/4](http://contributor-covenant.org/version/1/4), and the LGBTQ in Technology Slack [Code of Conduct](http://lgbtq.technology/coc.html). cacache-11.3.3/CONTRIBUTING.md000066400000000000000000000515361350173612200154110ustar00rootroot00000000000000# Contributing ## How do I... * [Use This Guide](#introduction)? * Ask or Say Something? 🤔🐛😱 * [Request Support](#request-support) * [Report an Error or Bug](#report-an-error-or-bug) * [Request a Feature](#request-a-feature) * Make Something? 🤓👩🏽‍💻📜🍳 * [Project Setup](#project-setup) * [Contribute Documentation](#contribute-documentation) * [Contribute Code](#contribute-code) * Manage Something ✅🙆🏼💃👔 * [Provide Support on Issues](#provide-support-on-issues) * [Label Issues](#label-issues) * [Clean Up Issues and PRs](#clean-up-issues-and-prs) * [Review Pull Requests](#review-pull-requests) * [Merge Pull Requests](#merge-pull-requests) * [Tag a Release](#tag-a-release) * [Join the Project Team](#join-the-project-team) * Add a Guide Like This One [To My Project](#attribution)? 🤖😻👻 ## Introduction Thank you so much for your interest in contributing!. All types of contributions are encouraged and valued. See the [table of contents](#toc) for different ways to help and details about how this project handles them!📝 Please make sure to read the relevant section before making your contribution! It will make it a lot easier for us maintainers to make the most of it and smooth out the experience for all involved. 💚 The [Project Team](#join-the-project-team) looks forward to your contributions. 🙌🏾✨ ## Request Support If you have a question about this project, how to use it, or just need clarification about something: * Open an Issue at https://github.com/zkat/cacache/issues * Provide as much context as you can about what you're running into. * Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. If not, please be ready to provide that information if maintainers ask for it. Once it's filed: * The project team will [label the issue](#label-issues). * Someone will try to have a response soon. * If you or the maintainers don't respond to an issue for 30 days, the [issue will be closed](#clean-up-issues-and-prs). If you want to come back to it, reply (once, please), and we'll reopen the existing issue. Please avoid filing new issues as extensions of one you already made. ## Report an Error or Bug If you run into an error or bug with the project: * Open an Issue at https://github.com/zkat/cacache/issues * Include *reproduction steps* that someone else can follow to recreate the bug or error on their own. * Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant. If not, please be ready to provide that information if maintainers ask for it. Once it's filed: * The project team will [label the issue](#label-issues). * A team member will try to reproduce the issue with your provided steps. If there are no repro steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced. * If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#contribute-code). * If you or the maintainers don't respond to an issue for 30 days, the [issue will be closed](#clean-up-issues-and-prs). If you want to come back to it, reply (once, please), and we'll reopen the existing issue. Please avoid filing new issues as extensions of one you already made. * `critical` issues may be left open, depending on perceived immediacy and severity, even past the 30 day deadline. ## Request a Feature If the project doesn't do something you need or want it to do: * Open an Issue at https://github.com/zkat/cacache/issues * Provide as much context as you can about what you're running into. * Please try and be clear about why existing features and alternatives would not work for you. Once it's filed: * The project team will [label the issue](#label-issues). * The project team will evaluate the feature request, possibly asking you more questions to understand its purpose and any relevant requirements. If the issue is closed, the team will convey their reasoning and suggest an alternative path forward. * If the feature request is accepted, it will be marked for implementation with `feature-accepted`, which can then be done by either by a core team member or by anyone in the community who wants to [contribute code](#contribute-code). Note: The team is unlikely to be able to accept every single feature request that is filed. Please understand if they need to say no. ## Project Setup So you wanna contribute some code! That's great! This project uses GitHub Pull Requests to manage contributions, so [read up on how to fork a GitHub project and file a PR](https://guides.github.com/activities/forking) if you've never done it before. If this seems like a lot or you aren't able to do all this setup, you might also be able to [edit the files directly](https://help.github.com/articles/editing-files-in-another-user-s-repository/) without having to do any of this setup. Yes, [even code](#contribute-code). If you want to go the usual route and run the project locally, though: * [Install Node.js](https://nodejs.org/en/download/) * [Fork the project](https://guides.github.com/activities/forking/#fork) Then in your terminal: * `cd path/to/your/clone` * `npm install` * `npm test` And you should be ready to go! ## Contribute Documentation Documentation is a super important, critical part of this project. Docs are how we keep track of what we're doing, how, and why. It's how we stay on the same page about our policies. And it's how we tell others everything they need in order to be able to use this project -- or contribute to it. So thank you in advance. Documentation contributions of any size are welcome! Feel free to file a PR even if you're just rewording a sentence to be more clear, or fixing a spelling mistake! To contribute documentation: * [Set up the project](#project-setup). * Edit or add any relevant documentation. * Make sure your changes are formatted correctly and consistently with the rest of the documentation. * Re-read what you wrote, and run a spellchecker on it to make sure you didn't miss anything. * In your commit message(s), begin the first line with `docs: `. For example: `docs: Adding a doc contrib section to CONTRIBUTING.md`. * Write clear, concise commit message(s) using [conventional-changelog format](https://github.com/conventional-changelog/conventional-changelog-angular/blob/master/convention.md). Documentation commits should use `docs(): `. * Go to https://github.com/zkat/cacache/pulls and open a new pull request with your changes. * If your PR is connected to an open issue, add a line in your PR's description that says `Fixes: #123`, where `#123` is the number of the issue you're fixing. Once you've filed the PR: * One or more maintainers will use GitHub's review feature to review your PR. * If the maintainer asks for any changes, edit your changes, push, and ask for another review. * If the maintainer decides to pass on your PR, they will thank you for the contribution and explain why they won't be accepting the changes. That's ok! We still really appreciate you taking the time to do it, and we don't take that lightly. 💚 * If your PR gets accepted, it will be marked as such, and merged into the `latest` branch soon after. Your contribution will be distributed to the masses next time the maintainers [tag a release](#tag-a-release) ## Contribute Code We like code commits a lot! They're super handy, and they keep the project going and doing the work it needs to do to be useful to others. Code contributions of just about any size are acceptable! The main difference between code contributions and documentation contributions is that contributing code requires inclusion of relevant tests for the code being added or changed. Contributions without accompanying tests will be held off until a test is added, unless the maintainers consider the specific tests to be either impossible, or way too much of a burden for such a contribution. To contribute code: * [Set up the project](#project-setup). * Make any necessary changes to the source code. * Include any [additional documentation](#contribute-documentation) the changes might need. * Write tests that verify that your contribution works as expected. * Write clear, concise commit message(s) using [conventional-changelog format](https://github.com/conventional-changelog/conventional-changelog-angular/blob/master/convention.md). * Dependency updates, additions, or removals must be in individual commits, and the message must use the format: `(deps): PKG@VERSION`, where `` is any of the usual `conventional-changelog` prefixes, at your discretion. * Go to https://github.com/zkat/cacache/pulls and open a new pull request with your changes. * If your PR is connected to an open issue, add a line in your PR's description that says `Fixes: #123`, where `#123` is the number of the issue you're fixing. Once you've filed the PR: * Barring special circumstances, maintainers will not review PRs until all checks pass (Travis, AppVeyor, etc). * One or more maintainers will use GitHub's review feature to review your PR. * If the maintainer asks for any changes, edit your changes, push, and ask for another review. Additional tags (such as `needs-tests`) will be added depending on the review. * If the maintainer decides to pass on your PR, they will thank you for the contribution and explain why they won't be accepting the changes. That's ok! We still really appreciate you taking the time to do it, and we don't take that lightly. 💚 * If your PR gets accepted, it will be marked as such, and merged into the `latest` branch soon after. Your contribution will be distributed to the masses next time the maintainers [tag a release](#tag-a-release) ## Provide Support on Issues [Needs Collaborator](#join-the-project-team): none Helping out other users with their questions is a really awesome way of contributing to any community. It's not uncommon for most of the issues on an open source projects being support-related questions by users trying to understand something they ran into, or find their way around a known bug. Sometimes, the `support` label will be added to things that turn out to actually be other things, like bugs or feature requests. In that case, suss out the details with the person who filed the original issue, add a comment explaining what the bug is, and change the label from `support` to `bug` or `feature`. If you can't do this yourself, @mention a maintainer so they can do it. In order to help other folks out with their questions: * Go to the issue tracker and [filter open issues by the `support` label](https://github.com/zkat/cacache/issues?q=is%3Aopen+is%3Aissue+label%3Asupport). * Read through the list until you find something that you're familiar enough with to give an answer to. * Respond to the issue with whatever details are needed to clarify the question, or get more details about what's going on. * Once the discussion wraps up and things are clarified, either close the issue, or ask the original issue filer (or a maintainer) to close it for you. Some notes on picking up support issues: * Avoid responding to issues you don't know you can answer accurately. * As much as possible, try to refer to past issues with accepted answers. Link to them from your replies with the `#123` format. * Be kind and patient with users -- often, folks who have run into confusing things might be upset or impatient. This is ok. Try to understand where they're coming from, and if you're too uncomfortable with the tone, feel free to stay away or withdraw from the issue. (note: if the user is outright hostile or is violating the CoC, [refer to the Code of Conduct](CODE_OF_CONDUCT.md) to resolve the conflict). ## Label Issues [Needs Collaborator](#join-the-project-team): Issue Tracker One of the most important tasks in handling issues is labeling them usefully and accurately. All other tasks involving issues ultimately rely on the issue being classified in such a way that relevant parties looking to do their own tasks can find them quickly and easily. In order to label issues, [open up the list of unlabeled issues](https://github.com/zkat/cacache/issues?q=is%3Aopen+is%3Aissue+no%3Alabel) and, **from newest to oldest**, read through each one and apply issue labels according to the table below. If you're unsure about what label to apply, skip the issue and try the next one: don't feel obligated to label each and every issue yourself! Label | Apply When | Notes --- | --- | --- `bug` | Cases where the code (or documentation) is behaving in a way it wasn't intended to. | If something is happening that surprises the *user* but does not go against the way the code is designed, it should use the `enhancement` label. `critical` | Added to `bug` issues if the problem described makes the code completely unusable in a common situation. | `documentation` | Added to issues or pull requests that affect any of the documentation for the project. | Can be combined with other labels, such as `bug` or `enhancement`. `duplicate` | Added to issues or PRs that refer to the exact same issue as another one that's been previously labeled. | Duplicate issues should be marked and closed right away, with a message referencing the issue it's a duplicate of (with `#123`) `enhancement` | Added to [feature requests](#request-a-feature), PRs, or documentation issues that are purely additive: the code or docs currently work as expected, but a change is being requested or suggested. | `help wanted` | Applied by [Committers](#join-the-project-team) to issues and PRs that they would like to get outside help for. Generally, this means it's lower priority for the maintainer team to itself implement, but that the community is encouraged to pick up if they so desire | Never applied on first-pass labeling. `in-progress` | Applied by [Committers](#join-the-project-team) to PRs that are pending some work before they're ready for review. | The original PR submitter should @mention the team member that applied the label once the PR is complete. `performance` | This issue or PR is directly related to improving performance. | `refactor` | Added to issues or PRs that deal with cleaning up or modifying the project for the betterment of it. | `starter` | Applied by [Committers](#join-the-project-team) to issues that they consider good introductions to the project for people who have not contributed before. These are not necessarily "easy", but rather focused around how much context is necessary in order to understand what needs to be done for this project in particular. | Existing project members are expected to stay away from these unless they increase in priority. `support` | This issue is either asking a question about how to use the project, clarifying the reason for unexpected behavior, or possibly reporting a `bug` but does not have enough detail yet to determine whether it would count as such. | The label should be switched to `bug` if reliable reproduction steps are provided. Issues primarily with unintended configurations of a user's environment are not considered bugs, even if they cause crashes. `tests` | This issue or PR either requests or adds primarily tests to the project. | If a PR is pending tests, that will be handled through the [PR review process](#review-pull-requests) `wontfix` | Labelers may apply this label to issues that clearly have nothing at all to do with the project or are otherwise entirely outside of its scope/sphere of influence. [Committers](#join-the-project-team) may apply this label and close an issue or PR if they decide to pass on an otherwise relevant issue. | The issue or PR should be closed as soon as the label is applied, and a clear explanation provided of why the label was used. Contributors are free to contest the labeling, but the decision ultimately falls on committers as to whether to accept something or not. ## Clean Up Issues and PRs [Needs Collaborator](#join-the-project-team): Issue Tracker Issues and PRs can go stale after a while. Maybe they're abandoned. Maybe the team will just plain not have time to address them any time soon. In these cases, they should be closed until they're brought up again or the interaction starts over. To clean up issues and PRs: * Search the issue tracker for issues or PRs, and add the term `updated:<=YYYY-MM-DD`, where the date is 30 days before today. * Go through each issue *from oldest to newest*, and close them if **all of the following are true**: * not opened by a maintainer * not marked as `critical` * not marked as `starter` or `help wanted` (these might stick around for a while, in general, as they're intended to be available) * no explicit messages in the comments asking for it to be left open * does not belong to a milestone * Leave a message when closing saying "Cleaning up stale issue. Please reopen or ping us if and when you're ready to resume this. See https://github.com/zkat/cacache/blob/latest/CONTRIBUTING.md#clean-up-issues-and-prs for more details." ## Review Pull Requests [Needs Collaborator](#join-the-project-team): Issue Tracker While anyone can comment on a PR, add feedback, etc, PRs are only *approved* by team members with Issue Tracker or higher permissions. PR reviews use [GitHub's own review feature](https://help.github.com/articles/about-pull-request-reviews/), which manages comments, approval, and review iteration. Some notes: * You may ask for minor changes ("nitpicks"), but consider whether they are really blockers to merging: try to err on the side of "approve, with comments". * *ALL PULL REQUESTS* should be covered by a test: either by a previously-failing test, an existing test that covers the entire functionality of the submitted code, or new tests to verify any new/changed behavior. All tests must also pass and follow established conventions. Test coverage should not drop, unless the specific case is considered reasonable by maintainers. * Please make sure you're familiar with the code or documentation being updated, unless it's a minor change (spellchecking, minor formatting, etc). You may @mention another project member who you think is better suited for the review, but still provide a non-approving review of your own. * Be extra kind: people who submit code/doc contributions are putting themselves in a pretty vulnerable position, and have put time and care into what they've done (even if that's not obvious to you!) -- always respond with respect, be understanding, but don't feel like you need to sacrifice your standards for their sake, either. Just don't be a jerk about it? ## Merge Pull Requests [Needs Collaborator](#join-the-project-team): Committer TBD - need to hash out a bit more of this process. ## Tag A Release [Needs Collaborator](#join-the-project-team): Committer TBD - need to hash out a bit more of this process. The most important bit here is probably that all tests must pass, and tags must use [semver](https://semver.org). ## Join the Project Team ### Ways to Join There are many ways to contribute! Most of them don't require any official status unless otherwise noted. That said, there's a couple of positions that grant special repository abilities, and this section describes how they're granted and what they do. All of the below positions are granted based on the project team's needs, as well as their consensus opinion about whether they would like to work with the person and think that they would fit well into that position. The process is relatively informal, and it's likely that people who express interest in participating can just be granted the permissions they'd like. You can spot a collaborator on the repo by looking for the `[Collaborator]` or `[Owner]` tags next to their names. Permission | Description --- | --- Issue Tracker | Granted to contributors who express a strong interest in spending time on the project's issue tracker. These tasks are mainly [labeling issues](#label-issues), [cleaning up old ones](#clean-up-issues-and-prs), and [reviewing pull requests](#review-pull-requests), as well as all the usual things non-team-member contributors can do. Issue handlers should not merge pull requests, tag releases, or directly commit code themselves: that should still be done through the usual pull request process. Becoming an Issue Handler means the project team trusts you to understand enough of the team's process and context to implement it on the issue tracker. Committer | Granted to contributors who want to handle the actual pull request merges, tagging new versions, etc. Committers should have a good level of familiarity with the codebase, and enough context to understand the implications of various changes, as well as a good sense of the will and expectations of the project team. Admin/Owner | Granted to people ultimately responsible for the project, its community, etc. ## Attribution This guide was generated using the WeAllJS `CONTRIBUTING.md` generator. [Make your own](https://npm.im/weallcontribute)! cacache-11.3.3/ISSUE_TEMPLATE000066400000000000000000000002731350173612200152560ustar00rootroot00000000000000 cacache-11.3.3/LICENSE.md000066400000000000000000000013631350173612200145550ustar00rootroot00000000000000ISC License Copyright (c) npm, Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. cacache-11.3.3/PULL_REQUEST_TEMPLATE000066400000000000000000000002671350173612200163550ustar00rootroot00000000000000 cacache-11.3.3/README.es.md000066400000000000000000000507511350173612200150430ustar00rootroot00000000000000# cacache [![npm version](https://img.shields.io/npm/v/cacache.svg)](https://npm.im/cacache) [![license](https://img.shields.io/npm/l/cacache.svg)](https://npm.im/cacache) [![Travis](https://img.shields.io/travis/zkat/cacache.svg)](https://travis-ci.org/zkat/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/zkat/cacache?svg=true)](https://ci.appveyor.com/project/zkat/cacache) [![Coverage Status](https://coveralls.io/repos/github/zkat/cacache/badge.svg?branch=latest)](https://coveralls.io/github/zkat/cacache?branch=latest) [`cacache`](https://github.com/zkat/cacache) es una librería de Node.js para manejar caches locales en disco, con acceso tanto con claves únicas como direcciones de contenido (hashes/hacheos). Es súper rápida, excelente con el acceso concurrente, y jamás te dará datos incorrectos, aún si se corrompen o manipulan directamente los ficheros del cache. El propósito original era reemplazar el caché local de [npm](https://npm.im/npm), pero se puede usar por su propia cuenta. _Traducciones: [English](README.md)_ ## Instalación `$ npm install --save cacache` ## Índice * [Ejemplo](#ejemplo) * [Características](#características) * [Cómo Contribuir](#cómo-contribuir) * [API](#api) * [Usando el API en español](#localized-api) * Leer * [`ls`](#ls) * [`ls.flujo`](#ls-stream) * [`saca`](#get-data) * [`saca.flujo`](#get-stream) * [`saca.info`](#get-info) * [`saca.tieneDatos`](#get-hasContent) * Escribir * [`mete`](#put-data) * [`mete.flujo`](#put-stream) * [opciones para `mete*`](#put-options) * [`rm.todo`](#rm-all) * [`rm.entrada`](#rm-entry) * [`rm.datos`](#rm-content) * Utilidades * [`ponLenguaje`](#set-locale) * [`limpiaMemoizado`](#clear-memoized) * [`tmp.hazdir`](#tmp-mkdir) * [`tmp.conTmp`](#with-tmp) * Integridad * [Subresource Integrity](#integrity) * [`verifica`](#verify) * [`verifica.ultimaVez`](#verify-last-run) ### Ejemplo ```javascript const cacache = require('cacache/es') const fs = require('fs') const tarbol = '/ruta/a/mi-tar.tgz' const rutaCache = '/tmp/my-toy-cache' const clave = 'mi-clave-única-1234' // ¡Añádelo al caché! Usa `rutaCache` como raíz del caché. cacache.mete(rutaCache, clave, '10293801983029384').then(integrity => { console.log(`Saved content to ${rutaCache}.`) }) const destino = '/tmp/mytar.tgz' // Copia el contenido del caché a otro fichero, pero esta vez con flujos. cacache.saca.flujo( rutaCache, clave ).pipe( fs.createWriteStream(destino) ).on('finish', () => { console.log('extracción completada') }) // La misma cosa, pero accesando el contenido directamente, sin tocar el índice. cacache.saca.porHacheo(rutaCache, integridad).then(datos => { fs.writeFile(destino, datos, err => { console.log('datos del tarbol sacados basado en su sha512, y escrito a otro fichero') }) }) ``` ### Características * Extracción por clave o por dirección de contenido (shasum, etc) * Usa el estándard de web, [Subresource Integrity](#integrity) * Compatible con multiples algoritmos - usa sha1, sha512, etc, en el mismo caché sin problema * Entradas con contenido idéntico comparten ficheros * Tolerancia de fallas (inmune a corrupción, ficheros parciales, carreras de proceso, etc) * Verificación completa de datos cuando (escribiendo y leyendo) * Concurrencia rápida, segura y "lockless" * Compatible con `stream`s (flujos) * Compatible con `Promise`s (promesas) * Bastante rápida -- acceso, incluyendo verificación, en microsegundos * Almacenaje de metadatos arbitrarios * Colección de basura y verificación adicional fuera de banda * Cobertura rigurosa de pruebas * Probablente hay un "Bloom filter" por ahí en algún lado. Eso le mola a la gente, ¿Verdad? 🤔 ### Cómo Contribuir El equipo de cacache felizmente acepta contribuciones de código y otras maneras de participación. ¡Hay muchas formas diferentes de contribuir! La [Guía de Colaboradores](CONTRIBUTING.md) (en inglés) tiene toda la información que necesitas para cualquier tipo de contribución: todo desde cómo reportar errores hasta cómo someter parches con nuevas características. Con todo y eso, no se preocupe por si lo que haces está exáctamente correcto: no hay ningún problema en hacer preguntas si algo no está claro, o no lo encuentras. El equipo de cacache tiene miembros hispanohablantes: es completamente aceptable crear `issues` y `pull requests` en español/castellano. Todos los participantes en este proyecto deben obedecer el [Código de Conducta](CODE_OF_CONDUCT.md) (en inglés), y en general actuar de forma amable y respetuosa mientras participan en esta comunidad. Por favor refiérase al [Historial de Cambios](CHANGELOG.md) (en inglés) para detalles sobre cambios importantes incluídos en cada versión. Finalmente, cacache tiene un sistema de localización de lenguaje. Si te interesa añadir lenguajes o mejorar los que existen, mira en el directorio `./locales` para comenzar. Happy hacking! ### API #### Usando el API en español cacache incluye una traducción completa de su API al castellano, con las mismas características. Para usar el API como está documentado en este documento, usa `require('cacache/es')` cacache también tiene otros lenguajes: encuéntralos bajo `./locales`, y podrás usar el API en ese lenguaje con `require('cacache/')` #### `> cacache.ls(cache) -> Promise` Enumera todas las entradas en el caché, dentro de un solo objeto. Cada entrada en el objeto tendrá como clave la clave única usada para el índice, el valor siendo un objeto de [`saca.info`](#get-info). ##### Ejemplo ```javascript cacache.ls(rutaCache).then(console.log) // Salida { 'my-thing': { key: 'my-thing', integrity: 'sha512-BaSe64/EnCoDED+HAsh==' path: '.testcache/content/deadbeef', // unido con `rutaCache` time: 12345698490, size: 4023948, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } }, 'other-thing': { key: 'other-thing', integrity: 'sha1-ANothER+hasH=', path: '.testcache/content/bada55', time: 11992309289, size: 111112 } } ``` #### `> cacache.ls.flujo(cache) -> Readable` Enumera todas las entradas en el caché, emitiendo un objeto de [`saca.info`](#get-info) por cada evento de `data` en el flujo. ##### Ejemplo ```javascript cacache.ls.flujo(rutaCache).on('data', console.log) // Salida { key: 'my-thing', integrity: 'sha512-BaSe64HaSh', path: '.testcache/content/deadbeef', // unido con `rutaCache` time: 12345698490, size: 13423, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } } { key: 'other-thing', integrity: 'whirlpool-WoWSoMuchSupport', path: '.testcache/content/bada55', time: 11992309289, size: 498023984029 } { ... } ``` #### `> cacache.saca(cache, clave, [ops]) -> Promise({data, metadata, integrity})` Devuelve un objeto con los datos, hacheo de integridad y metadatos identificados por la `clave`. La propiedad `data` de este objeto será una instancia de `Buffer` con los datos almacenados en el caché. to do with it! cacache just won't care. `integrity` es un `string` de [Subresource Integrity](#integrity). Dígase, un `string` que puede ser usado para verificar a la `data`, que tiene como formato `-`. So no existe ninguna entrada identificada por `clave`, o se los datos almacenados localmente fallan verificación, el `Promise` fallará. Una sub-función, `saca.porHacheo`, tiene casi el mismo comportamiento, excepto que busca entradas usando el hacheo de integridad, sin tocar el índice general. Esta versión *sólo* devuelve `data`, sin ningún objeto conteniéndola. ##### Nota Esta función lee la entrada completa a la memoria antes de devolverla. Si estás almacenando datos Muy Grandes, es posible que [`saca.flujo`](#get-stream) sea una mejor solución. ##### Ejemplo ```javascript // Busca por clave cache.saca(rutaCache, 'my-thing').then(console.log) // Salida: { metadata: { thingName: 'my' }, integrity: 'sha512-BaSe64HaSh', data: Buffer#, size: 9320 } // Busca por hacheo cache.saca.porHacheo(rutaCache, 'sha512-BaSe64HaSh').then(console.log) // Salida: Buffer# ``` #### `> cacache.saca.flujo(cache, clave, [ops]) -> Readable` Devuelve un [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams) de los datos almacenados bajo `clave`. So no existe ninguna entrada identificada por `clave`, o se los datos almacenados localmente fallan verificación, el `Promise` fallará. `metadata` y `integrity` serán emitidos como eventos antes de que el flujo cierre. Una sub-función, `saca.flujo.porHacheo`, tiene casi el mismo comportamiento, excepto que busca entradas usando el hacheo de integridad, sin tocar el índice general. Esta versión no emite eventos de `metadata` o `integrity`. ##### Ejemplo ```javascript // Busca por clave cache.saca.flujo( rutaCache, 'my-thing' ).on('metadata', metadata => { console.log('metadata:', metadata) }).on('integrity', integrity => { console.log('integrity:', integrity) }).pipe( fs.createWriteStream('./x.tgz') ) // Salidas: metadata: { ... } integrity: 'sha512-SoMeDIGest+64==' // Busca por hacheo cache.saca.flujo.porHacheo( rutaCache, 'sha512-SoMeDIGest+64==' ).pipe( fs.createWriteStream('./x.tgz') ) ``` #### `> cacache.saca.info(cache, clave) -> Promise` Busca la `clave` en el índice del caché, devolviendo información sobre la entrada si existe. ##### Campos * `key` - Clave de la entrada. Igual al argumento `clave`. * `integrity` - [hacheo de Subresource Integrity](#integrity) del contenido al que se refiere esta entrada. * `path` - Dirección del fichero de datos almacenados, unida al argumento `cache`. * `time` - Hora de creación de la entrada * `metadata` - Metadatos asignados a esta entrada por el usuario ##### Ejemplo ```javascript cacache.saca.info(rutaCache, 'my-thing').then(console.log) // Salida { key: 'my-thing', integrity: 'sha256-MUSTVERIFY+ALL/THINGS==' path: '.testcache/content/deadbeef', time: 12345698490, size: 849234, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } } ``` #### `> cacache.saca.tieneDatos(cache, integrity) -> Promise` Busca un [hacheo Subresource Integrity](#integrity) en el caché. Si existe el contenido asociado con `integrity`, devuelve un objeto con dos campos: el hacheo _específico_ que se usó para la búsqueda, `sri`, y el tamaño total del contenido, `size`. Si no existe ningún contenido asociado con `integrity`, devuelve `false`. ##### Ejemplo ```javascript cacache.saca.tieneDatos(rutaCache, 'sha256-MUSTVERIFY+ALL/THINGS==').then(console.log) // Salida { sri: { source: 'sha256-MUSTVERIFY+ALL/THINGS==', algorithm: 'sha256', digest: 'MUSTVERIFY+ALL/THINGS==', options: [] }, size: 9001 } cacache.saca.tieneDatos(rutaCache, 'sha521-NOT+IN/CACHE==').then(console.log) // Salida false ``` #### `> cacache.mete(cache, clave, datos, [ops]) -> Promise` Inserta `datos` en el caché. El `Promise` devuelto se resuelve con un hacheo (generado conforme a [`ops.algorithms`](#optsalgorithms)) después que la entrada haya sido escrita en completo. ##### Ejemplo ```javascript fetch( 'https://registry.npmjs.org/cacache/-/cacache-1.0.0.tgz' ).then(datos => { return cacache.mete(rutaCache, 'registry.npmjs.org|cacache@1.0.0', datos) }).then(integridad => { console.log('el hacheo de integridad es', integridad) }) ``` #### `> cacache.mete.flujo(cache, clave, [ops]) -> Writable` Devuelve un [Writable Stream](https://nodejs.org/api/stream.html#stream_writable_streams) que inserta al caché los datos escritos a él. Emite un evento `integrity` con el hacheo del contenido escrito, cuando completa. ##### Ejemplo ```javascript request.get( 'https://registry.npmjs.org/cacache/-/cacache-1.0.0.tgz' ).pipe( cacache.mete.flujo( rutaCache, 'registry.npmjs.org|cacache@1.0.0' ).on('integrity', d => console.log(`integrity digest is ${d}`)) ) ``` #### `> opciones para cacache.mete` La funciones `cacache.mete` tienen un número de opciones en común. ##### `ops.metadata` Metadatos del usuario que se almacenarán con la entrada. ##### `ops.size` El tamaño declarado de los datos que se van a insertar. Si es proveído, cacache verificará que los datos escritos sean de ese tamaño, o si no, fallará con un error con código `EBADSIZE`. ##### `ops.integrity` El hacheo de integridad de los datos siendo escritos. Si es proveído, y los datos escritos no le corresponden, la operación fallará con un error con código `EINTEGRITY`. `ops.algorithms` no tiene ningún efecto si esta opción está presente. ##### `ops.algorithms` Por Defecto: `['sha512']` Algoritmos que se deben usar cuando se calcule el hacheo de [subresource integrity](#integrity) para los datos insertados. Puede usar cualquier algoritmo enumerado en `crypto.getHashes()`. Por el momento, sólo se acepta un algoritmo (dígase, un array con exáctamente un valor). No tiene ningún efecto si `ops.integrity` también ha sido proveido. ##### `ops.uid`/`ops.gid` Si están presentes, cacache hará todo lo posible para asegurarse que todos los ficheros creados en el proceso de sus operaciones en el caché usen esta combinación en particular. ##### `ops.memoize` Por Defecto: `null` Si es verdad, cacache tratará de memoizar los datos de la entrada en memoria. La próxima vez que el proceso corriente trate de accesar los datos o entrada, cacache buscará en memoria antes de buscar en disco. Si `ops.memoize` es un objeto regular o un objeto como `Map` (es decir, un objeto con métodos `get()` y `set()`), este objeto en sí sera usado en vez del caché de memoria global. Esto permite tener lógica específica a tu aplicación encuanto al almacenaje en memoria de tus datos. Si quieres asegurarte que los datos se lean del disco en vez de memoria, usa `memoize: false` cuando uses funciones de `cacache.saca`. #### `> cacache.rm.todo(cache) -> Promise` Borra el caché completo, incluyendo ficheros temporeros, ficheros de datos, y el índice del caché. ##### Ejemplo ```javascript cacache.rm.todo(rutaCache).then(() => { console.log('THE APOCALYPSE IS UPON US 😱') }) ``` #### `> cacache.rm.entrada(cache, clave) -> Promise` Alias: `cacache.rm` Borra la entrada `clave` del índuce. El contenido asociado con esta entrada seguirá siendo accesible por hacheo usando [`saca.flujo.porHacheo`](#get-stream). Para borrar el contenido en sí, usa [`rm.datos`](#rm-content). Si quieres hacer esto de manera más segura (pues ficheros de contenido pueden ser usados por multiples entradas), usa [`verifica`](#verify) para borrar huérfanos. ##### Ejemplo ```javascript cacache.rm.entrada(rutaCache, 'my-thing').then(() => { console.log('I did not like it anyway') }) ``` #### `> cacache.rm.datos(cache, integrity) -> Promise` Borra el contenido identificado por `integrity`. Cualquier entrada que se refiera a este contenido quedarán huérfanas y se invalidarán si se tratan de accesar, al menos que contenido idéntico sea añadido bajo `integrity`. ##### Ejemplo ```javascript cacache.rm.datos(rutaCache, 'sha512-SoMeDIGest/IN+BaSE64==').then(() => { console.log('los datos para `mi-cosa` se borraron') }) ``` #### `> cacache.ponLenguaje(locale)` Configura el lenguaje usado para mensajes y errores de cacache. La lista de lenguajes disponibles está en el directorio `./locales` del proyecto. _Te interesa añadir más lenguajes? [Somete un PR](CONTRIBUTING.md)!_ #### `> cacache.limpiaMemoizado()` Completamente reinicializa el caché de memoria interno. Si estás usando tu propio objecto con `ops.memoize`, debes hacer esto de manera específica a él. #### `> tmp.hazdir(cache, ops) -> Promise` Alias: `tmp.mkdir` Devuelve un directorio único dentro del directorio `tmp` del caché. Una vez tengas el directorio, es responsabilidad tuya asegurarte que todos los ficheros escrito a él sean creados usando los permisos y `uid`/`gid` concordante con el caché. Si no, puedes pedirle a cacache que lo haga llamando a [`cacache.tmp.fix()`](#tmp-fix). Esta función arreglará todos los permisos en el directorio tmp. Si quieres que cacache limpie el directorio automáticamente cuando termines, usa [`cacache.tmp.conTmp()`](#with-tpm). ##### Ejemplo ```javascript cacache.tmp.mkdir(cache).then(dir => { fs.writeFile(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }) ``` #### `> tmp.conTmp(cache, ops, cb) -> Promise` Crea un directorio temporero con [`tmp.mkdir()`](#tmp-mkdir) y ejecuta `cb` con él como primer argumento. El directorio creado será removido automáticamente cuando el valor devolvido por `cb()` se resuelva. Las mismas advertencias aplican en cuanto a manejando permisos para los ficheros dentro del directorio. ##### Ejemplo ```javascript cacache.tmp.conTmp(cache, dir => { return fs.writeFileAsync(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }).then(() => { // `dir` no longer exists }) ``` #### Hacheos de Subresource Integrity cacache usa strings que siguen la especificación de [Subresource Integrity spec](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity). Es decir, donde quiera cacache espera un argumento o opción `integrity`, ese string debería usar el formato `-`. Una variación importante sobre los hacheos que cacache acepta es que acepta el nombre de cualquier algoritmo aceptado por el proceso de Node.js donde se usa. Puedes usar `crypto.getHashes()` para ver cuales están disponibles. ##### Generando tus propios hacheos Si tienes un `shasum`, en general va a estar en formato de string hexadecimal (es decir, un `sha1` se vería como algo así: `5f5513f8822fdbe5145af33b64d8d970dcf95c6e`). Para ser compatible con cacache, necesitas convertir esto a su equivalente en subresource integrity. Por ejemplo, el hacheo correspondiente al ejemplo anterior sería: `sha1-X1UT+IIv2+UUWvM7ZNjZcNz5XG4=`. Puedes usar código así para generarlo por tu cuenta: ```javascript const crypto = require('crypto') const algoritmo = 'sha512' const datos = 'foobarbaz' const integrity = ( algorithm + '-' + crypto.createHash(algoritmo).update(datos).digest('base64') ) ``` También puedes usar [`ssri`](https://npm.im/ssri) para deferir el trabajo a otra librería que garantiza que todo esté correcto, pues maneja probablemente todas las operaciones que tendrías que hacer con SRIs, incluyendo convirtiendo entre hexadecimal y el formato SRI. #### `> cacache.verifica(cache, ops) -> Promise` Examina y arregla tu caché: * Limpia entradas inválidas, huérfanas y corrompidas * Te deja filtrar cuales entradas retener, con tu propio filtro * Reclama cualquier ficheros de contenido sin referencias en el índice * Verifica integridad de todos los ficheros de contenido y remueve los malos * Arregla permisos del caché * Remieve el directorio `tmp` en el caché, y todo su contenido. Cuando termine, devuelve un objeto con varias estadísticas sobre el proceso de verificación, por ejemplo la cantidad de espacio de disco reclamado, el número de entradas válidas, número de entradas removidas, etc. ##### Opciones * `ops.uid` - uid para asignarle al caché y su contenido * `ops.gid` - gid para asignarle al caché y su contenido * `ops.filter` - recibe una entrada como argumento. Devuelve falso para removerla. Nota: es posible que esta función sea invocada con la misma entrada más de una vez. ##### Example ```sh echo somegarbage >> $RUTACACHE/content/deadbeef ``` ```javascript cacache.verifica(rutaCache).then(stats => { // deadbeef collected, because of invalid checksum. console.log('cache is much nicer now! stats:', stats) }) ``` #### `> cacache.verifica.ultimaVez(cache) -> Promise` Alias: `últimaVez` Devuelve un `Date` que representa la última vez que `cacache.verifica` fue ejecutada en `cache`. ##### Example ```javascript cacache.verifica(rutaCache).then(() => { cacache.verifica.ultimaVez(rutaCache).then(última => { console.log('La última vez que se usó cacache.verifica() fue ' + última) }) }) ``` cacache-11.3.3/README.md000066400000000000000000000473071350173612200144400ustar00rootroot00000000000000# cacache [![npm version](https://img.shields.io/npm/v/cacache.svg)](https://npm.im/cacache) [![license](https://img.shields.io/npm/l/cacache.svg)](https://npm.im/cacache) [![Travis](https://img.shields.io/travis/zkat/cacache.svg)](https://travis-ci.org/zkat/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/zkat/cacache?svg=true)](https://ci.appveyor.com/project/zkat/cacache) [![Coverage Status](https://coveralls.io/repos/github/zkat/cacache/badge.svg?branch=latest)](https://coveralls.io/github/zkat/cacache?branch=latest) [`cacache`](https://github.com/zkat/cacache) is a Node.js library for managing local key and content address caches. It's really fast, really good at concurrency, and it will never give you corrupted data, even if cache files get corrupted or manipulated. It was originally written to be used as [npm](https://npm.im)'s local cache, but can just as easily be used on its own. _Translations: [español](README.es.md)_ ## Install `$ npm install --save cacache` ## Table of Contents * [Example](#example) * [Features](#features) * [Contributing](#contributing) * [API](#api) * [Using localized APIs](#localized-api) * Reading * [`ls`](#ls) * [`ls.stream`](#ls-stream) * [`get`](#get-data) * [`get.stream`](#get-stream) * [`get.info`](#get-info) * [`get.hasContent`](#get-hasContent) * Writing * [`put`](#put-data) * [`put.stream`](#put-stream) * [`put*` opts](#put-options) * [`rm.all`](#rm-all) * [`rm.entry`](#rm-entry) * [`rm.content`](#rm-content) * Utilities * [`setLocale`](#set-locale) * [`clearMemoized`](#clear-memoized) * [`tmp.mkdir`](#tmp-mkdir) * [`tmp.withTmp`](#with-tmp) * Integrity * [Subresource Integrity](#integrity) * [`verify`](#verify) * [`verify.lastRun`](#verify-last-run) ### Example ```javascript const cacache = require('cacache/en') const fs = require('fs') const tarball = '/path/to/mytar.tgz' const cachePath = '/tmp/my-toy-cache' const key = 'my-unique-key-1234' // Cache it! Use `cachePath` as the root of the content cache cacache.put(cachePath, key, '10293801983029384').then(integrity => { console.log(`Saved content to ${cachePath}.`) }) const destination = '/tmp/mytar.tgz' // Copy the contents out of the cache and into their destination! // But this time, use stream instead! cacache.get.stream( cachePath, key ).pipe( fs.createWriteStream(destination) ).on('finish', () => { console.log('done extracting!') }) // The same thing, but skip the key index. cacache.get.byDigest(cachePath, integrityHash).then(data => { fs.writeFile(destination, data, err => { console.log('tarball data fetched based on its sha512sum and written out!') }) }) ``` ### Features * Extraction by key or by content address (shasum, etc) * [Subresource Integrity](#integrity) web standard support * Multi-hash support - safely host sha1, sha512, etc, in a single cache * Automatic content deduplication * Fault tolerance (immune to corruption, partial writes, process races, etc) * Consistency guarantees on read and write (full data verification) * Lockless, high-concurrency cache access * Streaming support * Promise support * Pretty darn fast -- sub-millisecond reads and writes including verification * Arbitrary metadata storage * Garbage collection and additional offline verification * Thorough test coverage * There's probably a bloom filter in there somewhere. Those are cool, right? 🤔 ### Contributing The cacache team enthusiastically welcomes contributions and project participation! There's a bunch of things you can do if you want to contribute! The [Contributor Guide](CONTRIBUTING.md) has all the information you need for everything from reporting bugs to contributing entire new features. Please don't hesitate to jump in if you'd like to, or even ask us questions if something isn't clear. All participants and maintainers in this project are expected to follow [Code of Conduct](CODE_OF_CONDUCT.md), and just generally be excellent to each other. Please refer to the [Changelog](CHANGELOG.md) for project history details, too. Happy hacking! ### API #### Using localized APIs cacache includes a complete API in English, with the same features as other translations. To use the English API as documented in this README, use `require('cacache/en')`. This is also currently the default if you do `require('cacache')`, but may change in the future. cacache also supports other languages! You can find the list of currently supported ones by looking in `./locales` in the source directory. You can use the API in that language with `require('cacache/')`. Want to add support for a new language? Please go ahead! You should be able to copy `./locales/en.js` and `./locales/en.json` and fill them in. Translating the `README.md` is a bit more work, but also appreciated if you get around to it. 👍🏼 #### `> cacache.ls(cache) -> Promise` Lists info for all entries currently in the cache as a single large object. Each entry in the object will be keyed by the unique index key, with corresponding [`get.info`](#get-info) objects as the values. ##### Example ```javascript cacache.ls(cachePath).then(console.log) // Output { 'my-thing': { key: 'my-thing', integrity: 'sha512-BaSe64/EnCoDED+HAsh==' path: '.testcache/content/deadbeef', // joined with `cachePath` time: 12345698490, size: 4023948, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } }, 'other-thing': { key: 'other-thing', integrity: 'sha1-ANothER+hasH=', path: '.testcache/content/bada55', time: 11992309289, size: 111112 } } ``` #### `> cacache.ls.stream(cache) -> Readable` Lists info for all entries currently in the cache as a single large object. This works just like [`ls`](#ls), except [`get.info`](#get-info) entries are returned as `'data'` events on the returned stream. ##### Example ```javascript cacache.ls.stream(cachePath).on('data', console.log) // Output { key: 'my-thing', integrity: 'sha512-BaSe64HaSh', path: '.testcache/content/deadbeef', // joined with `cachePath` time: 12345698490, size: 13423, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } } { key: 'other-thing', integrity: 'whirlpool-WoWSoMuchSupport', path: '.testcache/content/bada55', time: 11992309289, size: 498023984029 } { ... } ``` #### `> cacache.get(cache, key, [opts]) -> Promise({data, metadata, integrity})` Returns an object with the cached data, digest, and metadata identified by `key`. The `data` property of this object will be a `Buffer` instance that presumably holds some data that means something to you. I'm sure you know what to do with it! cacache just won't care. `integrity` is a [Subresource Integrity](#integrity) string. That is, a string that can be used to verify `data`, which looks like `-`. If there is no content identified by `key`, or if the locally-stored data does not pass the validity checksum, the promise will be rejected. A sub-function, `get.byDigest` may be used for identical behavior, except lookup will happen by integrity hash, bypassing the index entirely. This version of the function *only* returns `data` itself, without any wrapper. ##### Note This function loads the entire cache entry into memory before returning it. If you're dealing with Very Large data, consider using [`get.stream`](#get-stream) instead. ##### Example ```javascript // Look up by key cache.get(cachePath, 'my-thing').then(console.log) // Output: { metadata: { thingName: 'my' }, integrity: 'sha512-BaSe64HaSh', data: Buffer#, size: 9320 } // Look up by digest cache.get.byDigest(cachePath, 'sha512-BaSe64HaSh').then(console.log) // Output: Buffer# ``` #### `> cacache.get.stream(cache, key, [opts]) -> Readable` Returns a [Readable Stream](https://nodejs.org/api/stream.html#stream_readable_streams) of the cached data identified by `key`. If there is no content identified by `key`, or if the locally-stored data does not pass the validity checksum, an error will be emitted. `metadata` and `integrity` events will be emitted before the stream closes, if you need to collect that extra data about the cached entry. A sub-function, `get.stream.byDigest` may be used for identical behavior, except lookup will happen by integrity hash, bypassing the index entirely. This version does not emit the `metadata` and `integrity` events at all. ##### Example ```javascript // Look up by key cache.get.stream( cachePath, 'my-thing' ).on('metadata', metadata => { console.log('metadata:', metadata) }).on('integrity', integrity => { console.log('integrity:', integrity) }).pipe( fs.createWriteStream('./x.tgz') ) // Outputs: metadata: { ... } integrity: 'sha512-SoMeDIGest+64==' // Look up by digest cache.get.stream.byDigest( cachePath, 'sha512-SoMeDIGest+64==' ).pipe( fs.createWriteStream('./x.tgz') ) ``` #### `> cacache.get.info(cache, key) -> Promise` Looks up `key` in the cache index, returning information about the entry if one exists. ##### Fields * `key` - Key the entry was looked up under. Matches the `key` argument. * `integrity` - [Subresource Integrity hash](#integrity) for the content this entry refers to. * `path` - Filesystem path where content is stored, joined with `cache` argument. * `time` - Timestamp the entry was first added on. * `metadata` - User-assigned metadata associated with the entry/content. ##### Example ```javascript cacache.get.info(cachePath, 'my-thing').then(console.log) // Output { key: 'my-thing', integrity: 'sha256-MUSTVERIFY+ALL/THINGS==' path: '.testcache/content/deadbeef', time: 12345698490, size: 849234, metadata: { name: 'blah', version: '1.2.3', description: 'this was once a package but now it is my-thing' } } ``` #### `> cacache.get.hasContent(cache, integrity) -> Promise` Looks up a [Subresource Integrity hash](#integrity) in the cache. If content exists for this `integrity`, it will return an object, with the specific single integrity hash that was found in `sri` key, and the size of the found content as `size`. If no content exists for this integrity, it will return `false`. ##### Example ```javascript cacache.get.hasContent(cachePath, 'sha256-MUSTVERIFY+ALL/THINGS==').then(console.log) // Output { sri: { source: 'sha256-MUSTVERIFY+ALL/THINGS==', algorithm: 'sha256', digest: 'MUSTVERIFY+ALL/THINGS==', options: [] }, size: 9001 } cacache.get.hasContent(cachePath, 'sha521-NOT+IN/CACHE==').then(console.log) // Output false ``` #### `> cacache.put(cache, key, data, [opts]) -> Promise` Inserts data passed to it into the cache. The returned Promise resolves with a digest (generated according to [`opts.algorithms`](#optsalgorithms)) after the cache entry has been successfully written. ##### Example ```javascript fetch( 'https://registry.npmjs.org/cacache/-/cacache-1.0.0.tgz' ).then(data => { return cacache.put(cachePath, 'registry.npmjs.org|cacache@1.0.0', data) }).then(integrity => { console.log('integrity hash is', integrity) }) ``` #### `> cacache.put.stream(cache, key, [opts]) -> Writable` Returns a [Writable Stream](https://nodejs.org/api/stream.html#stream_writable_streams) that inserts data written to it into the cache. Emits an `integrity` event with the digest of written contents when it succeeds. ##### Example ```javascript request.get( 'https://registry.npmjs.org/cacache/-/cacache-1.0.0.tgz' ).pipe( cacache.put.stream( cachePath, 'registry.npmjs.org|cacache@1.0.0' ).on('integrity', d => console.log(`integrity digest is ${d}`)) ) ``` #### `> cacache.put options` `cacache.put` functions have a number of options in common. ##### `opts.metadata` Arbitrary metadata to be attached to the inserted key. ##### `opts.size` If provided, the data stream will be verified to check that enough data was passed through. If there's more or less data than expected, insertion will fail with an `EBADSIZE` error. ##### `opts.integrity` If present, the pre-calculated digest for the inserted content. If this option if provided and does not match the post-insertion digest, insertion will fail with an `EINTEGRITY` error. `algorithms` has no effect if this option is present. ##### `opts.algorithms` Default: ['sha512'] Hashing algorithms to use when calculating the [subresource integrity digest](#integrity) for inserted data. Can use any algorithm listed in `crypto.getHashes()` or `'omakase'`/`'お任せします'` to pick a random hash algorithm on each insertion. You may also use any anagram of `'modnar'` to use this feature. Currently only supports one algorithm at a time (i.e., an array length of exactly `1`). Has no effect if `opts.integrity` is present. ##### `opts.uid`/`opts.gid` If provided, cacache will do its best to make sure any new files added to the cache use this particular `uid`/`gid` combination. This can be used, for example, to drop permissions when someone uses `sudo`, but cacache makes no assumptions about your needs here. ##### `opts.memoize` Default: null If provided, cacache will memoize the given cache insertion in memory, bypassing any filesystem checks for that key or digest in future cache fetches. Nothing will be written to the in-memory cache unless this option is explicitly truthy. If `opts.memoize` is an object or a `Map`-like (that is, an object with `get` and `set` methods), it will be written to instead of the global memoization cache. Reading from disk data can be forced by explicitly passing `memoize: false` to the reader functions, but their default will be to read from memory. #### `> cacache.rm.all(cache) -> Promise` Clears the entire cache. Mainly by blowing away the cache directory itself. ##### Example ```javascript cacache.rm.all(cachePath).then(() => { console.log('THE APOCALYPSE IS UPON US 😱') }) ``` #### `> cacache.rm.entry(cache, key) -> Promise` Alias: `cacache.rm` Removes the index entry for `key`. Content will still be accessible if requested directly by content address ([`get.stream.byDigest`](#get-stream)). To remove the content itself (which might still be used by other entries), use [`rm.content`](#rm-content). Or, to safely vacuum any unused content, use [`verify`](#verify). ##### Example ```javascript cacache.rm.entry(cachePath, 'my-thing').then(() => { console.log('I did not like it anyway') }) ``` #### `> cacache.rm.content(cache, integrity) -> Promise` Removes the content identified by `integrity`. Any index entries referring to it will not be usable again until the content is re-added to the cache with an identical digest. ##### Example ```javascript cacache.rm.content(cachePath, 'sha512-SoMeDIGest/IN+BaSE64==').then(() => { console.log('data for my-thing is gone!') }) ``` #### `> cacache.setLocale(locale)` Configure the language/locale used for messages and errors coming from cacache. The list of available locales is in the `./locales` directory in the project root. _Interested in contributing more languages! [Submit a PR](CONTRIBUTING.md)!_ #### `> cacache.clearMemoized()` Completely resets the in-memory entry cache. #### `> tmp.mkdir(cache, opts) -> Promise` Returns a unique temporary directory inside the cache's `tmp` dir. This directory will use the same safe user assignment that all the other stuff use. Once the directory is made, it's the user's responsibility that all files within are made according to the same `opts.gid`/`opts.uid` settings that would be passed in. If not, you can ask cacache to do it for you by calling [`tmp.fix()`](#tmp-fix), which will fix all tmp directory permissions. If you want automatic cleanup of this directory, use [`tmp.withTmp()`](#with-tpm) ##### Example ```javascript cacache.tmp.mkdir(cache).then(dir => { fs.writeFile(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }) ``` #### `> tmp.withTmp(cache, opts, cb) -> Promise` Creates a temporary directory with [`tmp.mkdir()`](#tmp-mkdir) and calls `cb` with it. The created temporary directory will be removed when the return value of `cb()` resolves -- that is, if you return a Promise from `cb()`, the tmp directory will be automatically deleted once that promise completes. The same caveats apply when it comes to managing permissions for the tmp dir's contents. ##### Example ```javascript cacache.tmp.withTmp(cache, dir => { return fs.writeFileAsync(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }).then(() => { // `dir` no longer exists }) ``` #### Subresource Integrity Digests For content verification and addressing, cacache uses strings following the [Subresource Integrity spec](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity). That is, any time cacache expects an `integrity` argument or option, it should be in the format `-`. One deviation from the current spec is that cacache will support any hash algorithms supported by the underlying Node.js process. You can use `crypto.getHashes()` to see which ones you can use. ##### Generating Digests Yourself If you have an existing content shasum, they are generally formatted as a hexadecimal string (that is, a sha1 would look like: `5f5513f8822fdbe5145af33b64d8d970dcf95c6e`). In order to be compatible with cacache, you'll need to convert this to an equivalent subresource integrity string. For this example, the corresponding hash would be: `sha1-X1UT+IIv2+UUWvM7ZNjZcNz5XG4=`. If you want to generate an integrity string yourself for existing data, you can use something like this: ```javascript const crypto = require('crypto') const hashAlgorithm = 'sha512' const data = 'foobarbaz' const integrity = ( hashAlgorithm + '-' + crypto.createHash(hashAlgorithm).update(data).digest('base64') ) ``` You can also use [`ssri`](https://npm.im/ssri) to have a richer set of functionality around SRI strings, including generation, parsing, and translating from existing hex-formatted strings. #### `> cacache.verify(cache, opts) -> Promise` Checks out and fixes up your cache: * Cleans up corrupted or invalid index entries. * Custom entry filtering options. * Garbage collects any content entries not referenced by the index. * Checks integrity for all content entries and removes invalid content. * Fixes cache ownership. * Removes the `tmp` directory in the cache and all its contents. When it's done, it'll return an object with various stats about the verification process, including amount of storage reclaimed, number of valid entries, number of entries removed, etc. ##### Options * `opts.uid` - uid to assign to cache and its contents * `opts.gid` - gid to assign to cache and its contents * `opts.filter` - receives a formatted entry. Return false to remove it. Note: might be called more than once on the same entry. ##### Example ```sh echo somegarbage >> $CACHEPATH/content/deadbeef ``` ```javascript cacache.verify(cachePath).then(stats => { // deadbeef collected, because of invalid checksum. console.log('cache is much nicer now! stats:', stats) }) ``` #### `> cacache.verify.lastRun(cache) -> Promise` Returns a `Date` representing the last time `cacache.verify` was run on `cache`. ##### Example ```javascript cacache.verify(cachePath).then(() => { cacache.verify.lastRun(cachePath).then(lastTime => { console.log('cacache.verify was last called on' + lastTime) }) }) ``` cacache-11.3.3/appveyor.yml000066400000000000000000000005411350173612200155360ustar00rootroot00000000000000environment: matrix: - nodejs_version: "10" - nodejs_version: "9" - nodejs_version: "8" - nodejs_version: "6" platform: - x64 install: - ps: Install-Product node $env:nodejs_version $env:platform - npm i -g npm@latest - npm config set spin false - npm ci test_script: - npm test matrix: fast_finish: true build: off cacache-11.3.3/en.js000066400000000000000000000000721350173612200141050ustar00rootroot00000000000000'use strict' module.exports = require('./locales/en.js') cacache-11.3.3/es.js000066400000000000000000000000721350173612200141120ustar00rootroot00000000000000'use strict' module.exports = require('./locales/es.js') cacache-11.3.3/get.js000066400000000000000000000153321350173612200142670ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const figgyPudding = require('figgy-pudding') const fs = require('fs') const index = require('./lib/entry-index') const memo = require('./lib/memoization') const pipe = require('mississippi').pipe const pipeline = require('mississippi').pipeline const read = require('./lib/content/read') const through = require('mississippi').through const GetOpts = figgyPudding({ integrity: {}, memoize: {}, size: {} }) module.exports = function get (cache, key, opts) { return getData(false, cache, key, opts) } module.exports.byDigest = function getByDigest (cache, digest, opts) { return getData(true, cache, digest, opts) } function getData (byDigest, cache, key, opts) { opts = GetOpts(opts) const memoized = ( byDigest ? memo.get.byDigest(cache, key, opts) : memo.get(cache, key, opts) ) if (memoized && opts.memoize !== false) { return BB.resolve(byDigest ? memoized : { metadata: memoized.entry.metadata, data: memoized.data, integrity: memoized.entry.integrity, size: memoized.entry.size }) } return ( byDigest ? BB.resolve(null) : index.find(cache, key, opts) ).then(entry => { if (!entry && !byDigest) { throw new index.NotFoundError(cache, key) } return read(cache, byDigest ? key : entry.integrity, { integrity: opts.integrity, size: opts.size }).then(data => byDigest ? data : { metadata: entry.metadata, data: data, size: entry.size, integrity: entry.integrity }).then(res => { if (opts.memoize && byDigest) { memo.put.byDigest(cache, key, res, opts) } else if (opts.memoize) { memo.put(cache, entry, res.data, opts) } return res }) }) } module.exports.sync = function get (cache, key, opts) { return getDataSync(false, cache, key, opts) } module.exports.sync.byDigest = function getByDigest (cache, digest, opts) { return getDataSync(true, cache, digest, opts) } function getDataSync (byDigest, cache, key, opts) { opts = GetOpts(opts) const memoized = ( byDigest ? memo.get.byDigest(cache, key, opts) : memo.get(cache, key, opts) ) if (memoized && opts.memoize !== false) { return byDigest ? memoized : { metadata: memoized.entry.metadata, data: memoized.data, integrity: memoized.entry.integrity, size: memoized.entry.size } } const entry = !byDigest && index.find.sync(cache, key, opts) if (!entry && !byDigest) { throw new index.NotFoundError(cache, key) } const data = read.sync( cache, byDigest ? key : entry.integrity, { integrity: opts.integrity, size: opts.size } ) const res = byDigest ? data : { metadata: entry.metadata, data: data, size: entry.size, integrity: entry.integrity } if (opts.memoize && byDigest) { memo.put.byDigest(cache, key, res, opts) } else if (opts.memoize) { memo.put(cache, entry, res.data, opts) } return res } module.exports.stream = getStream function getStream (cache, key, opts) { opts = GetOpts(opts) let stream = through() const memoized = memo.get(cache, key, opts) if (memoized && opts.memoize !== false) { stream.on('newListener', function (ev, cb) { ev === 'metadata' && cb(memoized.entry.metadata) ev === 'integrity' && cb(memoized.entry.integrity) ev === 'size' && cb(memoized.entry.size) }) stream.write(memoized.data, () => stream.end()) return stream } index.find(cache, key).then(entry => { if (!entry) { return stream.emit( 'error', new index.NotFoundError(cache, key) ) } let memoStream if (opts.memoize) { let memoData = [] let memoLength = 0 memoStream = through((c, en, cb) => { memoData && memoData.push(c) memoLength += c.length cb(null, c, en) }, cb => { memoData && memo.put(cache, entry, Buffer.concat(memoData, memoLength), opts) cb() }) } else { memoStream = through() } stream.emit('metadata', entry.metadata) stream.emit('integrity', entry.integrity) stream.emit('size', entry.size) stream.on('newListener', function (ev, cb) { ev === 'metadata' && cb(entry.metadata) ev === 'integrity' && cb(entry.integrity) ev === 'size' && cb(entry.size) }) pipe( read.readStream(cache, entry.integrity, opts.concat({ size: opts.size == null ? entry.size : opts.size })), memoStream, stream ) }).catch(err => stream.emit('error', err)) return stream } module.exports.stream.byDigest = getStreamDigest function getStreamDigest (cache, integrity, opts) { opts = GetOpts(opts) const memoized = memo.get.byDigest(cache, integrity, opts) if (memoized && opts.memoize !== false) { const stream = through() stream.write(memoized, () => stream.end()) return stream } else { let stream = read.readStream(cache, integrity, opts) if (opts.memoize) { let memoData = [] let memoLength = 0 const memoStream = through((c, en, cb) => { memoData && memoData.push(c) memoLength += c.length cb(null, c, en) }, cb => { memoData && memo.put.byDigest( cache, integrity, Buffer.concat(memoData, memoLength), opts ) cb() }) stream = pipeline(stream, memoStream) } return stream } } module.exports.info = info function info (cache, key, opts) { opts = GetOpts(opts) const memoized = memo.get(cache, key, opts) if (memoized && opts.memoize !== false) { return BB.resolve(memoized.entry) } else { return index.find(cache, key) } } module.exports.hasContent = read.hasContent module.exports.copy = function cp (cache, key, dest, opts) { return copy(false, cache, key, dest, opts) } module.exports.copy.byDigest = function cpDigest (cache, digest, dest, opts) { return copy(true, cache, digest, dest, opts) } function copy (byDigest, cache, key, dest, opts) { opts = GetOpts(opts) if (read.copy) { return ( byDigest ? BB.resolve(null) : index.find(cache, key, opts) ).then(entry => { if (!entry && !byDigest) { throw new index.NotFoundError(cache, key) } return read.copy( cache, byDigest ? key : entry.integrity, dest, opts ).then(() => byDigest ? key : { metadata: entry.metadata, size: entry.size, integrity: entry.integrity }) }) } else { return getData(byDigest, cache, key, opts).then(res => { return fs.writeFileAsync(dest, byDigest ? res : res.data) .then(() => byDigest ? key : { metadata: res.metadata, size: res.size, integrity: res.integrity }) }) } } cacache-11.3.3/index.js000066400000000000000000000000721350173612200146120ustar00rootroot00000000000000'use strict' module.exports = require('./locales/en.js') cacache-11.3.3/lib/000077500000000000000000000000001350173612200137145ustar00rootroot00000000000000cacache-11.3.3/lib/content/000077500000000000000000000000001350173612200153665ustar00rootroot00000000000000cacache-11.3.3/lib/content/path.js000066400000000000000000000013561350173612200166650ustar00rootroot00000000000000'use strict' const contentVer = require('../../package.json')['cache-version'].content const hashToSegments = require('../util/hash-to-segments') const path = require('path') const ssri = require('ssri') // Current format of content file path: // // sha512-BaSE64Hex= -> // ~/.my-cache/content-v2/sha512/ba/da/55deadbeefc0ffee // module.exports = contentPath function contentPath (cache, integrity) { const sri = ssri.parse(integrity, { single: true }) // contentPath is the *strongest* algo given return path.join.apply(path, [ contentDir(cache), sri.algorithm ].concat(hashToSegments(sri.hexDigest()))) } module.exports._contentDir = contentDir function contentDir (cache) { return path.join(cache, `content-v${contentVer}`) } cacache-11.3.3/lib/content/read.js000066400000000000000000000123771350173612200166510ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('./path') const figgyPudding = require('figgy-pudding') const fs = require('graceful-fs') const PassThrough = require('stream').PassThrough const pipe = BB.promisify(require('mississippi').pipe) const ssri = require('ssri') const Y = require('../util/y.js') const lstatAsync = BB.promisify(fs.lstat) const readFileAsync = BB.promisify(fs.readFile) const ReadOpts = figgyPudding({ size: {} }) module.exports = read function read (cache, integrity, opts) { opts = ReadOpts(opts) return withContentSri(cache, integrity, (cpath, sri) => { return readFileAsync(cpath, null).then(data => { if (typeof opts.size === 'number' && opts.size !== data.length) { throw sizeError(opts.size, data.length) } else if (ssri.checkData(data, sri)) { return data } else { throw integrityError(sri, cpath) } }) }) } module.exports.sync = readSync function readSync (cache, integrity, opts) { opts = ReadOpts(opts) return withContentSriSync(cache, integrity, (cpath, sri) => { const data = fs.readFileSync(cpath) if (typeof opts.size === 'number' && opts.size !== data.length) { throw sizeError(opts.size, data.length) } else if (ssri.checkData(data, sri)) { return data } else { throw integrityError(sri, cpath) } }) } module.exports.stream = readStream module.exports.readStream = readStream function readStream (cache, integrity, opts) { opts = ReadOpts(opts) const stream = new PassThrough() withContentSri(cache, integrity, (cpath, sri) => { return lstatAsync(cpath).then(stat => ({ cpath, sri, stat })) }).then(({ cpath, sri, stat }) => { return pipe( fs.createReadStream(cpath), ssri.integrityStream({ integrity: sri, size: opts.size }), stream ) }).catch(err => { stream.emit('error', err) }) return stream } let copyFileAsync if (fs.copyFile) { module.exports.copy = copy module.exports.copy.sync = copySync copyFileAsync = BB.promisify(fs.copyFile) } function copy (cache, integrity, dest, opts) { opts = ReadOpts(opts) return withContentSri(cache, integrity, (cpath, sri) => { return copyFileAsync(cpath, dest) }) } function copySync (cache, integrity, dest, opts) { opts = ReadOpts(opts) return withContentSriSync(cache, integrity, (cpath, sri) => { return fs.copyFileSync(cpath, dest) }) } module.exports.hasContent = hasContent function hasContent (cache, integrity) { if (!integrity) { return BB.resolve(false) } return withContentSri(cache, integrity, (cpath, sri) => { return lstatAsync(cpath).then(stat => ({ size: stat.size, sri, stat })) }).catch(err => { if (err.code === 'ENOENT') { return false } if (err.code === 'EPERM') { if (process.platform !== 'win32') { throw err } else { return false } } }) } module.exports.hasContent.sync = hasContentSync function hasContentSync (cache, integrity) { if (!integrity) { return false } return withContentSriSync(cache, integrity, (cpath, sri) => { try { const stat = fs.lstatSync(cpath) return { size: stat.size, sri, stat } } catch (err) { if (err.code === 'ENOENT') { return false } if (err.code === 'EPERM') { if (process.platform !== 'win32') { throw err } else { return false } } } }) } function withContentSri (cache, integrity, fn) { return BB.try(() => { const sri = ssri.parse(integrity) // If `integrity` has multiple entries, pick the first digest // with available local data. const algo = sri.pickAlgorithm() const digests = sri[algo] if (digests.length <= 1) { const cpath = contentPath(cache, digests[0]) return fn(cpath, digests[0]) } else { return BB.any(sri[sri.pickAlgorithm()].map(meta => { return withContentSri(cache, meta, fn) }, { concurrency: 1 })) .catch(err => { if ([].some.call(err, e => e.code === 'ENOENT')) { throw Object.assign( new Error('No matching content found for ' + sri.toString()), { code: 'ENOENT' } ) } else { throw err[0] } }) } }) } function withContentSriSync (cache, integrity, fn) { const sri = ssri.parse(integrity) // If `integrity` has multiple entries, pick the first digest // with available local data. const algo = sri.pickAlgorithm() const digests = sri[algo] if (digests.length <= 1) { const cpath = contentPath(cache, digests[0]) return fn(cpath, digests[0]) } else { let lastErr = null for (const meta of sri[sri.pickAlgorithm()]) { try { return withContentSriSync(cache, meta, fn) } catch (err) { lastErr = err } } if (lastErr) { throw lastErr } } } function sizeError (expected, found) { var err = new Error(Y`Bad data size: expected inserted data to be ${expected} bytes, but got ${found} instead`) err.expected = expected err.found = found err.code = 'EBADSIZE' return err } function integrityError (sri, path) { var err = new Error(Y`Integrity verification failed for ${sri} (${path})`) err.code = 'EINTEGRITY' err.sri = sri err.path = path return err } cacache-11.3.3/lib/content/rm.js000066400000000000000000000007301350173612200163420ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('./path') const hasContent = require('./read').hasContent const rimraf = BB.promisify(require('rimraf')) module.exports = rm function rm (cache, integrity) { return hasContent(cache, integrity).then(content => { if (content) { const sri = content.sri if (sri) { return rimraf(contentPath(cache, sri)).then(() => true) } } else { return false } }) } cacache-11.3.3/lib/content/write.js000066400000000000000000000106261350173612200170630ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('./path') const fixOwner = require('../util/fix-owner') const fs = require('graceful-fs') const moveFile = require('../util/move-file') const PassThrough = require('stream').PassThrough const path = require('path') const pipe = BB.promisify(require('mississippi').pipe) const rimraf = BB.promisify(require('rimraf')) const ssri = require('ssri') const to = require('mississippi').to const uniqueFilename = require('unique-filename') const Y = require('../util/y.js') const writeFileAsync = BB.promisify(fs.writeFile) module.exports = write function write (cache, data, opts) { opts = opts || {} if (opts.algorithms && opts.algorithms.length > 1) { throw new Error( Y`opts.algorithms only supports a single algorithm for now` ) } if (typeof opts.size === 'number' && data.length !== opts.size) { return BB.reject(sizeError(opts.size, data.length)) } const sri = ssri.fromData(data, { algorithms: opts.algorithms }) if (opts.integrity && !ssri.checkData(data, opts.integrity, opts)) { return BB.reject(checksumError(opts.integrity, sri)) } return BB.using(makeTmp(cache, opts), tmp => ( writeFileAsync( tmp.target, data, { flag: 'wx' } ).then(() => ( moveToDestination(tmp, cache, sri, opts) )) )).then(() => ({ integrity: sri, size: data.length })) } module.exports.stream = writeStream function writeStream (cache, opts) { opts = opts || {} const inputStream = new PassThrough() let inputErr = false function errCheck () { if (inputErr) { throw inputErr } } let allDone const ret = to((c, n, cb) => { if (!allDone) { allDone = handleContent(inputStream, cache, opts, errCheck) } inputStream.write(c, n, cb) }, cb => { inputStream.end(() => { if (!allDone) { const e = new Error(Y`Cache input stream was empty`) e.code = 'ENODATA' return ret.emit('error', e) } allDone.then(res => { res.integrity && ret.emit('integrity', res.integrity) res.size !== null && ret.emit('size', res.size) cb() }, e => { ret.emit('error', e) }) }) }) ret.once('error', e => { inputErr = e }) return ret } function handleContent (inputStream, cache, opts, errCheck) { return BB.using(makeTmp(cache, opts), tmp => { errCheck() return pipeToTmp( inputStream, cache, tmp.target, opts, errCheck ).then(res => { return moveToDestination( tmp, cache, res.integrity, opts, errCheck ).then(() => res) }) }) } function pipeToTmp (inputStream, cache, tmpTarget, opts, errCheck) { return BB.resolve().then(() => { let integrity let size const hashStream = ssri.integrityStream({ integrity: opts.integrity, algorithms: opts.algorithms, size: opts.size }).on('integrity', s => { integrity = s }).on('size', s => { size = s }) const outStream = fs.createWriteStream(tmpTarget, { flags: 'wx' }) errCheck() return pipe(inputStream, hashStream, outStream).then(() => { return { integrity, size } }).catch(err => { return rimraf(tmpTarget).then(() => { throw err }) }) }) } function makeTmp (cache, opts) { const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix) return fixOwner.mkdirfix( path.dirname(tmpTarget), opts.uid, opts.gid ).then(() => ({ target: tmpTarget, moved: false })).disposer(tmp => (!tmp.moved && rimraf(tmp.target))) } function moveToDestination (tmp, cache, sri, opts, errCheck) { errCheck && errCheck() const destination = contentPath(cache, sri) const destDir = path.dirname(destination) return fixOwner.mkdirfix( destDir, opts.uid, opts.gid ).then(() => { errCheck && errCheck() return moveFile(tmp.target, destination) }).then(() => { errCheck && errCheck() tmp.moved = true return fixOwner.chownr(destination, opts.uid, opts.gid) }) } function sizeError (expected, found) { var err = new Error(Y`Bad data size: expected inserted data to be ${expected} bytes, but got ${found} instead`) err.expected = expected err.found = found err.code = 'EBADSIZE' return err } function checksumError (expected, found) { var err = new Error(Y`Integrity check failed: Wanted: ${expected} Found: ${found}`) err.code = 'EINTEGRITY' err.expected = expected err.found = found return err } cacache-11.3.3/lib/entry-index.js000066400000000000000000000163131350173612200165240ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('./content/path') const crypto = require('crypto') const figgyPudding = require('figgy-pudding') const fixOwner = require('./util/fix-owner') const fs = require('graceful-fs') const hashToSegments = require('./util/hash-to-segments') const ms = require('mississippi') const path = require('path') const ssri = require('ssri') const Y = require('./util/y.js') const indexV = require('../package.json')['cache-version'].index const appendFileAsync = BB.promisify(fs.appendFile) const readFileAsync = BB.promisify(fs.readFile) const readdirAsync = BB.promisify(fs.readdir) const concat = ms.concat const from = ms.from module.exports.NotFoundError = class NotFoundError extends Error { constructor (cache, key) { super(Y`No cache entry for \`${key}\` found in \`${cache}\``) this.code = 'ENOENT' this.cache = cache this.key = key } } const IndexOpts = figgyPudding({ metadata: {}, size: {}, uid: {}, gid: {} }) module.exports.insert = insert function insert (cache, key, integrity, opts) { opts = IndexOpts(opts) const bucket = bucketPath(cache, key) const entry = { key, integrity: integrity && ssri.stringify(integrity), time: Date.now(), size: opts.size, metadata: opts.metadata } return fixOwner.mkdirfix( path.dirname(bucket), opts.uid, opts.gid ).then(() => { const stringified = JSON.stringify(entry) // NOTE - Cleverness ahoy! // // This works because it's tremendously unlikely for an entry to corrupt // another while still preserving the string length of the JSON in // question. So, we just slap the length in there and verify it on read. // // Thanks to @isaacs for the whiteboarding session that ended up with this. return appendFileAsync( bucket, `\n${hashEntry(stringified)}\t${stringified}` ) }).then( () => fixOwner.chownr(bucket, opts.uid, opts.gid) ).catch({ code: 'ENOENT' }, () => { // There's a class of race conditions that happen when things get deleted // during fixOwner, or between the two mkdirfix/chownr calls. // // It's perfectly fine to just not bother in those cases and lie // that the index entry was written. Because it's a cache. }).then(() => { return formatEntry(cache, entry) }) } module.exports.insert.sync = insertSync function insertSync (cache, key, integrity, opts) { opts = IndexOpts(opts) const bucket = bucketPath(cache, key) const entry = { key, integrity: integrity && ssri.stringify(integrity), time: Date.now(), size: opts.size, metadata: opts.metadata } fixOwner.mkdirfix.sync(path.dirname(bucket), opts.uid, opts.gid) const stringified = JSON.stringify(entry) fs.appendFileSync( bucket, `\n${hashEntry(stringified)}\t${stringified}` ) try { fixOwner.chownr.sync(bucket, opts.uid, opts.gid) } catch (err) { if (err.code !== 'ENOENT') { throw err } } return formatEntry(cache, entry) } module.exports.find = find function find (cache, key) { const bucket = bucketPath(cache, key) return bucketEntries(bucket).then(entries => { return entries.reduce((latest, next) => { if (next && next.key === key) { return formatEntry(cache, next) } else { return latest } }, null) }).catch(err => { if (err.code === 'ENOENT') { return null } else { throw err } }) } module.exports.find.sync = findSync function findSync (cache, key) { const bucket = bucketPath(cache, key) try { return bucketEntriesSync(bucket).reduce((latest, next) => { if (next && next.key === key) { return formatEntry(cache, next) } else { return latest } }, null) } catch (err) { if (err.code === 'ENOENT') { return null } else { throw err } } } module.exports.delete = del function del (cache, key, opts) { return insert(cache, key, null, opts) } module.exports.delete.sync = delSync function delSync (cache, key, opts) { return insertSync(cache, key, null, opts) } module.exports.lsStream = lsStream function lsStream (cache) { const indexDir = bucketDir(cache) const stream = from.obj() // "/cachename/*" readdirOrEmpty(indexDir).map(bucket => { const bucketPath = path.join(indexDir, bucket) // "/cachename//*" return readdirOrEmpty(bucketPath).map(subbucket => { const subbucketPath = path.join(bucketPath, subbucket) // "/cachename///*" return readdirOrEmpty(subbucketPath).map(entry => { const getKeyToEntry = bucketEntries( path.join(subbucketPath, entry) ).reduce((acc, entry) => { acc.set(entry.key, entry) return acc }, new Map()) return getKeyToEntry.then(reduced => { for (let entry of reduced.values()) { const formatted = formatEntry(cache, entry) formatted && stream.push(formatted) } }).catch({ code: 'ENOENT' }, nop) }) }) }).then(() => { stream.push(null) }, err => { stream.emit('error', err) }) return stream } module.exports.ls = ls function ls (cache) { return BB.fromNode(cb => { lsStream(cache).on('error', cb).pipe(concat(entries => { cb(null, entries.reduce((acc, xs) => { acc[xs.key] = xs return acc }, {})) })) }) } function bucketEntries (bucket, filter) { return readFileAsync( bucket, 'utf8' ).then(data => _bucketEntries(data, filter)) } function bucketEntriesSync (bucket, filter) { const data = fs.readFileSync(bucket, 'utf8') return _bucketEntries(data, filter) } function _bucketEntries (data, filter) { let entries = [] data.split('\n').forEach(entry => { if (!entry) { return } const pieces = entry.split('\t') if (!pieces[1] || hashEntry(pieces[1]) !== pieces[0]) { // Hash is no good! Corruption or malice? Doesn't matter! // EJECT EJECT return } let obj try { obj = JSON.parse(pieces[1]) } catch (e) { // Entry is corrupted! return } if (obj) { entries.push(obj) } }) return entries } module.exports._bucketDir = bucketDir function bucketDir (cache) { return path.join(cache, `index-v${indexV}`) } module.exports._bucketPath = bucketPath function bucketPath (cache, key) { const hashed = hashKey(key) return path.join.apply(path, [bucketDir(cache)].concat( hashToSegments(hashed) )) } module.exports._hashKey = hashKey function hashKey (key) { return hash(key, 'sha256') } module.exports._hashEntry = hashEntry function hashEntry (str) { return hash(str, 'sha1') } function hash (str, digest) { return crypto .createHash(digest) .update(str) .digest('hex') } function formatEntry (cache, entry) { // Treat null digests as deletions. They'll shadow any previous entries. if (!entry.integrity) { return null } return { key: entry.key, integrity: entry.integrity, path: contentPath(cache, entry.integrity), size: entry.size, time: entry.time, metadata: entry.metadata } } function readdirOrEmpty (dir) { return readdirAsync(dir) .catch({ code: 'ENOENT' }, () => []) .catch({ code: 'ENOTDIR' }, () => []) } function nop () { } cacache-11.3.3/lib/memoization.js000066400000000000000000000030221350173612200166020ustar00rootroot00000000000000'use strict' const LRU = require('lru-cache') const MAX_SIZE = 50 * 1024 * 1024 // 50MB const MAX_AGE = 3 * 60 * 1000 let MEMOIZED = new LRU({ max: MAX_SIZE, maxAge: MAX_AGE, length: (entry, key) => { if (key.startsWith('key:')) { return entry.data.length } else if (key.startsWith('digest:')) { return entry.length } } }) module.exports.clearMemoized = clearMemoized function clearMemoized () { const old = {} MEMOIZED.forEach((v, k) => { old[k] = v }) MEMOIZED.reset() return old } module.exports.put = put function put (cache, entry, data, opts) { pickMem(opts).set(`key:${cache}:${entry.key}`, { entry, data }) putDigest(cache, entry.integrity, data, opts) } module.exports.put.byDigest = putDigest function putDigest (cache, integrity, data, opts) { pickMem(opts).set(`digest:${cache}:${integrity}`, data) } module.exports.get = get function get (cache, key, opts) { return pickMem(opts).get(`key:${cache}:${key}`) } module.exports.get.byDigest = getDigest function getDigest (cache, integrity, opts) { return pickMem(opts).get(`digest:${cache}:${integrity}`) } class ObjProxy { constructor (obj) { this.obj = obj } get (key) { return this.obj[key] } set (key, val) { this.obj[key] = val } } function pickMem (opts) { if (!opts || !opts.memoize) { return MEMOIZED } else if (opts.memoize.get && opts.memoize.set) { return opts.memoize } else if (typeof opts.memoize === 'object') { return new ObjProxy(opts.memoize) } else { return MEMOIZED } } cacache-11.3.3/lib/util/000077500000000000000000000000001350173612200146715ustar00rootroot00000000000000cacache-11.3.3/lib/util/fix-owner.js000066400000000000000000000045271350173612200171550ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const chownr = BB.promisify(require('chownr')) const mkdirp = BB.promisify(require('mkdirp')) const inflight = require('promise-inflight') module.exports.chownr = fixOwner function fixOwner (filepath, uid, gid) { if (!process.getuid) { // This platform doesn't need ownership fixing return BB.resolve() } if (typeof uid !== 'number' && typeof gid !== 'number') { // There's no permissions override. Nothing to do here. return BB.resolve() } if ((typeof uid === 'number' && process.getuid() === uid) && (typeof gid === 'number' && process.getgid() === gid)) { // No need to override if it's already what we used. return BB.resolve() } return inflight( 'fixOwner: fixing ownership on ' + filepath, () => chownr( filepath, typeof uid === 'number' ? uid : process.getuid(), typeof gid === 'number' ? gid : process.getgid() ).catch({ code: 'ENOENT' }, () => null) ) } module.exports.chownr.sync = fixOwnerSync function fixOwnerSync (filepath, uid, gid) { if (!process.getuid) { // This platform doesn't need ownership fixing return } if (typeof uid !== 'number' && typeof gid !== 'number') { // There's no permissions override. Nothing to do here. return } if ((typeof uid === 'number' && process.getuid() === uid) && (typeof gid === 'number' && process.getgid() === gid)) { // No need to override if it's already what we used. return } try { chownr.sync( filepath, typeof uid === 'number' ? uid : process.getuid(), typeof gid === 'number' ? gid : process.getgid() ) } catch (err) { if (err.code === 'ENOENT') { return null } } } module.exports.mkdirfix = mkdirfix function mkdirfix (p, uid, gid, cb) { return mkdirp(p).then(made => { if (made) { return fixOwner(made, uid, gid).then(() => made) } }).catch({ code: 'EEXIST' }, () => { // There's a race in mkdirp! return fixOwner(p, uid, gid).then(() => null) }) } module.exports.mkdirfix.sync = mkdirfixSync function mkdirfixSync (p, uid, gid) { try { const made = mkdirp.sync(p) if (made) { fixOwnerSync(made, uid, gid) return made } } catch (err) { if (err.code === 'EEXIST') { fixOwnerSync(p, uid, gid) return null } else { throw err } } } cacache-11.3.3/lib/util/hash-to-segments.js000066400000000000000000000002371350173612200204170ustar00rootroot00000000000000'use strict' module.exports = hashToSegments function hashToSegments (hash) { return [ hash.slice(0, 2), hash.slice(2, 4), hash.slice(4) ] } cacache-11.3.3/lib/util/move-file.js000066400000000000000000000033361350173612200171170ustar00rootroot00000000000000'use strict' const fs = require('graceful-fs') const BB = require('bluebird') const chmod = BB.promisify(fs.chmod) const unlink = BB.promisify(fs.unlink) let move let pinflight module.exports = moveFile function moveFile (src, dest) { // This isn't quite an fs.rename -- the assumption is that // if `dest` already exists, and we get certain errors while // trying to move it, we should just not bother. // // In the case of cache corruption, users will receive an // EINTEGRITY error elsewhere, and can remove the offending // content their own way. // // Note that, as the name suggests, this strictly only supports file moves. return BB.fromNode(cb => { fs.link(src, dest, err => { if (err) { if (err.code === 'EEXIST' || err.code === 'EBUSY') { // file already exists, so whatever } else if (err.code === 'EPERM' && process.platform === 'win32') { // file handle stayed open even past graceful-fs limits } else { return cb(err) } } return cb() }) }).then(() => { // content should never change for any reason, so make it read-only return BB.join(unlink(src), process.platform !== 'win32' && chmod(dest, '0444')) }).catch(() => { if (!pinflight) { pinflight = require('promise-inflight') } return pinflight('cacache-move-file:' + dest, () => { return BB.promisify(fs.stat)(dest).catch(err => { if (err.code !== 'ENOENT') { // Something else is wrong here. Bail bail bail throw err } // file doesn't already exist! let's try a rename -> copy fallback if (!move) { move = require('move-concurrently') } return move(src, dest, { BB, fs }) }) }) }) } cacache-11.3.3/lib/util/tmp.js000066400000000000000000000016741350173612200160370ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const figgyPudding = require('figgy-pudding') const fixOwner = require('./fix-owner') const path = require('path') const rimraf = BB.promisify(require('rimraf')) const uniqueFilename = require('unique-filename') const TmpOpts = figgyPudding({ tmpPrefix: {}, uid: {}, gid: {} }) module.exports.mkdir = mktmpdir function mktmpdir (cache, opts) { opts = TmpOpts(opts) const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix) return fixOwner.mkdirfix(tmpTarget, opts.uid, opts.gid).then(() => { return tmpTarget }) } module.exports.withTmp = withTmp function withTmp (cache, opts, cb) { if (!cb) { cb = opts opts = null } opts = TmpOpts(opts) return BB.using(mktmpdir(cache, opts).disposer(rimraf), cb) } module.exports.fix = fixtmpdir function fixtmpdir (cache, opts) { opts = TmpOpts(opts) return fixOwner(path.join(cache, 'tmp'), opts.uid, opts.gid) } cacache-11.3.3/lib/util/y.js000066400000000000000000000010321350173612200154730ustar00rootroot00000000000000'use strict' const path = require('path') const y18n = require('y18n')({ directory: path.join(__dirname, '../../locales'), locale: 'en', updateFiles: process.env.CACACHE_UPDATE_LOCALE_FILES === 'true' }) module.exports = yTag function yTag (parts) { let str = '' parts.forEach((part, i) => { const arg = arguments[i + 1] str += part if (arg) { str += '%s' } }) return y18n.__.apply(null, [str].concat([].slice.call(arguments, 1))) } module.exports.setLocale = locale => { y18n.setLocale(locale) } cacache-11.3.3/lib/verify.js000066400000000000000000000153111350173612200155570ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('./content/path') const figgyPudding = require('figgy-pudding') const finished = BB.promisify(require('mississippi').finished) const fixOwner = require('./util/fix-owner') const fs = require('graceful-fs') const glob = BB.promisify(require('glob')) const index = require('./entry-index') const path = require('path') const rimraf = BB.promisify(require('rimraf')) const ssri = require('ssri') BB.promisifyAll(fs) const VerifyOpts = figgyPudding({ concurrency: { default: 20 }, filter: {}, log: { default: { silly () {} } }, uid: {}, gid: {} }) module.exports = verify function verify (cache, opts) { opts = VerifyOpts(opts) opts.log.silly('verify', 'verifying cache at', cache) return BB.reduce([ markStartTime, fixPerms, garbageCollect, rebuildIndex, cleanTmp, writeVerifile, markEndTime ], (stats, step, i) => { const label = step.name || `step #${i}` const start = new Date() return BB.resolve(step(cache, opts)).then(s => { s && Object.keys(s).forEach(k => { stats[k] = s[k] }) const end = new Date() if (!stats.runTime) { stats.runTime = {} } stats.runTime[label] = end - start return stats }) }, {}).tap(stats => { stats.runTime.total = stats.endTime - stats.startTime opts.log.silly('verify', 'verification finished for', cache, 'in', `${stats.runTime.total}ms`) }) } function markStartTime (cache, opts) { return { startTime: new Date() } } function markEndTime (cache, opts) { return { endTime: new Date() } } function fixPerms (cache, opts) { opts.log.silly('verify', 'fixing cache permissions') return fixOwner.mkdirfix(cache, opts.uid, opts.gid).then(() => { // TODO - fix file permissions too return fixOwner.chownr(cache, opts.uid, opts.gid) }).then(() => null) } // Implements a naive mark-and-sweep tracing garbage collector. // // The algorithm is basically as follows: // 1. Read (and filter) all index entries ("pointers") // 2. Mark each integrity value as "live" // 3. Read entire filesystem tree in `content-vX/` dir // 4. If content is live, verify its checksum and delete it if it fails // 5. If content is not marked as live, rimraf it. // function garbageCollect (cache, opts) { opts.log.silly('verify', 'garbage collecting content') const indexStream = index.lsStream(cache) const liveContent = new Set() indexStream.on('data', entry => { if (opts.filter && !opts.filter(entry)) { return } liveContent.add(entry.integrity.toString()) }) return finished(indexStream).then(() => { const contentDir = contentPath._contentDir(cache) return glob(path.join(contentDir, '**'), { follow: false, nodir: true, nosort: true }).then(files => { return BB.resolve({ verifiedContent: 0, reclaimedCount: 0, reclaimedSize: 0, badContentCount: 0, keptSize: 0 }).tap((stats) => BB.map(files, (f) => { const split = f.split(/[/\\]/) const digest = split.slice(split.length - 3).join('') const algo = split[split.length - 4] const integrity = ssri.fromHex(digest, algo) if (liveContent.has(integrity.toString())) { return verifyContent(f, integrity).then(info => { if (!info.valid) { stats.reclaimedCount++ stats.badContentCount++ stats.reclaimedSize += info.size } else { stats.verifiedContent++ stats.keptSize += info.size } return stats }) } else { // No entries refer to this content. We can delete. stats.reclaimedCount++ return fs.statAsync(f).then(s => { return rimraf(f).then(() => { stats.reclaimedSize += s.size return stats }) }) } }, { concurrency: opts.concurrency })) }) }) } function verifyContent (filepath, sri) { return fs.statAsync(filepath).then(stat => { const contentInfo = { size: stat.size, valid: true } return ssri.checkStream( fs.createReadStream(filepath), sri ).catch(err => { if (err.code !== 'EINTEGRITY') { throw err } return rimraf(filepath).then(() => { contentInfo.valid = false }) }).then(() => contentInfo) }).catch({ code: 'ENOENT' }, () => ({ size: 0, valid: false })) } function rebuildIndex (cache, opts) { opts.log.silly('verify', 'rebuilding index') return index.ls(cache).then(entries => { const stats = { missingContent: 0, rejectedEntries: 0, totalEntries: 0 } const buckets = {} for (let k in entries) { if (entries.hasOwnProperty(k)) { const hashed = index._hashKey(k) const entry = entries[k] const excluded = opts.filter && !opts.filter(entry) excluded && stats.rejectedEntries++ if (buckets[hashed] && !excluded) { buckets[hashed].push(entry) } else if (buckets[hashed] && excluded) { // skip } else if (excluded) { buckets[hashed] = [] buckets[hashed]._path = index._bucketPath(cache, k) } else { buckets[hashed] = [entry] buckets[hashed]._path = index._bucketPath(cache, k) } } } return BB.map(Object.keys(buckets), key => { return rebuildBucket(cache, buckets[key], stats, opts) }, { concurrency: opts.concurrency }).then(() => stats) }) } function rebuildBucket (cache, bucket, stats, opts) { return fs.truncateAsync(bucket._path).then(() => { // This needs to be serialized because cacache explicitly // lets very racy bucket conflicts clobber each other. return BB.mapSeries(bucket, entry => { const content = contentPath(cache, entry.integrity) return fs.statAsync(content).then(() => { return index.insert(cache, entry.key, entry.integrity, { uid: opts.uid, gid: opts.gid, metadata: entry.metadata, size: entry.size }).then(() => { stats.totalEntries++ }) }).catch({ code: 'ENOENT' }, () => { stats.rejectedEntries++ stats.missingContent++ }) }) }) } function cleanTmp (cache, opts) { opts.log.silly('verify', 'cleaning tmp directory') return rimraf(path.join(cache, 'tmp')) } function writeVerifile (cache, opts) { const verifile = path.join(cache, '_lastverified') opts.log.silly('verify', 'writing verifile to ' + verifile) return fs.writeFileAsync(verifile, '' + (+(new Date()))) } module.exports.lastRun = lastRun function lastRun (cache) { return fs.readFileAsync( path.join(cache, '_lastverified'), 'utf8' ).then(data => new Date(+data)) } cacache-11.3.3/locales/000077500000000000000000000000001350173612200145705ustar00rootroot00000000000000cacache-11.3.3/locales/en.js000066400000000000000000000034431350173612200155340ustar00rootroot00000000000000'use strict' const ls = require('../ls.js') const get = require('../get.js') const put = require('../put.js') const rm = require('../rm.js') const verify = require('../verify.js') const setLocale = require('../lib/util/y.js').setLocale const clearMemoized = require('../lib/memoization.js').clearMemoized const tmp = require('../lib/util/tmp.js') setLocale('en') const x = module.exports x.ls = cache => ls(cache) x.ls.stream = cache => ls.stream(cache) x.get = (cache, key, opts) => get(cache, key, opts) x.get.byDigest = (cache, hash, opts) => get.byDigest(cache, hash, opts) x.get.sync = (cache, key, opts) => get.sync(cache, key, opts) x.get.sync.byDigest = (cache, key, opts) => get.sync.byDigest(cache, key, opts) x.get.stream = (cache, key, opts) => get.stream(cache, key, opts) x.get.stream.byDigest = (cache, hash, opts) => get.stream.byDigest(cache, hash, opts) x.get.copy = (cache, key, dest, opts) => get.copy(cache, key, dest, opts) x.get.copy.byDigest = (cache, hash, dest, opts) => get.copy.byDigest(cache, hash, dest, opts) x.get.info = (cache, key) => get.info(cache, key) x.get.hasContent = (cache, hash) => get.hasContent(cache, hash) x.get.hasContent.sync = (cache, hash) => get.hasContent.sync(cache, hash) x.put = (cache, key, data, opts) => put(cache, key, data, opts) x.put.stream = (cache, key, opts) => put.stream(cache, key, opts) x.rm = (cache, key) => rm.entry(cache, key) x.rm.all = cache => rm.all(cache) x.rm.entry = x.rm x.rm.content = (cache, hash) => rm.content(cache, hash) x.setLocale = lang => setLocale(lang) x.clearMemoized = () => clearMemoized() x.tmp = {} x.tmp.mkdir = (cache, opts) => tmp.mkdir(cache, opts) x.tmp.withTmp = (cache, opts, cb) => tmp.withTmp(cache, opts, cb) x.verify = (cache, opts) => verify(cache, opts) x.verify.lastRun = cache => verify.lastRun(cache) cacache-11.3.3/locales/en.json000066400000000000000000000006131350173612200160650ustar00rootroot00000000000000{ "No cache entry for `%s` found in `%s`": "No cache entry for %s found in %s", "Integrity verification failed for %s (%s)": "Integrity verification failed for %s (%s)", "Bad data size: expected inserted data to be %s bytes, but got %s instead": "Bad data size: expected inserted data to be %s bytes, but got %s instead", "Cache input stream was empty": "Cache input stream was empty" } cacache-11.3.3/locales/es.js000066400000000000000000000036721350173612200155450ustar00rootroot00000000000000'use strict' const ls = require('../ls.js') const get = require('../get.js') const put = require('../put.js') const rm = require('../rm.js') const verify = require('../verify.js') const setLocale = require('../lib/util/y.js').setLocale const clearMemoized = require('../lib/memoization.js').clearMemoized const tmp = require('../lib/util/tmp.js') setLocale('es') const x = module.exports x.ls = cache => ls(cache) x.ls.flujo = cache => ls.stream(cache) x.saca = (cache, clave, ops) => get(cache, clave, ops) x.saca.porHacheo = (cache, hacheo, ops) => get.byDigest(cache, hacheo, ops) x.saca.sinc = (cache, clave, ops) => get.sync(cache, clave, ops) x.saca.sinc.porHacheo = (cache, hacheo, ops) => get.sync.byDigest(cache, hacheo, ops) x.saca.flujo = (cache, clave, ops) => get.stream(cache, clave, ops) x.saca.flujo.porHacheo = (cache, hacheo, ops) => get.stream.byDigest(cache, hacheo, ops) x.sava.copia = (cache, clave, destino, opts) => get.copy(cache, clave, destino, opts) x.sava.copia.porHacheo = (cache, hacheo, destino, opts) => get.copy.byDigest(cache, hacheo, destino, opts) x.saca.info = (cache, clave) => get.info(cache, clave) x.saca.tieneDatos = (cache, hacheo) => get.hasContent(cache, hacheo) x.saca.tieneDatos.sinc = (cache, hacheo) => get.hasContent.sync(cache, hacheo) x.mete = (cache, clave, datos, ops) => put(cache, clave, datos, ops) x.mete.flujo = (cache, clave, ops) => put.stream(cache, clave, ops) x.rm = (cache, clave) => rm.entry(cache, clave) x.rm.todo = cache => rm.all(cache) x.rm.entrada = x.rm x.rm.datos = (cache, hacheo) => rm.content(cache, hacheo) x.ponLenguaje = lang => setLocale(lang) x.limpiaMemoizado = () => clearMemoized() x.tmp = {} x.tmp.mkdir = (cache, ops) => tmp.mkdir(cache, ops) x.tmp.hazdir = x.tmp.mkdir x.tmp.conTmp = (cache, ops, cb) => tmp.withTmp(cache, ops, cb) x.verifica = (cache, ops) => verify(cache, ops) x.verifica.ultimaVez = cache => verify.lastRun(cache) x.verifica.últimaVez = x.verifica.ultimaVez cacache-11.3.3/locales/es.json000066400000000000000000000007131350173612200160730ustar00rootroot00000000000000{ "No cache entry for `%s` found in `%s`": "No existe ninguna entrada para «%s» en «%s»", "Integrity verification failed for %s (%s)": "Verificación de integridad falló para «%s» (%s)", "Bad data size: expected inserted data to be %s bytes, but got %s instead": "Tamaño incorrecto de datos: los datos insertados debieron haber sido %s octetos, pero fueron %s", "Cache input stream was empty": "El stream de entrada al caché estaba vacío" } cacache-11.3.3/ls.js000066400000000000000000000001711350173612200141210ustar00rootroot00000000000000'use strict' var index = require('./lib/entry-index') module.exports = index.ls module.exports.stream = index.lsStream cacache-11.3.3/package-lock.json000066400000000000000000006123241350173612200163720ustar00rootroot00000000000000{ "name": "cacache", "version": "11.3.3", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", "dev": true, "requires": { "@babel/highlight": "^7.0.0" } }, "@babel/generator": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", "dev": true, "requires": { "@babel/types": "^7.4.4", "jsesc": "^2.5.1", "lodash": "^4.17.11", "source-map": "^0.5.0", "trim-right": "^1.0.1" }, "dependencies": { "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true } } }, "@babel/helper-function-name": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.0.0", "@babel/template": "^7.1.0", "@babel/types": "^7.0.0" } }, "@babel/helper-get-function-arity": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", "dev": true, "requires": { "@babel/types": "^7.0.0" } }, "@babel/helper-split-export-declaration": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", "dev": true, "requires": { "@babel/types": "^7.4.4" } }, "@babel/highlight": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" }, "dependencies": { "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true } } }, "@babel/parser": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", "dev": true }, "@babel/template": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.4.4", "@babel/types": "^7.4.4" } }, "@babel/traverse": { "version": "7.4.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "@babel/generator": "^7.4.4", "@babel/helper-function-name": "^7.1.0", "@babel/helper-split-export-declaration": "^7.4.4", "@babel/parser": "^7.4.5", "@babel/types": "^7.4.4", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.11" }, "dependencies": { "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "@babel/types": { "version": "7.4.4", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.11", "to-fast-properties": "^2.0.0" } }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", "dev": true, "requires": { "jsonparse": "^1.2.0", "through": ">=2.2.7 <3" } }, "acorn": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", "dev": true }, "acorn-jsx": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", "dev": true }, "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ajv-keywords": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.0.tgz", "integrity": "sha512-aUjdRFISbuFOl0EIZc+9e4FfZp0bDZgAdOOf30bJmw8VM9v84SHyVyxDfbWxpGYbdZD/9XoKxfHVNmxPkhwyGw==", "dev": true }, "ansi-escapes": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", "dev": true }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { "color-convert": "^1.9.0" } }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", "integrity": "sha512-P009oYkeHyU742iSZJzZZywj4QRJdnTWffaKuJQLablCZ1uz6/cW4yaRgcDaoQ+uwOxxnt0gRUcwfsNP2ri0gw==", "dev": true, "requires": { "default-require-extensions": "^2.0.0" } }, "aproba": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.1.1.tgz", "integrity": "sha1-ldNgDwdxCqDpKYxyatXs8urLq6s=" }, "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", "dev": true }, "arg": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", "dev": true }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { "sprintf-js": "~1.0.2" } }, "array-find-index": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", "dev": true }, "array-ify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", "dev": true }, "array-includes": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.7.0" } }, "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", "dev": true }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", "dev": true, "requires": { "safer-buffer": "~2.1.0" } }, "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", "dev": true }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", "dev": true }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, "babel-code-frame": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { "chalk": "^1.1.3", "esutils": "^2.0.2", "js-tokens": "^3.0.2" }, "dependencies": { "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, "chalk": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { "ansi-styles": "^2.2.1", "escape-string-regexp": "^1.0.2", "has-ansi": "^2.0.0", "strip-ansi": "^3.0.0", "supports-color": "^2.0.0" } }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true } } }, "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" }, "bcrypt-pbkdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, "requires": { "tweetnacl": "^0.14.3" } }, "benchmark": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", "dev": true, "requires": { "lodash": "^4.17.4", "platform": "^1.3.3" } }, "bind-obj-methods": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/bind-obj-methods/-/bind-obj-methods-2.0.0.tgz", "integrity": "sha512-3/qRXczDi2Cdbz6jE+W3IflJOutRVica8frpBn14de1mBOkzDo+6tY33kNhvkw54Kn3PzRRD2VnGbGPcTAk4sw==", "dev": true }, "bluebird": { "version": "3.5.5", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==" }, "brace-expansion": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.7.tgz", "integrity": "sha1-Pv/DxQ4ABTH7cg6v+A8K6O8jz1k=", "requires": { "balanced-match": "^0.4.1", "concat-map": "0.0.1" } }, "browser-process-hrtime": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", "dev": true }, "buffer-from": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, "buffer-shims": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz", "integrity": "sha1-mXjOMXOIxkmth5MCjDR37wRKi1E=" }, "builtin-modules": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", "dev": true }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", "integrity": "sha512-Mtgcv3lh3U0zRii/6qVgQODdPA4G3zhG+jtbCWj39RXuUFTMzH0vcdMtaJS1jPowd+It2Pqr6y3NJMQqOqCE2w==", "dev": true, "requires": { "hasha": "^3.0.0", "make-dir": "^2.0.0", "package-hash": "^3.0.0", "write-file-atomic": "^2.4.2" } }, "caller": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/caller/-/caller-1.0.1.tgz", "integrity": "sha1-uFGGD3Dhlds9J3OVqhp+I+ow7PU=", "dev": true }, "caller-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", "dev": true, "requires": { "callsites": "^0.2.0" } }, "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", "dev": true }, "camelcase": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", "dev": true }, "camelcase-keys": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", "dev": true, "requires": { "camelcase": "^4.1.0", "map-obj": "^2.0.0", "quick-lru": "^1.0.0" } }, "capture-stack-trace": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz", "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==", "dev": true }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", "supports-color": "^5.3.0" } }, "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", "dev": true }, "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" }, "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", "dev": true }, "clean-yaml-object": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", "dev": true }, "cli-cursor": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", "dev": true, "requires": { "restore-cursor": "^2.0.0" } }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", "dev": true }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", "dev": true, "requires": { "string-width": "^2.1.1", "strip-ansi": "^4.0.0", "wrap-ansi": "^2.0.0" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, "requires": { "color-name": "1.1.3" } }, "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", "dev": true }, "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" } }, "commander": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true, "optional": true }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, "compare-func": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", "dev": true, "requires": { "array-ify": "^1.0.0", "dot-prop": "^3.0.0" } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", "requires": { "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" } }, "contains-path": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", "dev": true }, "conventional-changelog": { "version": "3.1.8", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.8.tgz", "integrity": "sha512-fb3/DOLLrQdNqN0yYn/lT6HcNsAa9A+VTDBqlZBMQcEPPIeJIMI+DBs3yu+eiYOLi22w9oShq3nn/zN6qm1Hmw==", "dev": true, "requires": { "conventional-changelog-angular": "^5.0.3", "conventional-changelog-atom": "^2.0.1", "conventional-changelog-codemirror": "^2.0.1", "conventional-changelog-conventionalcommits": "^3.0.2", "conventional-changelog-core": "^3.2.2", "conventional-changelog-ember": "^2.0.2", "conventional-changelog-eslint": "^3.0.2", "conventional-changelog-express": "^2.0.1", "conventional-changelog-jquery": "^3.0.4", "conventional-changelog-jshint": "^2.0.1", "conventional-changelog-preset-loader": "^2.1.1" } }, "conventional-changelog-angular": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.3.tgz", "integrity": "sha512-YD1xzH7r9yXQte/HF9JBuEDfvjxxwDGGwZU1+ndanbY0oFgA+Po1T9JDSpPLdP0pZT6MhCAsdvFKC4TJ4MTJTA==", "dev": true, "requires": { "compare-func": "^1.3.1", "q": "^1.5.1" } }, "conventional-changelog-atom": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.1.tgz", "integrity": "sha512-9BniJa4gLwL20Sm7HWSNXd0gd9c5qo49gCi8nylLFpqAHhkFTj7NQfROq3f1VpffRtzfTQp4VKU5nxbe2v+eZQ==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-codemirror": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.1.tgz", "integrity": "sha512-23kT5IZWa+oNoUaDUzVXMYn60MCdOygTA2I+UjnOMiYVhZgmVwNd6ri/yDlmQGXHqbKhNR5NoXdBzSOSGxsgIQ==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-config-spec": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-1.0.0.tgz", "integrity": "sha512-RR3479x5Qw7XWkmNDYx/kOnsQJW+FZBIakURG/Dg7FkTaCrGjAkgfH96pQs9SyOEZI07USEXy7FjUDWYP8bt3Q==", "dev": true }, "conventional-changelog-conventionalcommits": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-3.0.2.tgz", "integrity": "sha512-w1+fQSDnm/7+sPKIYC5nfRVYDszt+6HdWizrigSqWFVIiiBVzkHGeqDLMSHc+Qq9qssHVAxAak5206epZyK87A==", "dev": true, "requires": { "compare-func": "^1.3.1", "q": "^1.5.1" } }, "conventional-changelog-core": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.2.3.tgz", "integrity": "sha512-LMMX1JlxPIq/Ez5aYAYS5CpuwbOk6QFp8O4HLAcZxe3vxoCtABkhfjetk8IYdRB9CDQGwJFLR3Dr55Za6XKgUQ==", "dev": true, "requires": { "conventional-changelog-writer": "^4.0.6", "conventional-commits-parser": "^3.0.3", "dateformat": "^3.0.0", "get-pkg-repo": "^1.0.0", "git-raw-commits": "2.0.0", "git-remote-origin-url": "^2.0.0", "git-semver-tags": "^2.0.3", "lodash": "^4.2.1", "normalize-package-data": "^2.3.5", "q": "^1.5.1", "read-pkg": "^3.0.0", "read-pkg-up": "^3.0.0", "through2": "^3.0.0" }, "dependencies": { "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "git-semver-tags": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.3.tgz", "integrity": "sha512-tj4FD4ww2RX2ae//jSrXZzrocla9db5h0V7ikPl1P/WwoZar9epdUhwR7XHXSgc+ZkNq72BEEerqQuicoEQfzA==", "dev": true, "requires": { "meow": "^4.0.0", "semver": "^6.0.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" } }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } }, "read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" } }, "semver": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", "dev": true }, "through2": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", "dev": true, "requires": { "readable-stream": "2 || 3" } } } }, "conventional-changelog-ember": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.2.tgz", "integrity": "sha512-qtZbA3XefO/n6DDmkYywDYi6wDKNNc98MMl2F9PKSaheJ25Trpi3336W8fDlBhq0X+EJRuseceAdKLEMmuX2tg==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-eslint": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.2.tgz", "integrity": "sha512-Yi7tOnxjZLXlCYBHArbIAm8vZ68QUSygFS7PgumPRiEk+9NPUeucy5Wg9AAyKoBprSV3o6P7Oghh4IZSLtKCvQ==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-express": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.1.tgz", "integrity": "sha512-G6uCuCaQhLxdb4eEfAIHpcfcJ2+ao3hJkbLrw/jSK/eROeNfnxCJasaWdDAfFkxsbpzvQT4W01iSynU3OoPLIw==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-jquery": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.4.tgz", "integrity": "sha512-IVJGI3MseYoY6eybknnTf9WzeQIKZv7aNTm2KQsiFVJH21bfP2q7XVjfoMibdCg95GmgeFlaygMdeoDDa+ZbEQ==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-jshint": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.1.tgz", "integrity": "sha512-kRFJsCOZzPFm2tzRHULWP4tauGMvccOlXYf3zGeuSW4U0mZhk5NsjnRZ7xFWrTFPlCLV+PNmHMuXp5atdoZmEg==", "dev": true, "requires": { "compare-func": "^1.3.1", "q": "^1.5.1" } }, "conventional-changelog-preset-loader": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.1.1.tgz", "integrity": "sha512-K4avzGMLm5Xw0Ek/6eE3vdOXkqnpf9ydb68XYmCc16cJ99XMMbc2oaNMuPwAsxVK6CC1yA4/I90EhmWNj0Q6HA==", "dev": true }, "conventional-changelog-writer": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.6.tgz", "integrity": "sha512-ou/sbrplJMM6KQpR5rKFYNVQYesFjN7WpNGdudQSWNi6X+RgyFUcSv871YBYkrUYV9EX8ijMohYVzn9RUb+4ag==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.2", "dateformat": "^3.0.0", "handlebars": "^4.1.0", "json-stringify-safe": "^5.0.1", "lodash": "^4.2.1", "meow": "^4.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^3.0.0" }, "dependencies": { "semver": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", "dev": true }, "through2": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", "dev": true, "requires": { "readable-stream": "2 || 3" } } } }, "conventional-commits-filter": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.2.tgz", "integrity": "sha512-WpGKsMeXfs21m1zIw4s9H5sys2+9JccTzpN6toXtxhpw2VNF2JUXwIakthKBy+LN4DvJm+TzWhxOMWOs1OFCFQ==", "dev": true, "requires": { "lodash.ismatch": "^4.4.0", "modify-values": "^1.0.0" } }, "conventional-commits-parser": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.3.tgz", "integrity": "sha512-KaA/2EeUkO4bKjinNfGUyqPTX/6w9JGshuQRik4r/wJz7rUw3+D3fDG6sZSEqJvKILzKXFQuFkpPLclcsAuZcg==", "dev": true, "requires": { "JSONStream": "^1.0.4", "is-text-path": "^2.0.0", "lodash": "^4.2.1", "meow": "^4.0.0", "split2": "^2.0.0", "through2": "^3.0.0", "trim-off-newlines": "^1.0.0" }, "dependencies": { "through2": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz", "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==", "dev": true, "requires": { "readable-stream": "2 || 3" } } } }, "conventional-recommended-bump": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-5.0.0.tgz", "integrity": "sha512-CsfdICpbUe0pmM4MTG90GPUqnFgB1SWIR2HAh+vS+JhhJdPWvc0brs8oadWoYGhFOQpQwe57JnvzWEWU0m2OSg==", "dev": true, "requires": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^2.1.1", "conventional-commits-filter": "^2.0.2", "conventional-commits-parser": "^3.0.2", "git-raw-commits": "2.0.0", "git-semver-tags": "^2.0.2", "meow": "^4.0.0", "q": "^1.5.1" }, "dependencies": { "concat-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", "dev": true, "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.0.2", "typedarray": "^0.0.6" } }, "readable-stream": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz", "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "string_decoder": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", "dev": true, "requires": { "safe-buffer": "~5.1.0" } } } }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", "dev": true, "requires": { "safe-buffer": "~5.1.1" } }, "copy-concurrently": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.3.tgz", "integrity": "sha1-Rft4ZiSaHKiJqlcI5svSc+dbslA=", "requires": { "aproba": "^1.1.1", "fs-write-stream-atomic": "^1.0.8", "iferr": "^0.1.5", "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.0" } }, "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "coveralls": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.4.tgz", "integrity": "sha512-eyqUWA/7RT0JagiL0tThVhjbIjoiEUyWCjtUJoOPcWoeofP5WK/jb2OJYoBFrR6DvplR+AxOyuBqk4JHkk5ykA==", "dev": true, "requires": { "growl": "~> 1.10.0", "js-yaml": "^3.11.0", "lcov-parse": "^0.0.10", "log-driver": "^1.2.7", "minimist": "^1.2.0", "request": "^2.86.0" }, "dependencies": { "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "cp-file": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/cp-file/-/cp-file-6.2.0.tgz", "integrity": "sha512-fmvV4caBnofhPe8kOcitBwSn2f39QLjnAnGq3gO9dfd75mUytzKNZB1hde6QHunW2Rt+OwuBOMc3i1tNElbszA==", "dev": true, "requires": { "graceful-fs": "^4.1.2", "make-dir": "^2.0.0", "nested-error-stacks": "^2.0.0", "pify": "^4.0.1", "safe-buffer": "^5.0.1" }, "dependencies": { "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true } } }, "cross-env": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz", "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==", "dev": true, "requires": { "cross-spawn": "^6.0.5", "is-windows": "^1.0.0" }, "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true } } }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" }, "dependencies": { "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "currently-unhandled": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { "array-find-index": "^1.0.1" } }, "cyclist": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=" }, "dargs": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "dateformat": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", "dev": true }, "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { "ms": "^2.1.1" }, "dependencies": { "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "debug-log": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/debug-log/-/debug-log-1.0.1.tgz", "integrity": "sha1-IwdjLUwEOCuN+KMvcLiVBG1SdF8=", "dev": true }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, "decamelize-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", "dev": true, "requires": { "decamelize": "^1.1.0", "map-obj": "^1.0.0" }, "dependencies": { "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true } } }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", "integrity": "sha1-9fj7sYp9bVCyH2QfZJ67Uiz+JPc=", "dev": true, "requires": { "strip-bom": "^3.0.0" } }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { "object-keys": "^1.0.12" } }, "deglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.1.tgz", "integrity": "sha512-2kjwuGGonL7gWE1XU4Fv79+vVzpoQCl0V+boMwWtOQJV2AGDabCwez++nB1Nli/8BabAfZQ/UuHPlp6AymKdWw==", "dev": true, "requires": { "find-root": "^1.0.0", "glob": "^7.0.5", "ignore": "^3.0.9", "pkg-config": "^1.1.0", "run-parallel": "^1.1.2", "uniq": "^1.0.1" }, "dependencies": { "ignore": { "version": "3.3.10", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", "dev": true } } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, "detect-indent": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", "dev": true }, "detect-newline": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.0.0.tgz", "integrity": "sha512-JAP22dVPAqvhdRFFxK1G5GViIokyUn0UWXRNW0ztK96fsqi9cuM8w8ESbSk+T2w5OVorcMcL6m7yUg1RrX+2CA==", "dev": true }, "diff": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/diff/-/diff-1.4.0.tgz", "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", "dev": true }, "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", "dev": true }, "dot-prop": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", "dev": true, "requires": { "is-obj": "^1.0.0" } }, "dotgitignore": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", "dev": true, "requires": { "find-up": "^3.0.0", "minimatch": "^3.0.4" }, "dependencies": { "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "duplexify": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", "requires": { "end-of-stream": "^1.0.0", "inherits": "^2.0.1", "readable-stream": "^2.0.0", "stream-shift": "^1.0.0" } }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" } }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", "dev": true }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", "requires": { "once": "^1.4.0" } }, "error-ex": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", "dev": true, "requires": { "es-to-primitive": "^1.2.0", "function-bind": "^1.1.1", "has": "^1.0.3", "is-callable": "^1.1.4", "is-regex": "^1.0.4", "object-keys": "^1.0.12" } }, "es-to-primitive": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", "dev": true, "requires": { "is-callable": "^1.1.4", "is-date-object": "^1.0.1", "is-symbol": "^1.0.2" } }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, "eslint": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.4.0.tgz", "integrity": "sha512-UIpL91XGex3qtL6qwyCQJar2j3osKxK9e3ano3OcGEIRM4oWIpCkDg9x95AXEC2wMs7PnxzOkPZ2gq+tsMS9yg==", "dev": true, "requires": { "ajv": "^6.5.0", "babel-code-frame": "^6.26.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^3.1.0", "doctrine": "^2.1.0", "eslint-scope": "^4.0.0", "eslint-utils": "^1.3.1", "eslint-visitor-keys": "^1.0.0", "espree": "^4.0.0", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^2.0.0", "functional-red-black-tree": "^1.0.1", "glob": "^7.1.2", "globals": "^11.7.0", "ignore": "^4.0.2", "imurmurhash": "^0.1.4", "inquirer": "^5.2.0", "is-resolvable": "^1.1.0", "js-yaml": "^3.11.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.5", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.2", "path-is-inside": "^1.0.2", "pluralize": "^7.0.0", "progress": "^2.0.0", "regexpp": "^2.0.0", "require-uncached": "^1.0.3", "semver": "^5.5.0", "strip-ansi": "^4.0.0", "strip-json-comments": "^2.0.1", "table": "^4.0.3", "text-table": "^0.2.0" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "eslint-config-standard": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", "integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==", "dev": true }, "eslint-config-standard-jsx": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-6.0.2.tgz", "integrity": "sha512-D+YWAoXw+2GIdbMBRAzWwr1ZtvnSf4n4yL0gKGg7ShUOGXkSOLerI17K4F6LdQMJPNMoWYqepzQD/fKY+tXNSg==", "dev": true }, "eslint-import-resolver-node": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", "dev": true, "requires": { "debug": "^2.6.9", "resolve": "^1.5.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } } } }, "eslint-module-utils": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", "dev": true, "requires": { "debug": "^2.6.8", "pkg-dir": "^2.0.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } } } }, "eslint-plugin-es": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.4.0.tgz", "integrity": "sha512-XfFmgFdIUDgvaRAlaXUkxrRg5JSADoRC8IkKLc/cISeR3yHVMefFHQZpcyXXEUUPHfy5DwviBcrfqlyqEwlQVw==", "dev": true, "requires": { "eslint-utils": "^1.3.0", "regexpp": "^2.0.1" } }, "eslint-plugin-import": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", "dev": true, "requires": { "contains-path": "^0.1.0", "debug": "^2.6.8", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.1", "eslint-module-utils": "^2.2.0", "has": "^1.0.1", "lodash": "^4.17.4", "minimatch": "^3.0.3", "read-pkg-up": "^2.0.0", "resolve": "^1.6.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "doctrine": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", "dev": true, "requires": { "esutils": "^2.0.2", "isarray": "^1.0.0" } }, "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "path-type": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", "dev": true, "requires": { "pify": "^2.0.0" } }, "read-pkg": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", "dev": true, "requires": { "load-json-file": "^2.0.0", "normalize-package-data": "^2.3.2", "path-type": "^2.0.0" } }, "read-pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^2.0.0" } } } }, "eslint-plugin-node": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-7.0.1.tgz", "integrity": "sha512-lfVw3TEqThwq0j2Ba/Ckn2ABdwmL5dkOgAux1rvOk6CO7A6yGyPI2+zIxN6FyNkp1X1X/BSvKOceD6mBWSj4Yw==", "dev": true, "requires": { "eslint-plugin-es": "^1.3.1", "eslint-utils": "^1.3.1", "ignore": "^4.0.2", "minimatch": "^3.0.4", "resolve": "^1.8.1", "semver": "^5.5.0" }, "dependencies": { "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "eslint-plugin-promise": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz", "integrity": "sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg==", "dev": true }, "eslint-plugin-react": { "version": "7.11.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz", "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==", "dev": true, "requires": { "array-includes": "^3.0.3", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.0.1", "prop-types": "^15.6.2" } }, "eslint-plugin-standard": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz", "integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==", "dev": true }, "eslint-scope": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-utils": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "dev": true }, "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, "esm": { "version": "3.2.25", "resolved": "https://registry.npmjs.org/esm/-/esm-3.2.25.tgz", "integrity": "sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA==", "dev": true }, "espree": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", "dev": true, "requires": { "acorn": "^6.0.2", "acorn-jsx": "^5.0.0", "eslint-visitor-keys": "^1.0.0" } }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", "dev": true }, "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, "requires": { "estraverse": "^4.0.0" } }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", "dev": true, "requires": { "estraverse": "^4.1.0" } }, "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, "events-to-array": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/events-to-array/-/events-to-array-1.1.2.tgz", "integrity": "sha1-LUH1Y+H+QA7Uli/hpNXGp1Od9/Y=", "dev": true }, "execa": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { "cross-spawn": "^6.0.0", "get-stream": "^4.0.0", "is-stream": "^1.1.0", "npm-run-path": "^2.0.0", "p-finally": "^1.0.0", "signal-exit": "^3.0.0", "strip-eof": "^1.0.0" }, "dependencies": { "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", "path-key": "^2.0.1", "semver": "^5.5.0", "shebang-command": "^1.2.0", "which": "^1.2.9" } }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", "dev": true, "requires": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", "tmp": "^0.0.33" } }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", "dev": true }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, "figgy-pudding": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==" }, "figures": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.0.0.tgz", "integrity": "sha512-HKri+WoWoUgr83pehn/SIgLOMZ9nAWC6dcGj26RY2R4F50u4+RTUz0RCrUlOV3nKRAICW1UGzyb+kcX2qK1S/g==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", "dev": true, "requires": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" } }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", "dev": true, "requires": { "commondir": "^1.0.1", "make-dir": "^2.0.0", "pkg-dir": "^3.0.0" }, "dependencies": { "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "pkg-dir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", "dev": true, "requires": { "find-up": "^3.0.0" } } } }, "find-root": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==", "dev": true }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { "path-exists": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "flat-cache": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.4.tgz", "integrity": "sha512-VwyB3Lkgacfik2vhqR4uv2rvebqmDvFu4jlN/C1RzWoJEo8I7z4Q404oiqYCkq41mni8EzQnm95emU9seckwtg==", "dev": true, "requires": { "circular-json": "^0.3.1", "graceful-fs": "^4.1.2", "rimraf": "~2.6.2", "write": "^0.2.1" } }, "flush-write-stream": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.4" } }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", "integrity": "sha1-T9ca0t/elnibmApcCilZN8svXOk=", "dev": true, "requires": { "cross-spawn": "^4", "signal-exit": "^3.0.0" }, "dependencies": { "cross-spawn": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" } }, "lru-cache": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" } }, "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", "dev": true } } }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", "dev": true }, "form-data": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, "from2": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.0" } }, "fs-access": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { "null-check": "^1.0.0" } }, "fs-exists-cached": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-exists-cached/-/fs-exists-cached-1.0.0.tgz", "integrity": "sha1-zyVVTKBQ3EmuZla0HeQiWJidy84=", "dev": true }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", "requires": { "graceful-fs": "^4.1.2", "iferr": "^0.1.5", "imurmurhash": "^0.1.4", "readable-stream": "1 || 2" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, "function-loop": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/function-loop/-/function-loop-1.0.2.tgz", "integrity": "sha512-Iw4MzMfS3udk/rqxTiDDCllhGwlOrsr50zViTOO/W6lS/9y6B1J0BD2VZzrnWUYBJsl3aeqjgR5v7bWWhZSYbA==", "dev": true }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, "get-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", "dev": true }, "get-pkg-repo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "meow": "^3.3.0", "normalize-package-data": "^2.3.0", "parse-github-repo-url": "^1.3.0", "through2": "^2.0.0" }, "dependencies": { "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", "dev": true }, "camelcase-keys": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { "camelcase": "^2.0.0", "map-obj": "^1.0.0" } }, "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", "dev": true }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { "repeating": "^2.0.0" } }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", "dev": true }, "meow": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { "camelcase-keys": "^2.0.0", "decamelize": "^1.1.2", "loud-rejection": "^1.0.0", "map-obj": "^1.0.1", "minimist": "^1.1.3", "normalize-package-data": "^2.3.4", "object-assign": "^4.0.1", "read-pkg-up": "^1.0.1", "redent": "^1.0.0", "trim-newlines": "^1.0.0" } }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "redent": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { "indent-string": "^2.1.0", "strip-indent": "^1.0.1" } }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { "get-stdin": "^4.0.1" } }, "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", "dev": true } } }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", "dev": true }, "get-stream": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" } }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { "assert-plus": "^1.0.0" } }, "git-raw-commits": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", "dev": true, "requires": { "dargs": "^4.0.1", "lodash.template": "^4.0.2", "meow": "^4.0.0", "split2": "^2.0.0", "through2": "^2.0.0" } }, "git-remote-origin-url": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", "dev": true, "requires": { "gitconfiglocal": "^1.0.0", "pify": "^2.3.0" } }, "git-semver-tags": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.2.tgz", "integrity": "sha512-34lMF7Yo1xEmsK2EkbArdoU79umpvm0MfzaDkSNYSJqtM5QLAVTPWgpiXSVI5o/O9EvZPSrP4Zvnec/CqhSd5w==", "dev": true, "requires": { "meow": "^4.0.0", "semver": "^5.5.0" }, "dependencies": { "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "gitconfiglocal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", "dev": true, "requires": { "ini": "^1.3.2" } }, "glob": { "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "globals": { "version": "11.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.4.0.tgz", "integrity": "sha512-Dyzmifil8n/TmSqYDEXbm+C8yitzJQqQIlJQLNRMwa+BOUJpRC19pyVeN12JAjt61xonvXjtff+hJruTRXn5HA==", "dev": true }, "graceful-fs": { "version": "4.1.15", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "growl": { "version": "1.10.5", "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "handlebars": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", "dev": true, "requires": { "neo-async": "^2.6.0", "optimist": "^0.6.1", "source-map": "^0.6.1", "uglify-js": "^3.1.4" } }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" }, "dependencies": { "ajv": { "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true } } }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { "function-bind": "^1.1.1" } }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", "dev": true }, "hasha": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hasha/-/hasha-3.0.0.tgz", "integrity": "sha1-UqMvq4Vp1BymmmH/GiFPjrfIvTk=", "dev": true, "requires": { "is-stream": "^1.0.1" } }, "hosted-git-info": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.4.2.tgz", "integrity": "sha1-AHa59GonBQbduq6lZJaJdGBhKmc=", "dev": true }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", "sshpk": "^1.7.0" } }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } }, "iferr": { "version": "0.1.5", "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=" }, "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "indent-string": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, "inquirer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-5.2.0.tgz", "integrity": "sha512-E9BmnJbAKLPGonz0HeWHtbKf+EeSP93paWO3ZYoUpq/aowXvYGjjCSuashhXPpzbArIjBbji39THkxTz9ZeEUQ==", "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", "cli-cursor": "^2.1.0", "cli-width": "^2.0.0", "external-editor": "^2.1.0", "figures": "^2.0.0", "lodash": "^4.3.0", "mute-stream": "0.0.7", "run-async": "^2.2.0", "rxjs": "^5.5.2", "string-width": "^2.1.0", "strip-ansi": "^4.0.0", "through": "^2.3.6" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "figures": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", "dev": true }, "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, "is-builtin-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { "builtin-modules": "^1.0.0" } }, "is-callable": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", "dev": true }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, "is-finite": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "is-fullwidth-code-point": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { "number-is-nan": "^1.0.0" } }, "is-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, "is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", "dev": true }, "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", "dev": true }, "is-regex": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", "dev": true, "requires": { "has": "^1.0.1" } }, "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", "dev": true }, "is-stream": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, "is-symbol": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", "dev": true, "requires": { "has-symbols": "^1.0.0" } }, "is-text-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", "dev": true, "requires": { "text-extensions": "^2.0.0" } }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", "dev": true }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", "dev": true }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz", "integrity": "sha512-8aXznuEPCJvGnMSRft4udDRDtb1V3pkQkMMI5LI+6HuQz5oQ4J2UFn1H82raA3qJtyOLkkwVqICBQkjnGtn5mA==", "dev": true }, "istanbul-lib-hook": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-2.0.7.tgz", "integrity": "sha512-vrRztU9VRRFDyC+aklfLoeXyNdTfga2EI3udDGn4cZ6fpSXpHLV9X6CHvfoMCPtggg8zvDDmC4b9xfu0z6/llA==", "dev": true, "requires": { "append-transform": "^1.0.0" } }, "istanbul-lib-instrument": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.3.0.tgz", "integrity": "sha512-5nnIN4vo5xQZHdXno/YDXJ0G+I3dAm4XgzfSVTPLQpj/zAV2dV6Juy0yaf10/zrJOJeHoN3fraFe+XRq2bFVZA==", "dev": true, "requires": { "@babel/generator": "^7.4.0", "@babel/parser": "^7.4.3", "@babel/template": "^7.4.0", "@babel/traverse": "^7.4.3", "@babel/types": "^7.4.0", "istanbul-lib-coverage": "^2.0.5", "semver": "^6.0.0" }, "dependencies": { "semver": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", "dev": true } } }, "istanbul-lib-report": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-2.0.8.tgz", "integrity": "sha512-fHBeG573EIihhAblwgxrSenp0Dby6tJMFR/HvlerBsrCTD5bkUuoNtn3gVh29ZCS824cGGBPn7Sg7cNk+2xUsQ==", "dev": true, "requires": { "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "supports-color": "^6.1.0" }, "dependencies": { "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", "dev": true, "requires": { "has-flag": "^3.0.0" } } } }, "istanbul-lib-source-maps": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-3.0.6.tgz", "integrity": "sha512-R47KzMtDJH6X4/YW9XTx+jrLnZnscW4VpNN+1PViSYTejLVPWv7oov+Duf8YQSPyVRUvueQqz1TcsC6mooZTXw==", "dev": true, "requires": { "debug": "^4.1.1", "istanbul-lib-coverage": "^2.0.5", "make-dir": "^2.1.0", "rimraf": "^2.6.3", "source-map": "^0.6.1" }, "dependencies": { "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", "dev": true, "requires": { "ms": "^2.1.1" } }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "istanbul-reports": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.6.tgz", "integrity": "sha512-SKi4rnMyLBKe0Jy2uUdx28h8oG7ph2PPuQPvIAh31d+Ci+lSiEu4C+h3oBPuJ9+mPKhOyW0M8gY4U5NM1WLeXA==", "dev": true, "requires": { "handlebars": "^4.1.2" } }, "js-tokens": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", "dev": true }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" } }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", "dev": true }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", "dev": true }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, "jsonparse": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", "dev": true }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", "json-schema": "0.2.3", "verror": "1.10.0" } }, "jsx-ast-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", "dev": true, "requires": { "array-includes": "^3.0.3" } }, "lcid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", "dev": true, "requires": { "invert-kv": "^1.0.0" } }, "lcov-parse": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-0.0.10.tgz", "integrity": "sha1-GwuP+ayceIklBYK3C3ExXZ2m2aM=", "dev": true }, "levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "load-json-file": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "strip-bom": "^3.0.0" } }, "locate-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", "dev": true, "requires": { "p-locate": "^2.0.0", "path-exists": "^3.0.0" }, "dependencies": { "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true } } }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, "lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", "dev": true }, "lodash.ismatch": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", "dev": true }, "lodash.template": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", "dev": true, "requires": { "lodash._reinterpolate": "~3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", "dev": true, "requires": { "lodash._reinterpolate": "~3.0.0" } }, "log-driver": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", "dev": true }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } }, "loud-rejection": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { "currently-unhandled": "^0.4.1", "signal-exit": "^3.0.0" } }, "lru-cache": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { "yallist": "^3.0.2" } }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", "dev": true, "requires": { "pify": "^4.0.1", "semver": "^5.6.0" }, "dependencies": { "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "semver": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", "dev": true } } }, "make-error": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", "dev": true }, "map-age-cleaner": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", "dev": true, "requires": { "p-defer": "^1.0.0" } }, "map-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", "dev": true }, "mem": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", "mimic-fn": "^2.0.0", "p-is-promise": "^2.0.0" }, "dependencies": { "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true } } }, "meow": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", "dev": true, "requires": { "camelcase-keys": "^4.0.0", "decamelize-keys": "^1.0.0", "loud-rejection": "^1.0.0", "minimist": "^1.1.3", "minimist-options": "^3.0.1", "normalize-package-data": "^2.3.4", "read-pkg-up": "^3.0.0", "redent": "^2.0.0", "trim-newlines": "^2.0.0" }, "dependencies": { "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" } }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } }, "read-pkg-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", "dev": true, "requires": { "find-up": "^2.0.0", "read-pkg": "^3.0.0" } } } }, "merge-source-map": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", "dev": true, "requires": { "source-map": "^0.6.1" } }, "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", "dev": true }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "dev": true, "requires": { "mime-db": "1.40.0" } }, "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "minimist-options": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", "dev": true, "requires": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0" } }, "minipass": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", "dev": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" } }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", "requires": { "concat-stream": "^1.5.0", "duplexify": "^3.4.2", "end-of-stream": "^1.1.0", "flush-write-stream": "^1.0.0", "from2": "^2.1.0", "parallel-transform": "^1.1.0", "pump": "^3.0.0", "pumpify": "^1.3.3", "stream-each": "^1.1.0", "through2": "^2.0.0" } }, "mkdirp": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" } }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", "dev": true }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", "requires": { "aproba": "^1.1.1", "copy-concurrently": "^1.0.0", "fs-write-stream-atomic": "^1.0.8", "mkdirp": "^0.5.1", "rimraf": "^2.5.4", "run-queue": "^1.0.3" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", "dev": true }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", "dev": true }, "nested-error-stacks": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/nested-error-stacks/-/nested-error-stacks-2.1.0.tgz", "integrity": "sha512-AO81vsIO1k1sM4Zrd6Hu7regmJN1NSiAja10gc4bX3F0wd+9rQmcuHQaHVQCYIEC8iFXnE+mavh23GOt7wBgug==", "dev": true }, "nice-try": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.4.tgz", "integrity": "sha512-2NpiFHqC87y/zFke0fC0spBXL3bBsoh/p5H1EFhshxjCR5+0g2d6BiXbUFz9v1sAcxsk2htp2eQnNIci2dIYcA==", "dev": true }, "normalize-package-data": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.3.6.tgz", "integrity": "sha1-SY+kIMlkAfeHQCuiHmAN75+YH/8=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" } }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", "dev": true, "requires": { "path-key": "^2.0.0" } }, "null-check": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", "dev": true }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "nyc": { "version": "14.1.1", "resolved": "https://registry.npmjs.org/nyc/-/nyc-14.1.1.tgz", "integrity": "sha512-OI0vm6ZGUnoGZv/tLdZ2esSVzDwUC88SNs+6JoSOMVxA+gKMB8Tk7jBwgemLx4O40lhhvZCVw1C+OYLOBOPXWw==", "dev": true, "requires": { "archy": "^1.0.0", "caching-transform": "^3.0.2", "convert-source-map": "^1.6.0", "cp-file": "^6.2.0", "find-cache-dir": "^2.1.0", "find-up": "^3.0.0", "foreground-child": "^1.5.6", "glob": "^7.1.3", "istanbul-lib-coverage": "^2.0.5", "istanbul-lib-hook": "^2.0.7", "istanbul-lib-instrument": "^3.3.0", "istanbul-lib-report": "^2.0.8", "istanbul-lib-source-maps": "^3.0.6", "istanbul-reports": "^2.2.4", "js-yaml": "^3.13.1", "make-dir": "^2.1.0", "merge-source-map": "^1.1.0", "resolve-from": "^4.0.0", "rimraf": "^2.6.3", "signal-exit": "^3.0.2", "spawn-wrap": "^1.4.2", "test-exclude": "^5.2.3", "uuid": "^3.3.2", "yargs": "^13.2.2", "yargs-parser": "^13.0.0" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cliui": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", "dev": true, "requires": { "string-width": "^3.1.0", "strip-ansi": "^5.2.0", "wrap-ansi": "^5.1.0" } }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": false, "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { "invert-kv": "^2.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", "mem": "^4.0.0" } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } }, "which-module": { "version": "2.0.0", "resolved": false, "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "wrap-ansi": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "string-width": "^3.0.0", "strip-ansi": "^5.0.0" } }, "yargs": { "version": "13.2.4", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.1.0" } }, "yargs-parser": { "version": "13.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true }, "object-keys": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } }, "onetime": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { "mimic-fn": "^1.0.0" } }, "opener": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", "dev": true }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { "minimist": "~0.0.1", "wordwrap": "~0.0.2" }, "dependencies": { "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", "dev": true } } }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "wordwrap": "~1.0.0" } }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { "lcid": "^1.0.0" } }, "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, "own-or": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/own-or/-/own-or-1.0.0.tgz", "integrity": "sha1-Tod/vtqaLsgAD7wLyuOWRe6L+Nw=", "dev": true }, "own-or-env": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/own-or-env/-/own-or-env-1.0.1.tgz", "integrity": "sha512-y8qULRbRAlL6x2+M0vIe7jJbJx/kmUTzYonRAa2ayesR2qWLswninkVyeJe4x3IEXhdgoNodzjQRKAoEs6Fmrw==", "dev": true, "requires": { "own-or": "^1.0.0" } }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", "dev": true }, "p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, "p-is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", "dev": true }, "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", "dev": true, "requires": { "p-try": "^1.0.0" } }, "p-locate": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { "p-limit": "^1.1.0" } }, "p-try": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", "dev": true }, "package-hash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-3.0.0.tgz", "integrity": "sha512-lOtmukMDVvtkL84rJHI7dpTYq+0rli8N2wlnqUcBuDWCfVhRUfOmnR9SsoHFMLpACvEV60dX7rd0rFaYDZI+FA==", "dev": true, "requires": { "graceful-fs": "^4.1.15", "hasha": "^3.0.0", "lodash.flattendeep": "^4.4.0", "release-zalgo": "^1.0.0" } }, "parallel-transform": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", "requires": { "cyclist": "~0.2.2", "inherits": "^2.0.3", "readable-stream": "^2.1.5" } }, "parse-github-repo-url": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", "dev": true }, "parse-json": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { "error-ex": "^1.2.0" } }, "path-exists": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { "pinkie-promise": "^2.0.0" } }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", "dev": true }, "path-key": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", "dev": true }, "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", "dev": true }, "path-type": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "pify": "^2.0.0", "pinkie-promise": "^2.0.0" } }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", "dev": true }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { "pinkie": "^2.0.0" } }, "pkg-conf": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz", "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=", "dev": true, "requires": { "find-up": "^2.0.0", "load-json-file": "^4.0.0" }, "dependencies": { "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true } } }, "pkg-config": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/pkg-config/-/pkg-config-1.1.1.tgz", "integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=", "dev": true, "requires": { "debug-log": "^1.0.0", "find-root": "^1.0.0", "xtend": "^4.0.1" } }, "pkg-dir": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", "dev": true, "requires": { "find-up": "^2.1.0" }, "dependencies": { "find-up": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", "dev": true, "requires": { "locate-path": "^2.0.0" } } } }, "platform": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.4.tgz", "integrity": "sha1-bw+xftqqSPIUQrOpdcBjEw8cPr0=", "dev": true }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", "dev": true }, "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, "process-nextick-args": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=" }, "prop-types": { "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", "react-is": "^16.8.1" } }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, "psl": { "version": "1.1.32", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz", "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g==", "dev": true }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "pumpify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz", "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", "requires": { "duplexify": "^3.5.3", "inherits": "^2.0.3", "pump": "^2.0.0" }, "dependencies": { "pump": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } } } }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", "dev": true }, "quick-lru": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", "dev": true }, "react-is": { "version": "16.8.6", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", "dev": true }, "read-pkg": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { "load-json-file": "^1.0.0", "normalize-package-data": "^2.3.2", "path-type": "^1.0.0" }, "dependencies": { "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^2.2.0", "pify": "^2.0.0", "pinkie-promise": "^2.0.0", "strip-bom": "^2.0.0" } }, "strip-bom": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { "is-utf8": "^0.2.0" } } } }, "read-pkg-up": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { "find-up": "^1.0.0", "read-pkg": "^1.0.0" } }, "readable-stream": { "version": "2.2.9", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.9.tgz", "integrity": "sha1-z3jsb0ptHrQ9JkiMrJfwQudLf8g=", "requires": { "buffer-shims": "~1.0.0", "core-util-is": "~1.0.0", "inherits": "~2.0.1", "isarray": "~1.0.0", "process-nextick-args": "~1.0.6", "string_decoder": "~1.0.0", "util-deprecate": "~1.0.1" } }, "redent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", "dev": true, "requires": { "indent-string": "^3.0.0", "strip-indent": "^2.0.0" } }, "regexpp": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", "dev": true }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", "dev": true, "requires": { "es6-error": "^4.0.1" } }, "repeating": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { "is-finite": "^1.0.0" } }, "request": { "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", "caseless": "~0.12.0", "combined-stream": "~1.0.6", "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", "har-validator": "~5.1.0", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", "json-stringify-safe": "~5.0.1", "mime-types": "~2.1.19", "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" } }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "require-inject": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/require-inject/-/require-inject-1.4.4.tgz", "integrity": "sha512-5Y5ctRN84+I4iOZO61gm+48tgP/6Hcd3VZydkaEM3MCuOvnHRsTJYQBOc01faI/Z9at5nsCAJVHhlfPA6Pc0Og==", "dev": true, "requires": { "caller": "^1.0.1" } }, "require-main-filename": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { "caller-path": "^0.1.0", "resolve-from": "^1.0.0" } }, "resolve": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.0.tgz", "integrity": "sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", "dev": true }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", "dev": true, "requires": { "onetime": "^2.0.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "requires": { "glob": "^7.1.3" } }, "run-async": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", "dev": true, "requires": { "is-promise": "^2.1.0" } }, "run-parallel": { "version": "1.1.9", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", "dev": true }, "run-queue": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", "requires": { "aproba": "^1.1.1" } }, "rxjs": { "version": "5.5.12", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", "dev": true, "requires": { "symbol-observable": "1.0.1" } }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, "semver": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, "shebang-command": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, "requires": { "shebang-regex": "^1.0.0" } }, "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", "dev": true }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" }, "dependencies": { "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true } } }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, "source-map-support": { "version": "0.5.12", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz", "integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==", "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "spawn-wrap": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.2.tgz", "integrity": "sha512-vMwR3OmmDhnxCVxM8M+xO/FtIp6Ju/mNaDfCMMW7FDcLRTPFWUswec4LXJHTJE2hwTI9O0YBfygu4DalFl7Ylg==", "dev": true, "requires": { "foreground-child": "^1.5.6", "mkdirp": "^0.5.0", "os-homedir": "^1.0.1", "rimraf": "^2.6.2", "signal-exit": "^3.0.2", "which": "^1.3.0" } }, "spdx-correct": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", "dev": true, "requires": { "spdx-license-ids": "^1.0.2" } }, "spdx-expression-parse": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", "dev": true }, "spdx-license-ids": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", "dev": true }, "split": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", "dev": true, "requires": { "through": "2" } }, "split2": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", "dev": true, "requires": { "through2": "^2.0.2" } }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", "dev": true }, "sshpk": { "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", "bcrypt-pbkdf": "^1.0.0", "dashdash": "^1.12.0", "ecc-jsbn": "~0.1.1", "getpass": "^0.1.1", "jsbn": "~0.1.0", "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" } }, "ssri": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", "requires": { "figgy-pudding": "^3.5.1" } }, "stack-utils": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.2.tgz", "integrity": "sha512-MTX+MeG5U994cazkjd/9KNAapsHnibjMLnfXodlkXw76JEea0UiNzrqidzo1emMwk7w5Qhc9jd4Bn9TBb1MFwA==", "dev": true }, "standard": { "version": "12.0.1", "resolved": "https://registry.npmjs.org/standard/-/standard-12.0.1.tgz", "integrity": "sha512-UqdHjh87OG2gUrNCSM4QRLF5n9h3TFPwrCNyVlkqu31Hej0L/rc8hzKqVvkb2W3x0WMq7PzZdkLfEcBhVOR6lg==", "dev": true, "requires": { "eslint": "~5.4.0", "eslint-config-standard": "12.0.0", "eslint-config-standard-jsx": "6.0.2", "eslint-plugin-import": "~2.14.0", "eslint-plugin-node": "~7.0.1", "eslint-plugin-promise": "~4.0.0", "eslint-plugin-react": "~7.11.1", "eslint-plugin-standard": "~4.0.0", "standard-engine": "~9.0.0" } }, "standard-engine": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-9.0.0.tgz", "integrity": "sha512-ZfNfCWZ2Xq67VNvKMPiVMKHnMdvxYzvZkf1AH8/cw2NLDBm5LRsxMqvEJpsjLI/dUosZ3Z1d6JlHDp5rAvvk2w==", "dev": true, "requires": { "deglob": "^2.1.0", "get-stdin": "^6.0.0", "minimist": "^1.1.0", "pkg-conf": "^2.0.0" }, "dependencies": { "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } } }, "standard-version": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-6.0.1.tgz", "integrity": "sha512-+09AwTbyLKyUwefiZSccgarp24okvH9A229NOVSpYTKWcxBxqZqdYmtQaJ8UET9mjPXRxP84vonJU4YMqCyBTQ==", "dev": true, "requires": { "chalk": "2.4.2", "conventional-changelog": "3.1.8", "conventional-changelog-config-spec": "1.0.0", "conventional-recommended-bump": "5.0.0", "detect-indent": "6.0.0", "detect-newline": "3.0.0", "dotgitignore": "2.1.0", "figures": "3.0.0", "find-up": "3.0.0", "fs-access": "1.0.1", "git-semver-tags": "2.0.2", "semver": "6.0.0", "stringify-package": "1.0.0", "yargs": "13.2.2" }, "dependencies": { "ansi-regex": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "dev": true }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "lcid": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { "invert-kv": "^2.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "os-locale": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { "execa": "^1.0.0", "lcid": "^2.0.0", "mem": "^4.0.0" } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, "semver": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.0.0.tgz", "integrity": "sha512-0UewU+9rFapKFnlbirLi3byoOuhrSsli/z/ihNnvM24vgF+8sNBiI1LZPBSH9wJKUwaUbw+s3hToDLCXkrghrQ==", "dev": true }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { "emoji-regex": "^7.0.1", "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^5.1.0" } }, "strip-ansi": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { "ansi-regex": "^4.1.0" } }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, "yargs": { "version": "13.2.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", "dev": true, "requires": { "cliui": "^4.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "os-locale": "^3.1.0", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^13.0.0" } }, "yargs-parser": { "version": "13.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "stream-each": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", "requires": { "end-of-stream": "^1.1.0", "stream-shift": "^1.0.0" } }, "stream-shift": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", "strip-ansi": "^3.0.0" } }, "string_decoder": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.0.tgz", "integrity": "sha1-8G9BFXtmTYYGn4S9vcmw2KsoFmc=", "requires": { "buffer-shims": "~1.0.0" } }, "stringify-package": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.0.tgz", "integrity": "sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g==", "dev": true }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { "ansi-regex": "^2.0.0" } }, "strip-bom": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, "strip-eof": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, "strip-indent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", "dev": true }, "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "requires": { "has-flag": "^3.0.0" } }, "symbol-observable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=", "dev": true }, "table": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/table/-/table-4.0.3.tgz", "integrity": "sha512-S7rnFITmBH1EnyKcvxBh1LjYeQMmnZtCXSEbHcH6S0NoKit24ZuFO/T1vDcLdYsLQkM188PVVhQmzKIuThNkKg==", "dev": true, "requires": { "ajv": "^6.0.1", "ajv-keywords": "^3.0.0", "chalk": "^2.1.0", "lodash": "^4.17.4", "slice-ansi": "1.0.0", "string-width": "^2.1.1" }, "dependencies": { "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", "dev": true }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", "strip-ansi": "^4.0.0" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", "dev": true, "requires": { "ansi-regex": "^3.0.0" } } } }, "tacks": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/tacks/-/tacks-1.3.0.tgz", "integrity": "sha512-jpQhdKlYom3cohYmjSYqny9Ie8QJr6OYe4wdyu/nEgfiIQpOvLwq72vCRucg9+jUlnspnKvL5HASnmkxOf3DXQ==", "dev": true, "requires": { "@iarna/cli": "^2.0.0", "mkdirp": "^0.5.1", "rimraf": "^2.6.2" }, "dependencies": { "@iarna/cli": { "version": "2.0.0", "bundled": true, "dev": true, "requires": { "signal-exit": "^3.0.2" } }, "balanced-match": { "version": "1.0.0", "bundled": true, "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "concat-map": { "version": "0.0.1", "bundled": true, "dev": true }, "fs.realpath": { "version": "1.0.0", "bundled": true, "dev": true }, "glob": { "version": "7.1.1", "bundled": true, "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.0.2", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "inflight": { "version": "1.0.6", "bundled": true, "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" } }, "inherits": { "version": "2.0.3", "bundled": true, "dev": true }, "minimatch": { "version": "3.0.3", "bundled": true, "dev": true, "requires": { "brace-expansion": "^1.0.0" } }, "minimist": { "version": "0.0.8", "bundled": true, "dev": true }, "mkdirp": { "version": "0.5.1", "bundled": true, "dev": true, "requires": { "minimist": "0.0.8" } }, "once": { "version": "1.4.0", "bundled": true, "dev": true, "requires": { "wrappy": "1" } }, "path-is-absolute": { "version": "1.0.1", "bundled": true, "dev": true }, "rimraf": { "version": "2.6.2", "bundled": true, "dev": true, "requires": { "glob": "^7.0.5" } }, "signal-exit": { "version": "3.0.2", "bundled": true, "dev": true }, "wrappy": { "version": "1.0.2", "bundled": true, "dev": true } } }, "tap": { "version": "12.7.0", "resolved": "https://registry.npmjs.org/tap/-/tap-12.7.0.tgz", "integrity": "sha512-SjglJmRv0pqrQQ7d5ZBEY8ZOqv3nYDBXEX51oyycOH7piuhn82JKT/yDNewwmOsodTD/RZL9MccA96EjDgK+Eg==", "dev": true, "requires": { "bind-obj-methods": "^2.0.0", "browser-process-hrtime": "^1.0.0", "capture-stack-trace": "^1.0.0", "clean-yaml-object": "^0.1.0", "color-support": "^1.1.0", "coveralls": "^3.0.2", "domain-browser": "^1.2.0", "esm": "^3.2.5", "foreground-child": "^1.3.3", "fs-exists-cached": "^1.0.0", "function-loop": "^1.0.1", "glob": "^7.1.3", "isexe": "^2.0.0", "js-yaml": "^3.13.1", "minipass": "^2.3.5", "mkdirp": "^0.5.1", "nyc": "^14.0.0", "opener": "^1.5.1", "os-homedir": "^1.0.2", "own-or": "^1.0.0", "own-or-env": "^1.0.1", "rimraf": "^2.6.3", "signal-exit": "^3.0.0", "source-map-support": "^0.5.10", "stack-utils": "^1.0.2", "tap-mocha-reporter": "^3.0.9", "tap-parser": "^7.0.0", "tmatch": "^4.0.0", "trivial-deferred": "^1.0.1", "ts-node": "^8.0.2", "tsame": "^2.0.1", "typescript": "^3.3.3", "write-file-atomic": "^2.4.2", "yapool": "^1.0.0" } }, "tap-mocha-reporter": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-3.0.9.tgz", "integrity": "sha512-VO07vhC9EG27EZdOe7bWBj1ldbK+DL9TnRadOgdQmiQOVZjFpUEQuuqO7+rNSO2kfmkq5hWeluYXDWNG/ytXTQ==", "dev": true, "requires": { "color-support": "^1.1.0", "debug": "^2.1.3", "diff": "^1.3.2", "escape-string-regexp": "^1.0.3", "glob": "^7.0.5", "js-yaml": "^3.3.1", "readable-stream": "^2.1.5", "tap-parser": "^5.1.0", "unicode-length": "^1.0.0" }, "dependencies": { "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { "ms": "2.0.0" } }, "tap-parser": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-5.4.0.tgz", "integrity": "sha512-BIsIaGqv7uTQgTW1KLTMNPSEQf4zDDPgYOBRdgOfuB+JFOLRBfEu6cLa/KvMvmqggu1FKXDfitjLwsq4827RvA==", "dev": true, "requires": { "events-to-array": "^1.0.1", "js-yaml": "^3.2.7", "readable-stream": "^2" } } } }, "tap-parser": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-7.0.0.tgz", "integrity": "sha512-05G8/LrzqOOFvZhhAk32wsGiPZ1lfUrl+iV7+OkKgfofZxiceZWMHkKmow71YsyVQ8IvGBP2EjcIjE5gL4l5lA==", "dev": true, "requires": { "events-to-array": "^1.0.1", "js-yaml": "^3.2.7", "minipass": "^2.2.0" } }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", "integrity": "sha512-M+oxtseCFO3EDtAaGH7iiej3CBkzXqFMbzqYAACdzKui4eZA+pq3tZEwChvOdNfa7xxy8BfbmgJSIr43cC/+2g==", "dev": true, "requires": { "glob": "^7.1.3", "minimatch": "^3.0.4", "read-pkg-up": "^4.0.0", "require-main-filename": "^2.0.0" }, "dependencies": { "find-up": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" } }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", "dev": true, "requires": { "graceful-fs": "^4.1.2", "parse-json": "^4.0.0", "pify": "^3.0.0", "strip-bom": "^3.0.0" } }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "p-limit": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" } }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", "dev": true, "requires": { "error-ex": "^1.3.1", "json-parse-better-errors": "^1.0.1" } }, "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "path-type": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", "dev": true, "requires": { "pify": "^3.0.0" } }, "pify": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", "dev": true }, "read-pkg": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", "dev": true, "requires": { "load-json-file": "^4.0.0", "normalize-package-data": "^2.3.2", "path-type": "^3.0.0" } }, "read-pkg-up": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz", "integrity": "sha512-6etQSH7nJGsK0RbG/2TeDzZFa8shjQ1um+SwQQ5cwKy0dhSXdOncEhb1CPpvQG4h7FyOV6EB6YlV0yJvZQNAkA==", "dev": true, "requires": { "find-up": "^3.0.0", "read-pkg": "^3.0.0" } }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true } } }, "text-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.0.0.tgz", "integrity": "sha512-F91ZqLgvi1E0PdvmxMgp+gcf6q8fMH7mhdwWfzXnl1k+GbpQDmi8l7DzLC5JTASKbwpY3TfxajAUzAXcv2NmsQ==", "dev": true }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", "dev": true }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "requires": { "readable-stream": "^2.1.5", "xtend": "~4.0.1" } }, "tmatch": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/tmatch/-/tmatch-4.0.0.tgz", "integrity": "sha512-Ynn2Gsp+oCvYScQXeV+cCs7citRDilq0qDXA6tuvFwDgiYyyaq7D5vKUlAPezzZR5NDobc/QMeN6e5guOYmvxg==", "dev": true }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { "os-tmpdir": "~1.0.2" } }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" }, "dependencies": { "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true } } }, "trim-newlines": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", "dev": true }, "trim-off-newlines": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", "dev": true }, "trim-right": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "trivial-deferred": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/trivial-deferred/-/trivial-deferred-1.0.1.tgz", "integrity": "sha1-N21NKdlR1jaKb3oK6FwvTV4GWPM=", "dev": true }, "ts-node": { "version": "8.3.0", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.3.0.tgz", "integrity": "sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==", "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.6", "yn": "^3.0.0" }, "dependencies": { "diff": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", "dev": true } } }, "tsame": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/tsame/-/tsame-2.0.1.tgz", "integrity": "sha512-jxyxgKVKa4Bh5dPcO42TJL22lIvfd9LOVJwdovKOnJa4TLLrHxquK+DlGm4rkGmrcur+GRx+x4oW00O2pY/fFw==", "dev": true }, "tunnel-agent": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { "prelude-ls": "~1.1.2" } }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, "typescript": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.5.2.tgz", "integrity": "sha512-7KxJovlYhTX5RaRbUdkAXN1KUZ8PwWlTzQdHV6xNqvuFOs7+WBo10TQUqT19Q/Jz2hk5v9TQDIhyLhhJY4p5AA==", "dev": true }, "uglify-js": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz", "integrity": "sha512-W+jrUHJr3DXKhrsS7NUVxn3zqMOFn0hL/Ei6v0anCIMoKC93TjcflTagwIHLW7SfMFfiQuktQyFVCFHGUE0+yg==", "dev": true, "optional": true, "requires": { "commander": "~2.20.0", "source-map": "~0.6.1" } }, "unicode-length": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-1.0.3.tgz", "integrity": "sha1-Wtp6f+1RhBpBijKM8UlHisg1irs=", "dev": true, "requires": { "punycode": "^1.3.2", "strip-ansi": "^3.0.1" }, "dependencies": { "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", "dev": true } } }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", "dev": true }, "unique-filename": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", "requires": { "unique-slug": "^2.0.0" } }, "unique-slug": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", "requires": { "imurmurhash": "^0.1.4" } }, "uri-js": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "dev": true, "requires": { "punycode": "^2.1.0" } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", "dev": true }, "validate-npm-package-license": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", "dev": true, "requires": { "spdx-correct": "~1.0.0", "spdx-expression-parse": "~1.0.0" } }, "verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", "extsprintf": "^1.2.0" } }, "weallbehave": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/weallbehave/-/weallbehave-1.2.0.tgz", "integrity": "sha1-hR79VUAlo06O8kmeR4DEQHcyFhs=", "dev": true, "requires": { "yargs": "^6.6.0" } }, "weallcontribute": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/weallcontribute/-/weallcontribute-1.0.9.tgz", "integrity": "sha512-VQMH5fGoOogF652BRlp18q/3hDzu027iaCH1jqQmksVb0aLqnoYL0q3+T4K+OjLquBgOCijm9XUw0A1Da1CxGg==", "dev": true, "requires": { "hosted-git-info": "^2.2.0", "yargs": "^6.6.0" } }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", "dev": true }, "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", "dev": true }, "wrap-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1" } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", "dev": true, "requires": { "mkdirp": "^0.5.1" } }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", "dev": true, "requires": { "graceful-fs": "^4.1.11", "imurmurhash": "^0.1.4", "signal-exit": "^3.0.2" } }, "xtend": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" }, "y18n": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==" }, "yallist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==" }, "yapool": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", "dev": true, "requires": { "camelcase": "^3.0.0", "cliui": "^3.2.0", "decamelize": "^1.1.1", "get-caller-file": "^1.0.1", "os-locale": "^1.4.0", "read-pkg-up": "^1.0.1", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", "string-width": "^1.0.2", "which-module": "^1.0.0", "y18n": "^3.2.1", "yargs-parser": "^4.2.0" }, "dependencies": { "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", "wrap-ansi": "^2.0.0" } }, "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", "dev": true } } }, "yargs-parser": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", "dev": true, "requires": { "camelcase": "^3.0.0" }, "dependencies": { "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true } } }, "yn": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.0.tgz", "integrity": "sha512-kKfnnYkbTfrAdd0xICNFw7Atm8nKpLcLv9AZGEt+kczL/WQVai4e2V6ZN8U/O+iI6WrNuJjNNOyu4zfhl9D3Hg==", "dev": true } } } cacache-11.3.3/package.json000066400000000000000000000046661350173612200154500ustar00rootroot00000000000000{ "name": "cacache", "version": "11.3.3", "cache-version": { "content": "2", "index": "5" }, "description": "Fast, fault-tolerant, cross-platform, disk-based, data-agnostic, content-addressable cache.", "main": "index.js", "files": [ "*.js", "lib", "locales" ], "scripts": { "benchmarks": "node test/benchmarks", "prerelease": "npm t", "postrelease": "npm publish && git push --follow-tags", "pretest": "standard", "release": "standard-version -s", "test": "cross-env CACACHE_UPDATE_LOCALE_FILES=true tap --coverage --nyc-arg=--all -J test/*.js", "test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test", "update-coc": "weallbehave -o . && git add CODE_OF_CONDUCT.md && git commit -m 'docs(coc): updated CODE_OF_CONDUCT.md'", "update-contrib": "weallcontribute -o . && git add CONTRIBUTING.md && git commit -m 'docs(contributing): updated CONTRIBUTING.md'" }, "repository": "https://github.com/zkat/cacache", "keywords": [ "cache", "caching", "content-addressable", "sri", "sri hash", "subresource integrity", "cache", "storage", "store", "file store", "filesystem", "disk cache", "disk storage" ], "author": { "name": "Kat Marchán", "email": "kzm@sykosomatic.org", "twitter": "maybekatz" }, "contributors": [ { "name": "Charlotte Spencer", "email": "charlottelaspencer@gmail.com", "twitter": "charlotteis" }, { "name": "Rebecca Turner", "email": "me@re-becca.org", "twitter": "ReBeccaOrg" } ], "license": "ISC", "dependencies": { "bluebird": "^3.5.5", "chownr": "^1.1.1", "figgy-pudding": "^3.5.1", "glob": "^7.1.4", "graceful-fs": "^4.1.15", "lru-cache": "^5.1.1", "mississippi": "^3.0.0", "mkdirp": "^0.5.1", "move-concurrently": "^1.0.1", "promise-inflight": "^1.0.1", "rimraf": "^2.6.3", "ssri": "^6.0.1", "unique-filename": "^1.1.1", "y18n": "^4.0.0" }, "devDependencies": { "benchmark": "^2.1.4", "chalk": "^2.4.2", "cross-env": "^5.1.4", "require-inject": "^1.4.4", "standard": "^12.0.1", "standard-version": "^6.0.1", "tacks": "^1.3.0", "tap": "^12.7.0", "weallbehave": "^1.2.0", "weallcontribute": "^1.0.9" }, "config": { "nyc": { "exclude": [ "node_modules/**", "test/**" ] } } } cacache-11.3.3/put.js000066400000000000000000000036761350173612200143300ustar00rootroot00000000000000'use strict' const figgyPudding = require('figgy-pudding') const index = require('./lib/entry-index') const memo = require('./lib/memoization') const write = require('./lib/content/write') const to = require('mississippi').to const PutOpts = figgyPudding({ algorithms: { default: ['sha512'] }, integrity: {}, memoize: {}, metadata: {}, pickAlgorithm: {}, size: {}, tmpPrefix: {}, uid: {}, gid: {}, single: {}, sep: {}, error: {}, strict: {} }) module.exports = putData function putData (cache, key, data, opts) { opts = PutOpts(opts) return write(cache, data, opts).then(res => { return index.insert( cache, key, res.integrity, opts.concat({ size: res.size }) ).then(entry => { if (opts.memoize) { memo.put(cache, entry, data, opts) } return res.integrity }) }) } module.exports.stream = putStream function putStream (cache, key, opts) { opts = PutOpts(opts) let integrity let size const contentStream = write.stream( cache, opts ).on('integrity', int => { integrity = int }).on('size', s => { size = s }) let memoData let memoTotal = 0 const stream = to((chunk, enc, cb) => { contentStream.write(chunk, enc, () => { if (opts.memoize) { if (!memoData) { memoData = [] } memoData.push(chunk) memoTotal += chunk.length } cb() }) }, cb => { contentStream.end(() => { index.insert(cache, key, integrity, opts.concat({ size })).then(entry => { if (opts.memoize) { memo.put(cache, entry, Buffer.concat(memoData, memoTotal), opts) } stream.emit('integrity', integrity) cb() }) }) }) let erred = false stream.once('error', err => { if (erred) { return } erred = true contentStream.emit('error', err) }) contentStream.once('error', err => { if (erred) { return } erred = true stream.emit('error', err) }) return stream } cacache-11.3.3/rm.js000066400000000000000000000012251350173612200141220ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const index = require('./lib/entry-index') const memo = require('./lib/memoization') const path = require('path') const rimraf = BB.promisify(require('rimraf')) const rmContent = require('./lib/content/rm') module.exports = entry module.exports.entry = entry function entry (cache, key) { memo.clearMemoized() return index.delete(cache, key) } module.exports.content = content function content (cache, integrity) { memo.clearMemoized() return rmContent(cache, integrity) } module.exports.all = all function all (cache) { memo.clearMemoized() return rimraf(path.join(cache, '*(content-*|index-*)')) } cacache-11.3.3/test/000077500000000000000000000000001350173612200141255ustar00rootroot00000000000000cacache-11.3.3/test/benchmarks/000077500000000000000000000000001350173612200162425ustar00rootroot00000000000000cacache-11.3.3/test/benchmarks/content.read.js000066400000000000000000000070401350173612200211650ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const CacheContent = require('../util/cache-content') const fs = BB.promisifyAll(require('fs')) const path = require('path') const Tacks = require('tacks') const ssri = require('ssri') const read = require('../../lib/content/read') let buf = [] for (let i = 0; i < Math.pow(2, 8); i++) { buf.push(Buffer.alloc(8, i)) } const CONTENT = Buffer.concat(buf, buf.length * 8) const INTEGRITY = ssri.fromData(CONTENT) const arr = [] for (let i = 0; i < 100; i++) { arr.push(CONTENT) } const BIGCONTENT = Buffer.concat(arr, CONTENT.length * 1000) const BIGINTEGRITY = ssri.fromData(BIGCONTENT) module.exports = (suite, CACHE) => { suite.add('content.read()', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { read( CACHE, INTEGRITY ).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('content.read() big data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [BIGINTEGRITY]: BIGCONTENT })) fixture.create(CACHE) }, fn (deferred) { read( CACHE, BIGINTEGRITY ).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('content.read.copy() small data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { if (read.copy) { read.copy(CACHE, INTEGRITY, path.join(CACHE, 'data')) .then( () => deferred.resolve(), err => deferred.reject(err) ) } else { read(CACHE, INTEGRITY) .then(data => fs.writeFileAsync(path.join(CACHE, 'data'), data)) .then( () => deferred.resolve(), err => deferred.reject(err) ) } } }) suite.add('content.read.copy() big data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [BIGINTEGRITY]: BIGCONTENT })) fixture.create(CACHE) }, fn (deferred) { if (read.copy) { read.copy(CACHE, BIGINTEGRITY, path.join(CACHE, 'bigdata')) .then( () => deferred.resolve(), err => deferred.reject(err) ) } else { read(CACHE, BIGINTEGRITY) .then(data => fs.writeFileAsync(path.join(CACHE, 'bigdata'), data)) .then( () => deferred.resolve(), err => deferred.reject(err) ) } } }) suite.add('content.read.stream() small data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { const stream = read.stream(CACHE, INTEGRITY) stream.on('data', () => {}) stream.on('error', err => deferred.reject(err)) stream.on('end', () => { deferred.resolve() }) } }) suite.add('content.read.stream() big data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [BIGINTEGRITY]: BIGCONTENT })) fixture.create(CACHE) }, fn (deferred) { const stream = read.stream(CACHE, BIGINTEGRITY) stream.on('data', () => {}) stream.on('error', err => deferred.reject(err)) stream.on('end', () => { deferred.resolve() }) } }) } cacache-11.3.3/test/benchmarks/get.js000066400000000000000000000060031350173612200173560ustar00rootroot00000000000000'use strict' const CacheContent = require('../util/cache-content') const memo = require('../../lib/memoization') const path = require('path') const Tacks = require('tacks') const ssri = require('ssri') const get = require('../../get') let buf = [] for (let i = 0; i < Math.pow(2, 8); i++) { buf.push(Buffer.alloc(8, i)) } const CONTENT = Buffer.concat(buf, buf.length * 8) const INTEGRITY = ssri.fromData(CONTENT) const arr = [] for (let i = 0; i < 100; i++) { arr.push(CONTENT) } const BIGCONTENT = Buffer.concat(arr, CONTENT.length * 1000) const BIGINTEGRITY = ssri.fromData(BIGCONTENT) module.exports = (suite, CACHE) => { suite.add('get.byDigest()', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { get.byDigest( CACHE, INTEGRITY ).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('get.byDigest() memoized', { defer: true, setup () { memo.put.byDigest(CACHE, INTEGRITY, CONTENT) }, fn (deferred) { get.byDigest( CACHE, INTEGRITY ).then( () => deferred.resolve(), err => deferred.reject(err) ) }, tearDown () { memo.clearMemoized() } }) suite.add('get.stream.byDigest() small data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { const stream = get.stream.byDigest(CACHE, INTEGRITY, { memoize: false }) stream.on('data', () => {}) stream.on('error', err => deferred.reject(err)) stream.on('end', () => { deferred.resolve() }) } }) suite.add('get.stream.byDigest() big data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [BIGINTEGRITY]: BIGCONTENT })) fixture.create(CACHE) }, fn (deferred) { const stream = get.stream.byDigest(CACHE, BIGINTEGRITY) stream.on('data', () => {}) stream.on('error', err => deferred.reject(err)) stream.on('end', () => { deferred.resolve() }) } }) suite.add('get.copy.byDigest() small data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) }, fn (deferred) { get.copy.byDigest(CACHE, INTEGRITY, path.join(CACHE, 'data')) .then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('get.copy.byDigest() big data', { defer: true, setup () { const fixture = new Tacks(CacheContent({ [BIGINTEGRITY]: BIGCONTENT })) fixture.create(CACHE) }, fn (deferred) { get.copy.byDigest(CACHE, BIGINTEGRITY, path.join(CACHE, 'data')) .then( () => deferred.resolve(), err => deferred.reject(err) ) } }) } cacache-11.3.3/test/benchmarks/index.find.js000066400000000000000000000022111350173612200206220ustar00rootroot00000000000000'use strict' const CacheIndex = require('../util/cache-index') const Tacks = require('tacks') const index = require('../../lib/entry-index') module.exports = (suite, CACHE) => { suite.add('index.find cache hit', { defer: true, fn (deferred) { index.find( CACHE, this.entry.key ).then( () => deferred.resolve(), err => deferred.reject(err) ) }, onStart () { const entry = { key: 'whatever', integrity: 'sha512-deadbeef', time: 12345, metadata: 'omgsometa' } const fixture = new Tacks(CacheIndex({ 'whatever': entry })) fixture.create(CACHE) this.fixture = fixture this.entry = entry } }) suite.add('index.find cache miss', { defer: true, fn (deferred) { index.find( CACHE, 'whatever' ).then( () => deferred.resolve(), err => deferred.reject(err) ) }, onStart () { const fixture = new Tacks(CacheIndex({ 'foo': { key: 'foo' }, 'w/e': { key: 'w/e' } })) fixture.create(CACHE) this.fixture = fixture } }) } cacache-11.3.3/test/benchmarks/index.insert.js000066400000000000000000000013311350173612200212100ustar00rootroot00000000000000'use strict' const KEY = 'foo' const INTEGRITY = 'sha512-deadbeef' const ALGO = 'whatnot' const index = require('../../lib/entry-index') module.exports = (suite, CACHE) => { suite.add('index.insert() different files', { defer: true, fn (deferred) { index.insert(CACHE, KEY + this.count, INTEGRITY, { metadata: 'foo' }).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('index.insert() same file', { defer: true, fn (deferred) { index.insert(CACHE, KEY, INTEGRITY, { metadata: 'foo', hashAlgorithm: ALGO }).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) } cacache-11.3.3/test/benchmarks/index.js000066400000000000000000000045371350173612200177200ustar00rootroot00000000000000'use strict' const Benchmark = require('benchmark') const chalk = require('chalk') const fs = require('fs') const path = require('path') const rimraf = require('rimraf') const CACHE = path.join(__dirname, '../', 'cache', 'benchmarks') const PREVIOUS = path.join(path.dirname(CACHE), 'last-benchmark.json') const WARN_RANGE = 5 const suite = new Benchmark.Suite({ onStart () { let previousPath = process.env.COMPARETO ? path.resolve(process.env.COMPARETO) : PREVIOUS try { this.previous = require(previousPath) } catch (e) {} console.log('================================================') if (this.previous) { console.log(' Comparing to', path.relative(process.cwd(), previousPath)) console.log('================================================') } }, onCycle (event) { const bench = event.target const prev = this.previous && this.previous[bench.name] const pctDelta = prev && (((bench.stats.mean - prev.stats.mean) / prev.stats.mean) * 100) let colorDiff = !prev ? '' : `${pctDelta > 0 ? '+' : ''}${pctDelta.toFixed(2)}% ` colorDiff = ` (${ pctDelta >= (WARN_RANGE + bench.stats.rme) ? chalk.red(colorDiff) : pctDelta <= -(WARN_RANGE + bench.stats.rme) ? chalk.green(colorDiff) : colorDiff }±${bench.stats.rme.toFixed(2)}%)` console.log(` ${bench.name}`) console.log('------------------------------------------------') if (bench.error) { console.log('Error:', bench.error.message || bench.error) } else { console.log(` ${ bench.hz.toFixed(bench.hz < 100 ? 2 : 0) } ops/s @ ~${ (bench.stats.mean * 1000).toFixed(3) }ms/op${colorDiff}`) console.log(` Sampled ${ bench.stats.sample.length } in ${ bench.times.elapsed.toFixed(2)}s.`) } console.log('================================================') rimraf.sync(CACHE) }, onComplete () { fs.writeFileSync(PREVIOUS, JSON.stringify(this.reduce((acc, bench) => { acc[bench.name] = bench return acc }, {})), 'utf8') } }) fs.readdir(__dirname, (err, files) => { if (err) { throw err } files.forEach(f => { if (path.extname(f) === '.js' && f !== 'index.js') { require('./' + f)(suite, path.join(CACHE, path.basename(f, '.js'))) } }) suite.run({ async: true }) }) cacache-11.3.3/test/benchmarks/put.js000066400000000000000000000032551350173612200174150ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const finished = BB.promisify(require('mississippi').finished) let buf = [] for (let i = 0; i < Math.pow(2, 8); i++) { buf.push(Buffer.alloc(8, i)) } const CONTENT = Buffer.concat(buf, buf.length * 8) const arr = [] for (let i = 0; i < 100; i++) { arr.push(CONTENT) } const BIGCONTENT = Buffer.concat(arr, CONTENT.length * 1000) const KEY = 'my-test-key' var put = require('../../put') module.exports = (suite, CACHE) => { suite.add('cacache.put()', { defer: true, fn (deferred) { put( CACHE, KEY + this.count, CONTENT + this.count ).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add('cacache.put() big data', { defer: true, fn (deferred) { put( CACHE, KEY + this.count, BIGCONTENT + this.count ).then( () => deferred.resolve(), err => deferred.reject(err) ) } }) suite.add(`cacache.put.stream() ${CONTENT.length} bytes`, { defer: true, fn (deferred) { const stream = put.stream(CACHE, KEY + this.count) finished( stream ).then( () => deferred.resolve(), err => deferred.reject(err) ) stream.write(CONTENT + this.count) stream.end() } }) suite.add(`cacache.put.stream() ${BIGCONTENT.length} bytes`, { defer: true, minSamples: 30, maxTime: 30, fn (deferred) { const stream = put.stream(CACHE, KEY + this.count) finished( stream ).then( () => deferred.resolve(), err => deferred.reject(err) ) stream.write(BIGCONTENT + this.count) stream.end() } }) } cacache-11.3.3/test/content.read.js000066400000000000000000000164331350173612200170560ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const finished = BB.promisify(require('mississippi').finished) const fs = require('fs') const path = require('path') const ssri = require('ssri') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) BB.promisifyAll(fs) const CACHE = path.join(testDir, 'cache') const CacheContent = require('./util/cache-content') const read = require('../lib/content/read') test('read: returns a BB with cache content data', function (t) { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return read(CACHE, INTEGRITY).then(data => { t.deepEqual(data, CONTENT, 'cache contents read correctly') }) }) test('read.sync: reads synchronously', t => { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) const data = read.sync(CACHE, INTEGRITY) t.deepEqual(data, CONTENT, 'cache contents read correctly') t.done() }) test('read.stream: returns a stream with cache content data', function (t) { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) const stream = read.stream(CACHE, INTEGRITY) stream.on('error', function (e) { throw e }) let buf = '' stream.on('data', function (data) { buf += data }) return BB.join( finished(stream).then(() => Buffer.from(buf)), read(CACHE, INTEGRITY, { size: CONTENT.length }), (fromStream, fromBulk) => { t.deepEqual(fromStream, CONTENT, 'stream data checks out') t.deepEqual(fromBulk, CONTENT, 'promise data checks out') } ) }) test('read: allows hashAlgorithm configuration', function (t) { const CONTENT = Buffer.from('foobarbaz') const HASH = 'whirlpool' const INTEGRITY = ssri.fromData(CONTENT, { algorithms: [HASH] }) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) const stream = read.stream(CACHE, INTEGRITY) stream.on('error', function (e) { throw e }) let buf = '' stream.on('data', function (data) { buf += data }) return BB.join( finished(stream).then(() => Buffer.from(buf)), read(CACHE, INTEGRITY), (fromStream, fromBulk) => { t.deepEqual(fromStream, CONTENT, 'stream used algorithm') t.deepEqual(fromBulk, CONTENT, 'promise used algorithm') } ) }) test('read: errors if content missing', function (t) { const stream = read.stream(CACHE, 'sha512-whatnot') stream.on('data', function (data) { throw new Error('unexpected data: ' + JSON.stringify(data)) }) stream.on('end', function () { throw new Error('end was called even though stream errored') }) return BB.join( finished(stream).catch({ code: 'ENOENT' }, err => err), read(CACHE, 'sha512-whatnot').catch({ code: 'ENOENT' }, err => err), (streamErr, bulkErr) => { t.equal(streamErr.code, 'ENOENT', 'stream got the right error') t.equal(bulkErr.code, 'ENOENT', 'bulk got the right error') } ) }) test('read: errors if content fails checksum', function (t) { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT.slice(3) // invalid contents! })) fixture.create(CACHE) const stream = read.readStream(CACHE, INTEGRITY) stream.on('end', function () { throw new Error('end was called even though stream errored') }) return BB.join( finished(stream).catch({ code: 'EINTEGRITY' }, err => err), read(CACHE, INTEGRITY).catch({ code: 'EINTEGRITY' }, err => err), (streamErr, bulkErr) => { t.equal(streamErr.code, 'EINTEGRITY', 'stream got the right error') t.equal(bulkErr.code, 'EINTEGRITY', 'bulk got the right error') } ) }) test('read: errors if content size does not match size option', function (t) { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT.slice(3) // invalid contents! })) fixture.create(CACHE) const stream = read.readStream(CACHE, INTEGRITY, { size: CONTENT.length }) stream.on('end', function () { throw new Error('end was called even though stream errored') }) return BB.join( finished(stream).catch({ code: 'EBADSIZE' }, err => err), read(CACHE, INTEGRITY, { size: CONTENT.length }).catch({ code: 'EBADSIZE' }, err => err), (streamErr, bulkErr) => { t.equal(streamErr.code, 'EBADSIZE', 'stream got the right error') t.equal(bulkErr.code, 'EBADSIZE', 'bulk got the right error') } ) }) test('hasContent: tests content existence', t => { const fixture = new Tacks(CacheContent({ 'sha1-deadbeef': '' })) fixture.create(CACHE) return BB.join( read.hasContent(CACHE, 'sha1-deadbeef') .then(content => { t.ok(content.sri, 'returned sri for this content') t.equal(content.size, 0, 'returned the right size for this content') t.ok(content.stat.isFile(), 'returned actual stat object') }), read.hasContent(CACHE, 'sha1-not-there') .then(content => { t.equal(content, false, 'returned false for missing content') }), read.hasContent(CACHE, 'sha1-not-here sha1-also-not-here') .then(content => { t.equal(content, false, 'multi-content hash failures work ok') }) ) }) test('hasContent.sync: checks content existence synchronously', t => { const fixture = new Tacks(CacheContent({ 'sha1-deadbeef': '' })) fixture.create(CACHE) const content = read.hasContent.sync(CACHE, 'sha1-deadbeef') t.ok(content.sri, 'returned sri for this content') t.equal(content.size, 0, 'returned the right size for this content') t.ok(content.stat.isFile(), 'returned actual stat object') t.equal( read.hasContent.sync(CACHE, 'sha1-not-there'), false, 'returned false for missing content' ) t.equal( read.hasContent.sync(CACHE, 'sha1-not-here sha1-also-not-here'), false, 'multi-content hash failures work ok' ) t.done() }) test('copy: copies content to a destination path', { skip: !fs.copyFile && 'Not supported on node versions without fs.copyFile' }, t => { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const DEST = path.join(CACHE, 'foobar-file') const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return read.copy(CACHE, INTEGRITY, DEST).then(() => { return fs.readFileAsync(DEST) }).then(data => { t.deepEqual(data, CONTENT, 'file successfully copied') }) }) test('copy.sync: copies content to a destination path synchronously', { skip: !fs.copyFile && 'Not supported on node versions without fs.copyFile' }, t => { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const DEST = path.join(CACHE, 'foobar-file') const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) read.copy.sync(CACHE, INTEGRITY, DEST) t.deepEqual( fs.readFileSync(DEST), CONTENT, 'file successfully copied' ) t.done() }) cacache-11.3.3/test/content.rm.js000066400000000000000000000024301350173612200165510ustar00rootroot00000000000000'use strict' const contentPath = require('../lib/content/path') const fs = require('graceful-fs') const path = require('path') const BB = require('bluebird') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) BB.promisifyAll(fs) const CACHE = path.join(testDir, 'cache') const CacheContent = require('./util/cache-content') const rm = require('../lib/content/rm') test('removes a content entry', function (t) { const fixture = new Tacks(CacheContent({ 'sha1-deadbeef': '' })) fixture.create(CACHE) return rm(CACHE, 'sha1-deadbeef').then(() => ( fs.statAsync(contentPath(CACHE, 'sha1-deadbeef')) )).then(() => { throw new Error('expected an error') }).catch(err => { t.ok(err, 'fs.stat failed on rmed content') t.equal('ENOENT', err.code, 'file does not exist anymore') }) }) test('works fine if entry missing', function (t) { const fixture = new Tacks(CacheContent({})) fixture.create(CACHE) return rm(CACHE, 'sha1-deadbeef').then(() => ( fs.statAsync(contentPath(CACHE, 'sha1-deadbeef')) )).then(() => { throw new Error('expected an error') }).catch(err => { t.ok(err, 'fs.stat failed on rmed content') t.equal('ENOENT', err.code, 'file does not exist anymore') }) }) cacache-11.3.3/test/content.write.chownr.js000066400000000000000000000030321350173612200205630ustar00rootroot00000000000000'use strict' const fromString = require('./util/from-string') const path = require('path') const pipe = require('mississippi').pipe const requireInject = require('require-inject') const ssri = require('ssri') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const CACHE = path.join(testDir, 'cache') const contentPath = require('../lib/content/path') test('allows setting a custom uid for cache contents on write', { skip: process.getuid ? false : 'test only works on platforms that can set uid/gid' }, t => { const CONTENT = 'foobarbaz' const INTEGRITY = ssri.fromData(CONTENT) const NEWUID = process.getuid() + 1 const NEWGID = process.getgid() + 1 const updatedPaths = [] const write = requireInject('../lib/content/write', { chownr: function (p, uid, gid, cb) { process.nextTick(function () { const rel = path.relative(CACHE, p) t.equal(uid, NEWUID, 'new uid set for ' + rel) t.equal(gid, NEWGID, 'new gid set for ' + rel) updatedPaths.push(p) cb(null) }) } }) t.plan(7) pipe(fromString(CONTENT), write.stream(CACHE, { uid: NEWUID, gid: NEWGID, hashAlgorithm: 'sha1' }), function (err) { if (err) { throw err } const cpath = contentPath(CACHE, INTEGRITY) const expectedPaths = [ CACHE, path.join(CACHE, path.relative(CACHE, cpath).split(path.sep)[0]), cpath ] t.deepEqual( updatedPaths.sort(), expectedPaths, 'all paths that needed user stuff set got set') }) }) cacache-11.3.3/test/content.write.js000066400000000000000000000172521350173612200172750ustar00rootroot00000000000000'use strict' const fromString = require('./util/from-string') const fs = require('fs') const path = require('path') const pipe = require('mississippi').pipe const rimraf = require('rimraf') const ssri = require('ssri') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const CACHE = path.join(testDir, 'cache') const CacheContent = require('./util/cache-content') const contentPath = require('../lib/content/path') const write = require('../lib/content/write') test('basic put', t => { const CONTENT = 'foobarbaz' // Default is sha512 const INTEGRITY = ssri.fromData(CONTENT) let integrity const src = fromString(CONTENT) const stream = write.stream(CACHE).on('integrity', i => { integrity = i }) pipe(src, stream, err => { if (err) { throw err } const cpath = contentPath(CACHE, integrity) t.plan(3) t.deepEqual(integrity, INTEGRITY, 'calculated integrity value matches') fs.lstat(cpath, (err, stat) => { if (err) { throw err } t.ok(stat.isFile(), 'content inserted as a single file') }) fs.readFile(cpath, 'utf8', (err, data) => { if (err) { throw err } t.equal(data, CONTENT, 'contents are identical to inserted content') }) }) }) test('checks input digest doesn\'t match data', t => { const CONTENT = 'foobarbaz' const INTEGRITY = ssri.fromData(CONTENT) t.plan(5) let int1 let int2 pipe(fromString('bazbarfoo'), write.stream(CACHE, { integrity: INTEGRITY }).on('integrity', int => { int1 = int }), err => { t.ok(!int1, 'no digest emitted') t.ok(!!err, 'got an error') t.equal(err.code, 'EINTEGRITY', 'returns a useful error code') }) pipe(fromString(CONTENT), write.stream(CACHE, { integrity: INTEGRITY }).on('integrity', int => { int2 = int }), err => { t.ok(!err, 'completed without error') t.deepEqual(int2, INTEGRITY, 'returns a matching digest') }) }) test('errors if stream ends with no data', t => { let integrity = null pipe(fromString(''), write.stream(CACHE).on('integrity', int => { integrity = int }), err => { t.ok(err, 'got an error') t.equal(integrity, null, 'no digest returned') t.equal(err.code, 'ENODATA', 'returns useful error code') t.end() }) }) test('errors if input size does not match expected', t => { t.plan(10) let int1 = null pipe(fromString('abc'), write.stream(CACHE, { size: 5 }).on('integrity', int => { int1 = int }), err => { t.ok(err, 'got an error when data smaller than expected') t.equal(int1, null, 'no digest returned') t.equal(err.code, 'EBADSIZE', 'returns useful error code') t.equal(err.expected, 5, 'error includes expected size') t.equal(err.found, 3, 'error includes found size') }) let int2 = null pipe(fromString('abcdefghi'), write.stream(CACHE, { size: 5 }).on('integrity', int => { int2 = int }), err => { t.ok(err, 'got an error when data bigger than expected') t.equal(int2, null, 'no digest returned') t.equal(err.code, 'EBADSIZE', 'returns useful error code') t.equal(err.expected, 5, 'error includes expected size') t.equal(err.found, 9, 'error includes found size') }) }) test('does not overwrite content if already on disk', t => { const CONTENT = 'foobarbaz' const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: 'nope' })) fixture.create(CACHE) t.plan(4) let int1 let int2 // With a digest -- early short-circuiting pipe(fromString(CONTENT), write.stream(CACHE, { integrity: INTEGRITY }).on('integrity', int => { int1 = int }), err => { if (err) { throw err } t.deepEqual(int1, INTEGRITY, 'short-circuit returns a matching digest') fs.readFile(contentPath(CACHE, INTEGRITY), 'utf8', (e, d) => { if (e) { throw e } t.equal(d, 'nope', 'process short-circuited. Data not written.') }) }) pipe(fromString(CONTENT), write.stream(CACHE).on('integrity', int => { int2 = int }), err => { if (err) { throw err } t.deepEqual(int2, INTEGRITY, 'full write returns a matching digest') fs.readFile(contentPath(CACHE, INTEGRITY), 'utf8', function (e, d) { if (e) { throw e } t.equal(d, 'nope', 'previously-written data intact - no dupe write') }) }) }) test('errors if input stream errors', t => { const stream = fromString('foobarbaz') .on('end', () => stream.emit('error', new Error('bleh'))) let integrity const putter = write.stream(CACHE).on('integrity', int => { integrity = int }) pipe(stream, putter, err => { t.ok(err, 'got an error') t.ok(!integrity, 'no digest returned') t.match(err && err.message, 'bleh', 'returns the error from input stream') fs.stat(contentPath(CACHE, ssri.fromData('foobarbaz')), (err, stat) => { t.ok(err, 'got an error') t.equal(err.code, 'ENOENT', 'target file missing. No files created.') t.end() }) }) }) test('exits normally if file already open', t => { const CONTENT = 'foobarbaz' const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) let integrity fixture.create(CACHE) // This case would only fail on Windows, when an entry is being read. // Generally, you'd get an EBUSY back. fs.open(contentPath(CACHE, INTEGRITY), 'r+', function (err, fd) { if (err) { throw err } pipe(fromString(CONTENT), write.stream(CACHE).on('integrity', int => { integrity = int }), err => { if (err) { throw err } t.deepEqual(integrity, INTEGRITY, 'returns a matching digest') fs.close(fd, err => { if (err) { throw err } rimraf(contentPath(CACHE, INTEGRITY), err => { if (err) { throw err } t.end() }) }) }) }) }) test('cleans up tmp on successful completion', t => { const CONTENT = 'foobarbaz' pipe(fromString(CONTENT), write.stream(CACHE), err => { if (err) { throw err } const tmp = path.join(CACHE, 'tmp') fs.readdir(tmp, function (err, files) { if (!err || (err && err.code === 'ENOENT')) { files = files || [] t.deepEqual(files, [], 'nothing in the tmp dir!') t.end() } else { throw err } }) }) }) test('cleans up tmp on error', t => { const CONTENT = 'foobarbaz' pipe(fromString(CONTENT), write.stream(CACHE, { size: 1 }), err => { t.ok(err, 'got an error') t.equal(err.code, 'EBADSIZE', 'got expected code') const tmp = path.join(CACHE, 'tmp') fs.readdir(tmp, function (err, files) { if (!err || (err && err.code === 'ENOENT')) { files = files || [] t.deepEqual(files, [], 'nothing in the tmp dir!') t.end() } else { throw err } }) }) }) test('checks the size of stream data if opts.size provided', t => { const CONTENT = 'foobarbaz' let int1, int2, int3 t.plan(8) pipe( fromString(CONTENT.slice(3)), write.stream(CACHE, { size: CONTENT.length }).on('integrity', int => { int1 = int }), err => { t.ok(!!err, 'got an error') t.ok(!int1, 'no digest returned') t.equal(err.code, 'EBADSIZE', 'returns a useful error code') } ) pipe( fromString(CONTENT + 'quux'), write.stream(CACHE, { size: CONTENT.length }).on('integrity', int => { int2 = int }), err => { t.ok(!!err, 'got an error') t.ok(!int2, 'no digest returned') t.equal(err.code, 'EBADSIZE', 'returns a useful error code') } ) pipe( fromString(CONTENT), write.stream(CACHE, { size: CONTENT.length }).on('integrity', int => { int3 = int }), err => { t.ifError(err, 'completed without error') t.ok(int3, 'got a digest') } ) }) cacache-11.3.3/test/get.js000066400000000000000000000221561350173612200152500ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const finished = BB.promisify(require('mississippi').finished) const fs = require('fs') const index = require('../lib/entry-index') const memo = require('../lib/memoization') const path = require('path') const rimraf = BB.promisify(require('rimraf')) const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') BB.promisifyAll(fs) const CacheContent = require('./util/cache-content') const CACHE = path.join(testDir, 'cache') const CONTENT = Buffer.from('foobarbaz', 'utf8') const SIZE = CONTENT.length const KEY = 'my-test-key' const INTEGRITY = ssri.fromData(CONTENT).toString() const METADATA = { foo: 'bar' } const get = require('..').get function opts (extra) { return Object.assign({ size: SIZE, metadata: METADATA }, extra) } // Simple wrapper util cause this gets WORDY function streamGet (byDigest) { const args = [].slice.call(arguments, 1) let data = [] let dataLen = 0 let integrity let metadata let size const stream = ( byDigest ? get.stream.byDigest : get.stream ).apply(null, args) stream.on('data', d => { data.push(d) dataLen += d.length }).on('integrity', int => { integrity = ssri.stringify(int) }).on('metadata', m => { metadata = m }).on('size', s => { size = s }) return finished(stream).then(() => ({ data: Buffer.concat(data, dataLen), integrity, metadata, size })) } test('basic bulk get', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, opts()).then(() => { return get(CACHE, KEY) }).then(res => { t.deepEqual(res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') }).then(() => { return get.byDigest(CACHE, INTEGRITY) }).then(res => { t.deepEqual(res, CONTENT, 'byDigest returned proper data') }) }) test('basic sync get', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) const res = get.sync(CACHE, KEY) t.deepEqual(res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') const resByDig = get.sync.byDigest(CACHE, INTEGRITY) t.deepEqual(resByDig, CONTENT, 'byDigest returned proper data') t.done() }) test('basic stream get', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, opts()).then(() => { return BB.join( streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY), (byKey, byDigest) => { t.deepEqual(byKey, { data: CONTENT, integrity: INTEGRITY, metadata: METADATA, size: SIZE }, 'got all expected data and fields from key fetch') t.deepEqual( byDigest.data, CONTENT, 'got correct data from digest fetch' ) } ) }) }) test('get.copy', t => { const DEST = path.join(CACHE, 'copymehere') const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, opts()) .then(() => get.copy(CACHE, KEY, DEST)) .then(res => { t.deepEqual(res, { metadata: METADATA, integrity: INTEGRITY, size: SIZE }, 'copy operation returns basic metadata') return fs.readFileAsync(DEST) }) .then(data => { t.deepEqual(data, CONTENT, 'data copied by key matches') return rimraf(DEST) }) .then(() => get.copy.byDigest(CACHE, INTEGRITY, DEST)) .then(() => fs.readFileAsync(DEST)) .then(data => { t.deepEqual(data, CONTENT, 'data copied by digest matches') return rimraf(DEST) }) }) test('ENOENT if not found', t => { return get(CACHE, KEY).then(() => { throw new Error('lookup should fail') }).catch(err => { t.ok(err, 'got an error') t.equal(err.code, 'ENOENT', 'error code is ENOENT') return get.info(CACHE, KEY) }).catch(err => { t.ok(err, 'got an error') t.equal(err.code, 'ENOENT', 'error code is ENOENT') }) }) test('get.info index entry lookup', t => { return index.insert(CACHE, KEY, INTEGRITY, opts()).then(ENTRY => { return get.info(CACHE, KEY).then(entry => { t.deepEqual(entry, ENTRY, 'get.info() returned the right entry') }) }) }) test('memoizes data on bulk read', t => { memo.clearMemoized() const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, opts()).then(ENTRY => { return get(CACHE, KEY).then(() => { t.deepEqual(memo.get(CACHE, KEY), null, 'no memoization!') return get(CACHE, KEY, { memoize: true }) }).then(res => { t.deepEqual(res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'usual data returned') t.deepEqual(memo.get(CACHE, KEY), { entry: ENTRY, data: CONTENT }, 'data inserted into memoization cache') return rimraf(CACHE) }).then(() => { return get(CACHE, KEY) }).then(res => { t.deepEqual(res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'memoized data fetched by default') return get(CACHE, KEY, { memoize: false }).then(() => { throw new Error('expected get to fail') }).catch(err => { t.ok(err, 'got an error from unmemoized get') t.equal(err.code, 'ENOENT', 'cached content not found') t.deepEqual(memo.get(CACHE, KEY), { entry: ENTRY, data: CONTENT }, 'data still in memoization cache') }) }) }) }) test('memoizes data on stream read', t => { memo.clearMemoized() const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, opts()).then(ENTRY => { return BB.join( streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY), () => { t.deepEqual(memo.get(CACHE, KEY), null, 'no memoization by key!') t.deepEqual( memo.get.byDigest(CACHE, INTEGRITY), null, 'no memoization by digest!' ) } ).then(() => { memo.clearMemoized() return streamGet(true, CACHE, INTEGRITY, { memoize: true }) }).then(byDigest => { t.deepEqual(byDigest.data, CONTENT, 'usual data returned from stream') t.deepEqual(memo.get(CACHE, KEY), null, 'digest fetch = no key entry') t.deepEqual( memo.get.byDigest(CACHE, INTEGRITY), CONTENT, 'content memoized' ) t.deepEqual( memo.get.byDigest('whatev', INTEGRITY), null, 'content memoization filtered by cache' ) }).then(() => { memo.clearMemoized() return streamGet(false, CACHE, KEY, { memoize: true }) }).then(byKey => { t.deepEqual(byKey, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'usual data returned from key fetch') t.deepEqual(memo.get(CACHE, KEY), { entry: ENTRY, data: CONTENT }, 'data inserted into memoization cache') t.deepEqual( memo.get.byDigest(CACHE, INTEGRITY), CONTENT, 'content memoized by digest, too' ) t.deepEqual( memo.get('whatev', KEY), null, 'entry memoization filtered by cache' ) }).then(() => { return rimraf(CACHE) }).then(() => { return BB.join( streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY), (byKey, byDigest) => { t.deepEqual(byKey, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'key fetch fulfilled by memoization cache') t.deepEqual( byDigest.data, CONTENT, 'digest fetch fulfilled by memoization cache' ) } ) }).then(() => { return BB.join( streamGet(false, CACHE, KEY, { memoize: false }).catch(err => err), streamGet(true, CACHE, INTEGRITY, { memoize: false }).catch(err => err), (keyErr, digestErr) => { t.equal(keyErr.code, 'ENOENT', 'key get memoization bypassed') t.equal(keyErr.code, 'ENOENT', 'digest get memoization bypassed') } ) }) }) }) test('get.info uses memoized data', t => { memo.clearMemoized() const ENTRY = { key: KEY, integrity: INTEGRITY, time: +(new Date()), size: SIZE, metadata: null } memo.put(CACHE, ENTRY, CONTENT) return get.info(CACHE, KEY).then(info => { t.deepEqual(info, ENTRY, 'got the entry from memoization cache') }) }) test('identical hashes with different algorithms do not conflict') test('throw error if something is really wrong with bucket') cacache-11.3.3/test/index.find.js000066400000000000000000000132661350173612200165210ustar00rootroot00000000000000'use strict' const CacheIndex = require('./util/cache-index') const fs = require('fs') const path = require('path') const BB = require('bluebird') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) BB.promisifyAll(fs) const CACHE = path.join(testDir, 'cache') const SIZE = 999 const contentPath = require('../lib/content/path') const index = require('../lib/entry-index') test('index.find cache hit', function (t) { const entry = { key: 'whatever', integrity: 'whatnot-deadbeef', time: 12345, metadata: 'omgsometa', size: 5 } const fixture = new Tacks(CacheIndex({ 'whatever': entry })) fixture.create(CACHE) return index.find( CACHE, entry.key ).then(info => { t.ok(info, 'cache hit') t.equal( info.path, contentPath(CACHE, entry.integrity), 'path added to info' ) delete info.path t.deepEqual(info, entry, 'rest of info matches entry on disk') }) }) test('index.find cache miss', function (t) { const fixture = new Tacks(CacheIndex({ 'foo': { key: 'foo' }, 'w/e': { key: 'w/e' } })) fixture.create(CACHE) return index.find( CACHE, 'whatever' ).then(info => { t.ok(!info, 'cache miss when specific key not present') }) }) test('index.find no cache', function (t) { return fs.statAsync(CACHE).then(() => { throw new Error('expected cache directory') }).catch(err => { t.assert(err, 'cache directory does not exist') return index.find(CACHE, 'whatever') }).then(info => { t.ok(!info, 'if there is no cache dir, behaves like a cache miss') }) }) test('index.find key case-sensitivity', function (t) { const fixture = new Tacks(CacheIndex({ 'jsonstream': { key: 'jsonstream', integrity: 'sha1-lowercase', time: 54321, size: SIZE }, 'JSONStream': { key: 'JSONStream', integrity: 'sha1-capitalised', time: 12345, size: SIZE } })) fixture.create(CACHE) return BB.join( index.find(CACHE, 'JSONStream').then(info => { t.ok(info, 'found an entry for JSONStream') t.equal(info.key, 'JSONStream', 'fetched the correct entry') }), index.find(CACHE, 'jsonstream').then(info => { t.ok(info, 'found an entry for jsonstream') t.equal(info.key, 'jsonstream', 'fetched the correct entry') }), index.find(CACHE, 'jsonStream').then(info => { t.ok(!info, 'no entry for jsonStream') }) ) }) test('index.find path-breaking characters', function (t) { const entry = { key: ';;!registry\nhttps://registry.npmjs.org/back \\ slash@Cool™?', integrity: 'sha1-deadbeef', time: 12345, metadata: 'omgsometa', size: 9 } const fixture = new Tacks(CacheIndex({ [entry.key]: entry })) fixture.create(CACHE) return index.find(CACHE, entry.key).then(info => { t.ok(info, 'cache hit') delete info.path t.deepEqual( info, entry, 'info remains intact even with fs-unfriendly chars' ) }) }) test('index.find extremely long keys', function (t) { let key = '' for (let i = 0; i < 10000; i++) { key += i } const entry = { key: key, integrity: 'sha1-deadbeef', time: 12345, metadata: 'woo', size: 10 } const fixture = new Tacks(CacheIndex({ [entry.key]: entry })) fixture.create(CACHE) return index.find(CACHE, entry.key).then(info => { t.ok(info, 'cache hit') delete info.path t.deepEqual( info, entry, 'info remains intact even with absurdly long key' ) }) }) test('index.find multiple index entries for key', function (t) { const key = 'whatever' const fixture = new Tacks(CacheIndex({ 'whatever': [ { key: key, integrity: 'sha1-deadbeef', time: 54321 }, { key: key, integrity: 'sha1-bada55', time: 12345 } ] })) fixture.create(CACHE) return index.find(CACHE, key).then(info => { t.ok(info, 'cache hit') t.equal(info.integrity, 'sha1-bada55', 'most recent entry wins') }) }) test('index.find garbled data in index file', function (t) { // Even though `index.insert()` is safe from direct // race conditions, it's still possible for individual // entries to become corrupted, or to be partially written, // since `index.find` does not acquire a write-preventing lock. // // Because entries are newline-prepended and only one // can be written at a time, the main possible corruption // source is if an append fails mid-write (for example, due // to the process crashing). In this case, the corrupt entry // will simply be skipped. const key = 'whatever' const stringified = JSON.stringify({ key: key, integrity: 'sha1-deadbeef', time: 54321 }) const fixture = new Tacks(CacheIndex({ 'whatever': '\n' + `${index._hashEntry(stringified)}\t${stringified}` + '\n{"key": "' + key + '"\noway' })) fixture.create(CACHE) return index.find(CACHE, key).then(info => { t.ok(info, 'cache hit in spite of crash-induced fail') t.equal(info.integrity, 'sha1-deadbeef', ' recent entry wins') }) }) test('index.find hash conflict in same bucket', function (t) { // This... is very unlikely to happen. But hey. const entry = { key: 'whatever', integrity: 'sha1-deadbeef', time: 12345, metadata: 'yay', size: 8 } const fixture = new Tacks(CacheIndex({ 'whatever': [ { key: 'ohnoes', integrity: 'sha1-welp!' }, entry, { key: 'nope', integrity: 'sha1-bada55' } ] })) fixture.create(CACHE) return index.find(CACHE, entry.key).then(info => { t.ok(info, 'cache hit') delete info.path t.deepEqual( info, entry, 'got the right one even though different keys exist in index' ) }) }) cacache-11.3.3/test/index.insert.js000066400000000000000000000124751350173612200171060ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const CacheIndex = require('./util/cache-index') const contentPath = require('../lib/content/path') const fs = require('fs') const path = require('path') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) BB.promisifyAll(fs) const CACHE = path.join(testDir, 'cache') const index = require('../lib/entry-index') const KEY = 'foo' const BUCKET = index._bucketPath(CACHE, KEY) const INTEGRITY = 'sha512-deadbeef' const SIZE = 999 function opts (extra) { return Object.assign({ size: SIZE }, extra) } test('basic insertion', function (t) { return index.insert(CACHE, KEY, INTEGRITY, opts({ metadata: 'foo' })).then(entry => { t.deepEqual(entry, { key: KEY, integrity: INTEGRITY, path: contentPath(CACHE, INTEGRITY), time: entry.time, metadata: 'foo', size: SIZE }, 'formatted entry returned') return fs.readFileAsync(BUCKET, 'utf8') }).then(data => { t.equal(data[0], '\n', 'first entry starts with a \\n') const split = data.split('\t') t.equal(split[0].slice(1), index._hashEntry(split[1]), 'consistency header correct') const entry = JSON.parse(split[1]) t.ok(entry.time, 'entry has a timestamp') t.deepEqual(entry, { key: KEY, integrity: INTEGRITY, time: entry.time, metadata: 'foo', size: SIZE }, 'entry matches what was inserted') }) }) test('inserts additional entries into existing key', function (t) { return index.insert(CACHE, KEY, INTEGRITY, opts({ metadata: 1 })).then(() => ( index.insert(CACHE, KEY, INTEGRITY, opts({ metadata: 2 })) )).then(() => { return fs.readFileAsync(BUCKET, 'utf8') }).then(data => { const entries = data.split('\n').slice(1).map(line => { return JSON.parse(line.split('\t')[1]) }) entries.forEach(function (e) { delete e.time }) t.deepEqual(entries, [{ key: KEY, integrity: INTEGRITY, metadata: 1, size: SIZE }, { key: KEY, integrity: INTEGRITY, metadata: 2, size: SIZE }], 'all entries present') }) }) test('separates entries even if one is corrupted', function (t) { // TODO - check that middle-of-string corrupted writes won't hurt. const fixture = new Tacks(CacheIndex({ 'foo': '\n' + JSON.stringify({ key: KEY, integrity: 'meh', time: 54321, size: SIZE }) + '\n{"key": "' + KEY + '"\noway' })) fixture.create(CACHE) return index.insert( CACHE, KEY, INTEGRITY, opts() ).then(() => { return fs.readFileAsync(BUCKET, 'utf8') }).then(data => { const entry = JSON.parse(data.split('\n')[4].split('\t')[1]) delete entry.time t.deepEqual(entry, { key: KEY, integrity: INTEGRITY, size: SIZE }, 'new entry unaffected by corruption') }) }) test('optional arbitrary metadata', function (t) { const metadata = { foo: 'bar' } return index.insert( CACHE, KEY, INTEGRITY, opts({ metadata: metadata }) ).then(() => { return fs.readFileAsync(BUCKET, 'utf8') }).then(data => { const entry = JSON.parse(data.split('\t')[1]) delete entry.time t.deepEqual(entry, { key: KEY, integrity: INTEGRITY, metadata: metadata, size: SIZE }, 'entry includes inserted metadata') }) }) test('key case-sensitivity', function (t) { return BB.join( index.insert(CACHE, KEY, INTEGRITY, opts()), index.insert(CACHE, KEY.toUpperCase(), INTEGRITY + 'upper', opts()) ).then(() => { return BB.join( index.find(CACHE, KEY), index.find(CACHE, KEY.toUpperCase()), (entry, upperEntry) => { delete entry.time delete upperEntry.time t.deepEqual({ key: entry.key, integrity: entry.integrity, size: SIZE }, { key: KEY, integrity: INTEGRITY, size: SIZE }, 'regular entry exists') t.deepEqual({ key: upperEntry.key, integrity: upperEntry.integrity, size: SIZE }, { key: KEY.toUpperCase(), integrity: INTEGRITY + 'upper', size: SIZE }, 'case-variant entry intact') } ) }) }) test('path-breaking characters', function (t) { const newKey = ';;!registry\nhttps://registry.npmjs.org/back \\ slash@Cool™?' return index.insert( CACHE, newKey, INTEGRITY, opts() ).then(() => { const bucket = index._bucketPath(CACHE, newKey) return fs.readFileAsync(bucket, 'utf8') }).then(data => { const entry = JSON.parse(data.split('\t')[1]) delete entry.time t.deepEqual(entry, { key: newKey, integrity: INTEGRITY, size: SIZE }, 'entry exists and matches original key with invalid chars') }) }) test('extremely long keys', function (t) { let newKey = '' for (let i = 0; i < 10000; i++) { newKey += i } return index.insert( CACHE, newKey, INTEGRITY, opts() ).then(() => { const bucket = index._bucketPath(CACHE, newKey) return fs.readFileAsync(bucket, 'utf8') }).then(data => { const entry = JSON.parse(data.split('\t')[1]) delete entry.time t.deepEqual(entry, { key: newKey, integrity: INTEGRITY, size: SIZE }, 'entry exists in spite of INCREDIBLY LONG key') }) }) test('concurrent writes') test('correct ownership') cacache-11.3.3/test/ls.js000066400000000000000000000104351350173612200151040ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const CacheIndex = require('./util/cache-index') const contentPath = require('../lib/content/path') const finished = BB.promisify(require('mississippi').finished) const index = require('../lib/entry-index.js') const path = require('path') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const CACHE = path.join(testDir, 'cache') const File = Tacks.File const ls = require('..').ls test('basic listing', function (t) { const contents = { 'whatever': { key: 'whatever', integrity: 'sha512-deadbeef', time: 12345, metadata: 'omgsometa', size: 234234 }, 'whatnot': { key: 'whatnot', integrity: 'sha512-bada55', time: 54321, metadata: null, size: 425345345 } } const fixture = new Tacks(CacheIndex(contents)) contents.whatever.path = contentPath( CACHE, contents.whatever.integrity) contents.whatnot.path = contentPath( CACHE, contents.whatnot.integrity) fixture.create(CACHE) return ls(CACHE).then(listing => { t.deepEqual(listing, contents, 'index contents correct') }).then(() => { const listing = [] const stream = ls.stream(CACHE) stream.on('data', entry => { listing[entry.key] = entry }) return finished(stream).then(() => { t.deepEqual(listing, contents, 'ls is streamable') }) }) }) test('separate keys in conflicting buckets', function (t) { const contents = { 'whatever': { key: 'whatever', integrity: 'sha512-deadbeef', time: 12345, metadata: 'omgsometa', size: 5 }, 'whatev': { key: 'whatev', integrity: 'sha512-bada55', time: 54321, metadata: null, size: 99234234 } } const fixture = new Tacks(CacheIndex({ // put both in the same bucket 'whatever': [contents.whatever, contents.whatev] })) contents.whatever.path = contentPath( CACHE, contents.whatever.integrity) contents.whatev.path = contentPath( CACHE, contents.whatev.integrity) fixture.create(CACHE) return ls(CACHE).then(listing => { t.deepEqual(listing, contents, 'index contents correct') }) }) test('works fine on an empty/missing cache', function (t) { return ls(CACHE).then(listing => { t.deepEqual(listing, {}, 'returned an empty listing') }) }) test('ignores non-dir files', function (t) { const index = CacheIndex({ 'whatever': { key: 'whatever', integrity: 'sha512-deadbeef', time: 12345, metadata: 'omgsometa', size: 234234 } }) index.contents['garbage'] = File('hello world') const fixture = new Tacks(index) fixture.create(CACHE) return ls(CACHE).then(listing => { t.equal(Object.keys(listing).length, 1, 'only 1 item in listing') t.equal(listing.whatever.key, 'whatever', 'only the correct entry listed') }) }) test('correctly ignores deleted entries', t => { const contents = { 'whatever': { key: 'whatever', integrity: 'sha512-deadbeef', time: 12345, metadata: 'omgsometa', size: 234234 }, 'whatnot': { key: 'whatnot', integrity: 'sha512-bada55', time: 54321, metadata: null, size: 425345345 }, 'whatwhere': { key: 'whatwhere', integrity: 'sha512-bada55e5', time: 54321, metadata: null, size: 425345345 } } const fixture = new Tacks(CacheIndex(contents)) contents.whatever.path = contentPath( CACHE, contents.whatever.integrity) contents.whatnot.path = contentPath( CACHE, contents.whatnot.integrity) contents.whatwhere.path = contentPath( CACHE, contents.whatwhere.integrity) fixture.create(CACHE) return index.delete(CACHE, 'whatnot') .then(() => ls(CACHE)) .then(listing => t.deepEqual(listing, { whatever: contents.whatever, whatwhere: contents.whatwhere }, 'index contents correct')) .then(() => { const listing = [] const stream = ls.stream(CACHE) stream.on('data', entry => { listing[entry.key] = entry }) return finished(stream) .then(() => t.deepEqual(listing, { whatever: contents.whatever, whatwhere: contents.whatwhere }, 'ls is streamable')) }) }) cacache-11.3.3/test/memoization.js000066400000000000000000000101101350173612200170070ustar00rootroot00000000000000'use strict' const test = require('tap').test const memo = require('../lib/memoization') const CACHE = 'mycache' const ENTRY = { key: 'foo', integrity: 'sha512-deadbeef', time: new Date(), metadata: null } const DATA = 'foobarbaz' test('memoizes entry and data by key', t => { memo.put(CACHE, ENTRY, DATA) t.deepEqual(memo.clearMemoized(), { [`key:${CACHE}:${ENTRY.key}`]: { entry: ENTRY, data: DATA }, [`digest:${CACHE}:${ENTRY.integrity}`]: DATA }, 'cache has both key and digest entries') t.done() }) test('can fetch data by key', t => { memo.put(CACHE, ENTRY, DATA) t.deepEqual(memo.get(CACHE, ENTRY.key), { entry: ENTRY, data: DATA }, 'fetched data correctly') t.deepEqual( memo.get(CACHE + 'meh', ENTRY.key), null, 'different caches store different keyspaces' ) memo.clearMemoized() t.done() }) test('can fetch data by digest', t => { memo.put(CACHE, ENTRY, DATA) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity), DATA, 'got raw data by digest, without an entry' ) memo.clearMemoized() t.done() }) test('can clear out the memoization cache', t => { memo.put(CACHE, ENTRY, DATA) memo.clearMemoized() t.deepEqual( memo.get(CACHE, ENTRY.key), null, 'entry not there anymore' ) t.deepEqual( memo.get.byDigest(ENTRY.integrity), null, 'digest-based data not there anymore' ) t.done() }) test('accepts optional injected cache', t => { memo.clearMemoized() const MEMO = new Map() memo.put(CACHE, ENTRY, DATA, { memoize: MEMO }) t.deepEqual( memo.get(CACHE, ENTRY.key), null, 'entry not in global memo cache' ) t.deepEqual( memo.get(CACHE, ENTRY.key, { memoize: MEMO }), { entry: ENTRY, data: DATA }, 'entry fetched from injected memoizer' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: MEMO }), DATA, 'content entry fetched from injected memoizer' ) t.deepEqual( MEMO.get(`key:${CACHE}:${ENTRY.key}`), { entry: ENTRY, data: DATA }, 'entry is in the injected memoizer' ) t.deepEqual( MEMO.get(`digest:${CACHE}:${ENTRY.integrity}`), DATA, 'content entry is in the injected memoizer' ) MEMO.clear() t.deepEqual( memo.get(CACHE, ENTRY.key, { memoize: MEMO }), null, 'tried to read from cleared memoizer' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: MEMO }), null, 'tried to read by digest from cleared memoizer' ) memo.put.byDigest(CACHE, ENTRY.integrity, DATA, { memoize: MEMO }) t.deepEqual( MEMO.get(`digest:${CACHE}:${ENTRY.integrity}`), DATA, 'content entry is in the injected memoizer' ) const obj = {} memo.put(CACHE, ENTRY, DATA, { memoize: obj }) t.deepEqual( memo.get(CACHE, ENTRY.key, { memoize: obj }), { entry: ENTRY, data: DATA }, 'entry fetched from injected object memoizer' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: MEMO }), DATA, 'content entry fetched from injected object memoizer' ) memo.clearMemoized() memo.put(CACHE, ENTRY, DATA, { memoize: 'foo' }) t.deepEqual( memo.get(CACHE, ENTRY.key, { memoize: 'foo' }), { entry: ENTRY, data: DATA }, 'entry fetched from global memoization obj on non-obj option' ) t.deepEqual( memo.get(CACHE, ENTRY.key, { memoize: 'foo' }), { entry: ENTRY, data: DATA }, 'entry fetched from global memoization obj on non-obj option' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: 'foo' }), DATA, 'content entry fetched global memoizer obj on non-obj option' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: 'foo' }), DATA, 'content entry fetched global memoizer obj on non-obj option' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: false }), DATA, 'content entry fetched global memoizer obj on non-obj option' ) t.deepEqual( memo.get.byDigest(CACHE, ENTRY.integrity, { memoize: false }), DATA, 'content entry fetched global memoizer obj on non-obj option' ) t.done() }) cacache-11.3.3/test/put.js000066400000000000000000000111721350173612200152750ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const fromString = require('./util/from-string') const fs = BB.promisifyAll(require('fs')) const index = require('../lib/entry-index') const memo = require('../lib/memoization') const path = require('path') const pipe = BB.promisify(require('mississippi').pipe) const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') const CACHE = path.join(testDir, 'cache') const CONTENT = Buffer.from('foobarbaz', 'utf8') const KEY = 'my-test-key' const INTEGRITY = ssri.fromData(CONTENT).toString() const METADATA = { foo: 'bar' } const contentPath = require('../lib/content/path') var put = require('..').put test('basic bulk insertion', t => { return put(CACHE, KEY, CONTENT).then(integrity => { t.equal(integrity.toString(), INTEGRITY, 'returned content integrity') const dataPath = contentPath(CACHE, integrity) return fs.readFileAsync(dataPath) }).then(data => { t.deepEqual(data, CONTENT, 'content was correctly inserted') }) }) test('basic stream insertion', t => { let int const src = fromString(CONTENT) const stream = put.stream(CACHE, KEY).on('integrity', i => { int = i }) return pipe(src, stream).then(() => { t.equal(int.toString(), INTEGRITY, 'returned integrity matches expected') return fs.readFileAsync(contentPath(CACHE, int)) }).then(data => { t.deepEqual(data, CONTENT, 'contents are identical to inserted content') }) }) test('adds correct entry to index before finishing', t => { return put(CACHE, KEY, CONTENT, { metadata: METADATA }).then(() => { return index.find(CACHE, KEY) }).then(entry => { t.ok(entry, 'got an entry') t.equal(entry.key, KEY, 'entry has the right key') t.equal(entry.integrity, INTEGRITY, 'entry has the right key') t.deepEqual(entry.metadata, METADATA, 'metadata also inserted') }) }) test('optionally memoizes data on bulk insertion', t => { return put(CACHE, KEY, CONTENT, { metadata: METADATA, memoize: true }).then(integrity => { t.equal(integrity.toString(), INTEGRITY, 'integrity returned as usual') return index.find(CACHE, KEY) // index.find is not memoized }).then(entry => { t.deepEqual(memo.get(CACHE, KEY), { data: CONTENT, entry: entry }, 'content inserted into memoization cache by key') t.deepEqual( memo.get.byDigest(CACHE, INTEGRITY), CONTENT, 'content inserted into memoization cache by integrity' ) }) }) test('optionally memoizes data on stream insertion', t => { let int const src = fromString(CONTENT) const stream = put.stream(CACHE, KEY, { metadata: METADATA, memoize: true }).on('integrity', i => { int = i }) return pipe(src, stream).then(() => { t.equal(int.toString(), INTEGRITY, 'integrity emitted as usual') return fs.readFileAsync(contentPath(CACHE, int)) }).then(data => { t.deepEqual(data, CONTENT, 'contents are identical to inserted content') return index.find(CACHE, KEY) // index.find is not memoized }).then(entry => { t.deepEqual(memo.get(CACHE, KEY), { data: CONTENT, entry: entry }, 'content inserted into memoization cache by key') t.deepEqual( memo.get.byDigest(CACHE, INTEGRITY), CONTENT, 'content inserted into memoization cache by integrity' ) }) }) test('errors if integrity errors', t => { return BB.join( put(CACHE, KEY, CONTENT, { integrity: 'sha1-BaDDigEST' }).catch(err => { t.equal(err.code, 'EINTEGRITY', 'got error from bad integrity') }) ) }) test('signals error if error writing to cache', t => { return BB.join( put(CACHE, KEY, CONTENT, { size: 2 }).then(() => { throw new Error('expected error') }).catch(err => err), pipe(fromString(CONTENT), put.stream(CACHE, KEY, { size: 2 })).then(() => { throw new Error('expected error') }).catch(err => err), (bulkErr, streamErr) => { t.equal(bulkErr.code, 'EBADSIZE', 'got error from bulk write') t.equal(streamErr.code, 'EBADSIZE', 'got error from stream write') } ) }) test('errors if input stream errors', t => { let int const putter = put.stream(CACHE, KEY).on('integrity', i => { int = i }) const stream = fromString(false) return pipe( stream, putter ).then(() => { throw new Error('expected error') }).catch(err => { t.ok(err, 'got an error') t.ok(!int, 'no integrity returned') t.match( err.message, /Invalid non-string/, 'returns the error from input stream' ) return fs.readdirAsync(testDir) }).then(files => { t.deepEqual(files, [], 'no files created') }) }) cacache-11.3.3/test/rm.js000066400000000000000000000052541350173612200151070ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const fs = BB.promisifyAll(require('fs')) const index = require('../lib/entry-index') const path = require('path') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') const CacheContent = require('./util/cache-content') const CACHE = path.join(testDir, 'cache') const CONTENT = Buffer.from('foobarbaz') const KEY = 'my-test-key' const INTEGRITY = ssri.fromData(CONTENT) const METADATA = { foo: 'bar' } const contentPath = require('../lib/content/path') const get = require('..').get const rm = require('..').rm test('rm.entry removes entries, not content', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, { metadata: METADATA }).then(() => { t.equal(rm, rm.entry, 'rm is an alias for rm.entry') return rm.entry(CACHE, KEY) }).then(() => { return get(CACHE, KEY) }).then(res => { throw new Error('unexpected success') }).catch({ code: 'ENOENT' }, err => { t.match(err.message, KEY, 'entry no longer accessible') }).then(() => { return fs.readFileAsync(contentPath(CACHE, INTEGRITY)) }).then(data => { t.deepEqual(data, CONTENT, 'content remains in cache') }) }) test('rm.content removes content, not entries', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, { metadata: METADATA }).then(() => { return rm.content(CACHE, INTEGRITY) }).then(() => { return get(CACHE, KEY) }).then(res => { throw new Error('unexpected success') }).catch({ code: 'ENOENT' }, err => { t.match(err.message, /no such file/, 'entry no longer accessible') }).then(() => { return fs.readFileAsync(contentPath(CACHE, INTEGRITY)) }).then(() => { throw new Error('unexpected success') }).catch({ code: 'ENOENT' }, err => { t.match(err.message, /no such file/, 'content gone') }) }) test('rm.all deletes content and index dirs', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return index.insert(CACHE, KEY, INTEGRITY, { metadata: METADATA }).then(() => { return fs.mkdirAsync(path.join(CACHE, 'tmp')) }).then(() => { return fs.writeFileAsync(path.join(CACHE, 'other.js'), 'hi') }).then(() => { return rm.all(CACHE) }).then(() => { return fs.readdirAsync(CACHE) }).then(files => { t.deepEqual(files.sort(), [ 'other.js', 'tmp' ], 'removes content and index directories without touching other stuff') }) }) cacache-11.3.3/test/strict.js000066400000000000000000000013661350173612200160010ustar00rootroot00000000000000'use strict' const fs = require('fs') const glob = require('glob') const path = require('path') const test = require('tap').test test('all JavaScript source files use strict mode', function (t) { const globStr = '**/*.js' const root = path.resolve(__dirname, '../') glob(globStr, { cwd: root, ignore: 'node_modules/**/*.js' }, function (err, files) { if (err) { throw err } const line = "'use strict'\n" const bytecount = line.length const buf = Buffer.alloc(bytecount) files.forEach(function (f) { const fd = fs.openSync(path.join(root, f), 'r') fs.readSync(fd, buf, 0, bytecount, 0) fs.closeSync(fd) t.equal(buf.toString('utf8'), line, f + ' is using strict mode.') }) t.done() }) }) cacache-11.3.3/test/util.move-file.js000066400000000000000000000054601350173612200173270ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const fs = require('fs') const path = require('path') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const Dir = Tacks.Dir const File = Tacks.File const moveFile = require('../lib/util/move-file') BB.promisifyAll(fs) test('move a file', function (t) { const fixture = new Tacks(Dir({ src: File('foo') })) fixture.create(testDir) return moveFile('src', 'dest').then(() => { return fs.readFileAsync('dest', 'utf8') }).then(data => { t.equal(data, 'foo', 'file data correct') return fs.statAsync('src').catch(err => { t.ok(err, 'src read error') t.equal(err.code, 'ENOENT', 'src does not exist') }) }) }) test('does not clobber existing files', function (t) { const fixture = new Tacks(Dir({ src: File('foo'), dest: File('bar') })) fixture.create(testDir) return moveFile('src', 'dest').then(() => { return fs.readFileAsync('dest', 'utf8') }).then(data => { t.equal(data, 'bar', 'conflicting file left intact') return fs.statAsync('src').catch(err => { t.ok(err, 'src read error') t.equal(err.code, 'ENOENT', 'src file still deleted') }) }) }) test('does not move a file into an existing directory', function (t) { const fixture = new Tacks(Dir({ src: File('foo'), dest: Dir({}) })) fixture.create(testDir) return moveFile('src', 'dest').then(() => { return fs.readdirAsync('dest') }).then(files => { t.equal(files.length, 0, 'directory remains empty') }) }) test('does not error if destination file is open', function (t) { const fixture = new Tacks(Dir({ src: File('foo'), dest: File('bar') })) fixture.create(testDir) return fs.openAsync('dest', 'r+').then(fd => { return moveFile('src', 'dest').then(() => { return fs.closeAsync(fd) }).then(() => { return fs.readFileAsync('dest', 'utf8') }).then(data => { t.equal(data, 'bar', 'destination left intact') return fs.statAsync('src').catch(err => { t.ok(err, 'src read error') t.equal(err.code, 'ENOENT', 'src does not exist') }) }) }) }) test('errors if dest is not writable', { skip: process.platform === 'win32' }, function (t) { const fixture = new Tacks(Dir({ src: File('foo'), dest: Dir({}) })) fixture.create(testDir) return fs.chmodAsync('dest', parseInt('400', 8)).then(() => { return moveFile('src', path.join('dest', 'file')).then(() => { throw new Error('move succeeded and should not have') }).catch(err => { t.ok(err, 'error was returned') t.equal(err.code, 'EACCES', 'error is about permissions') return fs.readFileAsync('src', 'utf8') }) }).then(data => { t.equal(data, 'foo', 'src contents left intact') }) }) cacache-11.3.3/test/util.tmp.js000066400000000000000000000023641350173612200162440ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const fs = BB.promisifyAll(require('graceful-fs')) const path = require('path') const test = require('tap').test const CACHE = require('./util/test-dir')(__filename) const tmp = require('../lib/util/tmp') test('creates a unique tmpdir inside the cache', t => { return tmp.mkdir(CACHE).then(dir => { t.match(path.relative(CACHE, dir), /^tmp[\\/].*/, 'returns a path inside tmp') return fs.statAsync(dir) }).then(stat => { t.ok(stat.isDirectory(), 'path points to an existing directory') }) }) test('provides a utility that does resource disposal on tmp', t => { return tmp.withTmp(CACHE, dir => { return fs.statAsync(dir).then(stat => { t.ok(stat.isDirectory(), 'path points to an existing directory') }).then(() => dir) }).then(dir => { return BB.join( fs.statAsync(dir).then(() => { throw new Error('expected fail') }).catch({ code: 'ENOENT' }, () => {}), fs.statAsync(path.join(CACHE, 'tmp')), (nope, yes) => { t.notOk(nope, 'tmp subdir removed') t.ok(yes.isDirectory(), 'tmp parent dir left intact') } ) }) }) test('makes sure ownership is correct') test('provides a function for fixing ownership in the tmp dir') cacache-11.3.3/test/util/000077500000000000000000000000001350173612200151025ustar00rootroot00000000000000cacache-11.3.3/test/util/cache-content.js000066400000000000000000000013611350173612200201540ustar00rootroot00000000000000'use strict' const contentPath = require('../../lib/content/path') const path = require('path') const Tacks = require('tacks') const Dir = Tacks.Dir const File = Tacks.File module.exports = CacheContent function CacheContent (entries) { var tree = Dir({}) Object.keys(entries).forEach(function (k) { const cpath = contentPath('', k) const content = entries[k] const parts = cpath.split(path.sep) insertContent(tree, parts, content) }) return tree } function insertContent (tree, pathTo, content) { const key = pathTo[0] if (pathTo.length <= 1) { tree.contents[key] = File(content) } else { tree.contents[key] = tree.contents[key] || Dir({}) insertContent(tree.contents[key], pathTo.slice(1), content) } } cacache-11.3.3/test/util/cache-index.js000066400000000000000000000027371350173612200176210ustar00rootroot00000000000000'use strict' const index = require('../../lib/entry-index') const path = require('path') const Tacks = require('tacks') const bucketPath = index._bucketPath const hashEntry = index._hashEntry const Dir = Tacks.Dir const File = Tacks.File // Creates a simulated index using the chained lookup structure, from // an unhashed version of the index (basically `cacache.ls`). // // The returned object is for use with Tacks module.exports = CacheIndex function CacheIndex (entries) { var tree = Dir({}) Object.keys(entries).forEach(function (k) { const bpath = bucketPath('', k) const parts = bpath.split(path.sep) let lines = entries[k] let serialised if (typeof lines === 'string') { serialised = lines } else { if (typeof lines.length !== 'number') { lines = [lines] } serialised = '\n' + lines.map(line => { const stringified = JSON.stringify(line) return `${hashEntry(stringified)}\t${stringified}` }).join('\n') } insertContent(tree, parts, serialised) }) return tree } function insertContent (tree, pathTo, content) { const key = pathTo[0] if (pathTo.length <= 1) { if (tree.contents[key]) { tree.contents[key] = File([ tree.contents[key].contents, content ].join('\n')) } else { tree.contents[key] = File(content) } } else { tree.contents[key] = tree.contents[key] || Dir({}) insertContent(tree.contents[key], pathTo.slice(1), content) } } cacache-11.3.3/test/util/from-string.js000066400000000000000000000003461350173612200177120ustar00rootroot00000000000000'use strict' var through = require('mississippi').through module.exports = fromString function fromString (str) { var stream = through() setTimeout(function () { stream.write(str) stream.end() }) return stream } cacache-11.3.3/test/util/test-dir.js000066400000000000000000000016471350173612200172030ustar00rootroot00000000000000'use strict' const mkdirp = require('mkdirp') const path = require('path') const rimraf = require('rimraf') const tap = require('tap') const cacheDir = path.resolve(__dirname, '../cache') module.exports = testDir function testDir (filename) { const base = path.basename(filename, '.js') const dir = path.join(cacheDir, base) tap.beforeEach(cb => { reset(dir, err => { if (err) { throw err } cb() }) }) if (!process.env.KEEPCACHE) { tap.tearDown(() => { process.chdir(__dirname) // This is ok cause this is the last // thing to run in the process rimraf(dir, () => {}) }) } return dir } module.exports.reset = reset function reset (testDir, cb) { process.chdir(__dirname) rimraf(testDir, function (err) { if (err) { return cb(err) } mkdirp(testDir, function (err) { if (err) { return cb(err) } process.chdir(testDir) cb() }) }) } cacache-11.3.3/test/verify.js000066400000000000000000000163461350173612200160010ustar00rootroot00000000000000'use strict' const BB = require('bluebird') const contentPath = require('../lib/content/path') const index = require('../lib/entry-index') const fs = BB.promisifyAll(require('graceful-fs')) const path = require('path') const Tacks = require('tacks') const test = require('tap').test const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') const CacheContent = require('./util/cache-content') const CACHE = path.join(testDir, 'cache') const CONTENT = Buffer.from('foobarbaz', 'utf8') const KEY = 'my-test-key' const INTEGRITY = ssri.fromData(CONTENT) const METADATA = { foo: 'bar' } const BUCKET = index._bucketPath(CACHE, KEY) const verify = require('..').verify function mockCache () { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return fs.mkdirAsync(path.join(CACHE, 'tmp')).then(() => { return index.insert(CACHE, KEY, INTEGRITY, { metadata: METADATA }) }) } test('removes corrupted index entries from buckets', t => { return mockCache().then(() => { return fs.readFileAsync(BUCKET, 'utf8').then(BUCKETDATA => { // traaaaash return fs.appendFileAsync(BUCKET, '\n234uhhh').then(() => { return verify(CACHE) }).then(stats => { t.equal(stats.missingContent, 0, 'content valid because of good entry') t.equal(stats.totalEntries, 1, 'only one entry counted') return fs.readFileAsync(BUCKET, 'utf8') }).then(bucketData => { const bucketEntry = JSON.parse(bucketData.split('\t')[1]) const targetEntry = JSON.parse(BUCKETDATA.split('\t')[1]) targetEntry.time = bucketEntry.time // different timestamps t.deepEqual( bucketEntry, targetEntry, 'bucket only contains good entry') }) }) }) }) test('removes shadowed index entries from buckets', t => { return mockCache().then(() => { return index.insert(CACHE, KEY, INTEGRITY, { metadata: 'meh' }).then(newEntry => { return verify(CACHE).then(stats => { t.equal(stats.missingContent, 0, 'content valid because of good entry') t.equal(stats.totalEntries, 1, 'only one entry counted') return fs.readFileAsync(BUCKET, 'utf8') }).then(bucketData => { const stringified = JSON.stringify({ key: newEntry.key, integrity: newEntry.integrity.toString(), time: +(bucketData.match(/"time":([0-9]+)/)[1]), metadata: newEntry.metadata }) t.equal( bucketData, `\n${index._hashEntry(stringified)}\t${stringified}`, 'only the most recent entry is still in the bucket' ) }) }) }) }) test('accepts function for custom user filtering of index entries', t => { const KEY2 = KEY + 'aaa' const KEY3 = KEY + 'bbb' return mockCache().then(() => { return BB.join( index.insert(CACHE, KEY2, INTEGRITY, { metadata: 'haayyyy' }), index.insert(CACHE, KEY3, INTEGRITY, { metadata: 'haayyyy again' }), (entryA, entryB) => ({ [entryA.key]: entryA, [entryB.key]: entryB }) ) }).then(newEntries => { return verify(CACHE, { filter (entry) { return entry.key.length === KEY2.length } }).then(stats => { t.deepEqual({ verifiedContent: stats.verifiedContent, rejectedEntries: stats.rejectedEntries, totalEntries: stats.totalEntries }, { verifiedContent: 1, rejectedEntries: 1, totalEntries: 2 }, 'reported relevant changes') return index.ls(CACHE) }).then(entries => { entries[KEY2].time = newEntries[KEY2].time entries[KEY3].time = newEntries[KEY3].time t.deepEqual(entries, newEntries, 'original entry not included') }) }) }) test('removes corrupted content', t => { const cpath = contentPath(CACHE, INTEGRITY) return mockCache().then(() => { return fs.truncateAsync(cpath, CONTENT.length - 1) }).then(() => { return verify(CACHE) }).then(stats => { delete stats.startTime delete stats.runTime delete stats.endTime t.deepEqual(stats, { verifiedContent: 0, reclaimedCount: 1, reclaimedSize: CONTENT.length - 1, badContentCount: 1, keptSize: 0, missingContent: 1, rejectedEntries: 1, totalEntries: 0 }, 'reported correct collection counts') return fs.statAsync(cpath).then(() => { throw new Error('expected a failure') }).catch({ code: 'ENOENT' }, err => { t.match(err.message, /no such file/, 'content no longer in cache') }) }) }) test('removes content not referenced by any entries', t => { const fixture = new Tacks(CacheContent({ [INTEGRITY]: CONTENT })) fixture.create(CACHE) return verify(CACHE).then(stats => { delete stats.startTime delete stats.runTime delete stats.endTime t.deepEqual(stats, { verifiedContent: 0, reclaimedCount: 1, reclaimedSize: CONTENT.length, badContentCount: 0, keptSize: 0, missingContent: 0, rejectedEntries: 0, totalEntries: 0 }, 'reported correct collection counts') }) }) test('cleans up contents of tmp dir', t => { const tmpFile = path.join(CACHE, 'tmp', 'x') const misc = path.join(CACHE, 'y') return mockCache().then(() => { return BB.join( fs.writeFileAsync(tmpFile, ''), fs.writeFileAsync(misc, ''), () => verify(CACHE) ) }).then(() => { return BB.join( fs.statAsync(tmpFile).catch({ code: 'ENOENT' }, e => e), fs.statAsync(misc), (err, stat) => { t.equal(err.code, 'ENOENT', 'tmp file was blown away') t.ok(stat, 'misc file was not touched') } ) }) }) test('writes a file with last verification time', t => { return verify(CACHE).then(() => { return BB.join( verify.lastRun(CACHE), fs.readFileAsync( path.join(CACHE, '_lastverified'), 'utf8' ).then(data => { return new Date(parseInt(data)) }), (fromLastRun, fromFile) => { t.equal(+fromLastRun, +fromFile, 'last verified was writen') } ) }) }) test('fixes permissions and users on cache contents') test('re-builds the index with the size parameter', t => { const KEY2 = KEY + 'aaa' const KEY3 = KEY + 'bbb' return mockCache().then(() => { return BB.join( index.insert(CACHE, KEY2, INTEGRITY, { metadata: 'haayyyy', size: 20 }), index.insert(CACHE, KEY3, INTEGRITY, { metadata: 'haayyyy again', size: 30 })) }).then(() => { return index.ls(CACHE).then((newEntries) => { return verify(CACHE) .then(stats => { t.deepEqual({ verifiedContent: stats.verifiedContent, rejectedEntries: stats.rejectedEntries, totalEntries: stats.totalEntries }, { verifiedContent: 1, rejectedEntries: 0, totalEntries: 3 }, 'reported relevant changes') return index.ls(CACHE) }).then(entries => { entries[KEY].time = newEntries[KEY].time entries[KEY2].time = newEntries[KEY2].time entries[KEY3].time = newEntries[KEY3].time t.deepEqual(entries, newEntries, 'original index entries not preserved') }) }) }) }) cacache-11.3.3/verify.js000066400000000000000000000000671350173612200150130ustar00rootroot00000000000000'use strict' module.exports = require('./lib/verify')