node-cacache-15.0.5/000077500000000000000000000000001374506532500141065ustar00rootroot00000000000000node-cacache-15.0.5/.github/000077500000000000000000000000001374506532500154465ustar00rootroot00000000000000node-cacache-15.0.5/.github/CODEOWNERS000066400000000000000000000000201374506532500170310ustar00rootroot00000000000000* @npm/cli-team node-cacache-15.0.5/.github/settings.yml000066400000000000000000000000601374506532500200250ustar00rootroot00000000000000--- _extends: 'open-source-project-boilerplate' node-cacache-15.0.5/.github/workflows/000077500000000000000000000000001374506532500175035ustar00rootroot00000000000000node-cacache-15.0.5/.github/workflows/ci.yml000066400000000000000000000072431374506532500206270ustar00rootroot00000000000000--- ################################################################################ # Template - Node CI # # Description: # This contains the basic information to: install dependencies, run tests, # get coverage, and run linting on a nodejs project. This template will run # over the MxN matrix of all operating systems, and all current LTS versions # of NodeJS. # # Dependencies: # This template assumes that your project is using the `tap` module for # testing. If you're not using this module, then the step that runs your # coverage will need to be adjusted. # ################################################################################ name: Node CI on: [push, pull_request] jobs: build: strategy: fail-fast: false matrix: node-version: [10.x, 12.x, 13.x] os: [ubuntu-latest, macOS-latest] runs-on: ${{ matrix.os }} steps: # Checkout the repository - uses: actions/checkout@v2 # Installs the specific version of Node.js - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} ################################################################################ # Install Dependencies # # ASSUMPTIONS: # - The project has a package-lock.json file # # Simply run the tests for the project. ################################################################################ - name: Install dependencies run: npm ci ################################################################################ # Run Testing # # ASSUMPTIONS: # - The project has `tap` as a devDependency # - There is a script called "test" in the package.json # # Simply run the tests for the project. ################################################################################ - name: Run tests run: npm test -- --no-coverage ################################################################################ # Run coverage check # # ASSUMPTIONS: # - The project has `tap` as a devDependency # - There is a script called "coverage" in the package.json # # Coverage should only be posted once, we are choosing the latest LTS of # node, and ubuntu as the matrix point to post coverage from. We limit # to the 'push' event so that coverage ins't posted twice from the # pull-request event, and push event (line 3). ################################################################################ - name: Run coverage report if: github.event_name == 'push' && matrix.node-version == '12.x' && matrix.os == 'ubuntu-latest' run: npm run coverage env: # The environment variable name is leveraged by `tap` COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }} ################################################################################ # Run linting # # ASSUMPTIONS: # - There is a script called "lint" in the package.json # # We run linting AFTER we run testing and coverage checks, because if a step # fails in an GitHub Action, all other steps are not run. We don't want to # fail to run tests or coverage because of linting. It should be the lowest # priority of all the steps. ################################################################################ - name: Run linter if: github.event_name == 'push' && matrix.node-version == '12.x' && matrix.os == 'ubuntu-latest' run: npm run lint node-cacache-15.0.5/CHANGELOG.md000066400000000000000000000707121374506532500157260ustar00rootroot00000000000000# 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. ### [15.0.5](https://github.com/npm/cacache/compare/v15.0.4...v15.0.5) (2020-07-11) ### [15.0.4](https://github.com/npm/cacache/compare/v15.0.3...v15.0.4) (2020-06-03) ### Bug Fixes * replace move-file dep with @npmcli/move-file ([bf88af0](https://github.com/npm/cacache/commit/bf88af04e50cca9b54041151139ffc1fd415e2dc)), closes [#37](https://github.com/npm/cacache/issues/37) ### [15.0.3](https://github.com/npm/cacache/compare/v15.0.2...v15.0.3) (2020-04-28) ### Bug Fixes * actually remove move-concurrently dep ([29e6eec](https://github.com/npm/cacache/commit/29e6eec9fee73444ee09daf1c1be06ddd5fe57f6)) ### [15.0.2](https://github.com/npm/cacache/compare/v15.0.1...v15.0.2) (2020-04-28) ### Bug Fixes * tacks should be a dev dependency ([93ec158](https://github.com/npm/cacache/commit/93ec15852f0fdf1753ea7f75b4b8926daf8a7565)) ## [15.0.1](https://github.com/npm/cacache/compare/v15.0.0...v15.0.1) (2020-04-27) * **deps:** Use move-file instead of move-file-concurrently. ([92b125](https://github.com/npm/cacache/commit/92b1251a11b9848878b6c0d101b18bd8845acaa6)) ## [15.0.0](https://github.com/npm/cacache/compare/v14.0.0...v15.0.0) (2020-02-18) ### ⚠ BREAKING CHANGES * drop figgy-pudding and use canonical option names. ### Features * remove figgy-pudding ([57d11bc](https://github.com/npm/cacache/commit/57d11bce34f979247d1057d258acc204c4944491)) ## [14.0.0](https://github.com/npm/cacache/compare/v13.0.1...v14.0.0) (2020-01-28) ### ⚠ BREAKING CHANGES * **deps:** bumps engines to >= 10 * **deps:** tar v6 and mkdirp v1 ([5a66e7a](https://github.com/npm/cacache/commit/5a66e7a)) ### [13.0.1](https://github.com/npm/cacache/compare/v13.0.0...v13.0.1) (2019-09-30) ### Bug Fixes * **fix-owner:** chownr.sync quits on non-root uid ([08801be](https://github.com/npm/cacache/commit/08801be)) ## [13.0.0](https://github.com/npm/cacache/compare/v12.0.3...v13.0.0) (2019-09-25) ### ⚠ BREAKING CHANGES * This subtly changes the streaming interface of everything in cacache that streams, which is, well, everything in cacache. Most users will probably not notice, but any code that depended on stream behavior always being deferred until next tick will need to adjust. The mississippi methods 'to', 'from', 'through', and so on, have been replaced with their Minipass counterparts, and streaming interaction with the file system is done via fs-minipass. The following modules are of interest here: - [minipass](http://npm.im/minipass) The core stream library. - [fs-minipass](http://npm.im/fs-minipass) Note that the 'WriteStream' class from fs-minipass is _not_ a Minipass stream, but rather a plain old EventEmitter that duck types as a Writable. - [minipass-collect](http://npm.im/minipass-collect) Gather up all the data from a stream. Cacache only uses Collect.PassThrough, which is a basic Minipass passthrough stream which emits a 'collect' event with the completed data just before the 'end' event. - [minipass-pipeline](http://npm.im/minipass-pipeline) Connect one or more streams into a pipe chain. Errors anywhere in the pipeline are proxied down the chain and then up to the Pipeline object itself. Writes go into the head, reads go to the tail. Used in place of pump() and pumpify(). - [minipass-flush](http://npm.im/minipass-flush) A Minipass passthrough stream that defers its 'end' event until after a flush() method has completed (either calling the supplied callback, or returning a promise.) Use in place of flush-write-stream (aka mississippi.to). Streams from through2, concat-stream, and the behavior provided by end-of-stream are all implemented in Minipass itself. Features of interest to cacache, which make Minipass a particularly good fit: - All of the 'endish' events are normalized, so we can just listen on 'end' and know that finish, prefinish, and close will be handled as well. - Minipass doesn't waste time [containing zalgo](https://blog.izs.me/2013/08/designing-apis-for-asynchrony). - Minipass has built-in support for promises that indicate the end or error: stream.promise(), stream.collect(), and stream.concat(). - With reliable and consistent timing guarantees, much less error-checking logic is required. We can be more confident that an error is being thrown or emitted in the correct place, rather than in a callback which is deferred, resulting in a hung promise or uncaughtException. The biggest downside of Minipass is that it lacks some of the internal characteristics of node-core streams, which many community modules use to identify streams. They have no _writableState or _readableState objects, or _read or _write methods. As a result, the is-stream module (at least, at the time of this commit) doesn't recognize Minipass streams as readable or writable streams. All in all, the changes required of downstream users should be minimal, but are unlikely to be zero. Hence the semver major change. ### Features * replace all streams with Minipass streams ([f4c0962](https://github.com/npm/cacache/commit/f4c0962)) * **deps:** Add minipass and minipass-pipeline ([a6545a9](https://github.com/npm/cacache/commit/a6545a9)) * **promise:** converted .resolve to native promise, converted .map and .reduce to native ([220c56d](https://github.com/npm/cacache/commit/220c56d)) * **promise:** individually promisifing functions as needed ([74b939e](https://github.com/npm/cacache/commit/74b939e)) * **promise:** moved .reject from bluebird to native promise ([1d56da1](https://github.com/npm/cacache/commit/1d56da1)) * **promise:** removed .fromNode, removed .join ([9c457a0](https://github.com/npm/cacache/commit/9c457a0)) * **promise:** removed .map, replaced with p-map. removed .try ([cc3ee05](https://github.com/npm/cacache/commit/cc3ee05)) * **promise:** removed .tap ([0260f12](https://github.com/npm/cacache/commit/0260f12)) * **promise:** removed .using/.disposer ([5d832f3](https://github.com/npm/cacache/commit/5d832f3)) * **promise:** removed bluebird ([c21298c](https://github.com/npm/cacache/commit/c21298c)) * **promise:** removed bluebird specific .catch calls ([28aeeac](https://github.com/npm/cacache/commit/28aeeac)) * **promise:** replaced .reduce and .mapSeries ([478f5cb](https://github.com/npm/cacache/commit/478f5cb)) ### [12.0.3](https://github.com/npm/cacache/compare/v12.0.2...v12.0.3) (2019-08-19) ### Bug Fixes * do not chown if not running as root ([2d80af9](https://github.com/npm/cacache/commit/2d80af9)) ### [12.0.2](https://github.com/npm/cacache/compare/v12.0.1...v12.0.2) (2019-07-19) ### [12.0.1](https://github.com/npm/cacache/compare/v12.0.0...v12.0.1) (2019-07-19) * **deps** Abstracted out `lib/util/infer-owner.js` to [@npmcli/infer-owner](https://www.npmjs.com/package/@npmcli/infer-owner) so that it could be more easily used in other parts of the npm CLI. ## [12.0.0](https://github.com/npm/cacache/compare/v11.3.3...v12.0.0) (2019-07-15) ### Features * infer uid/gid instead of accepting as options ([ac84d14](https://github.com/npm/cacache/commit/ac84d14)) * **i18n:** add another error message ([676cb32](https://github.com/npm/cacache/commit/676cb32)) ### BREAKING CHANGES * the uid gid options are no longer respected or necessary. As of this change, cacache will always match the cache contents to the ownership of the cache directory (or its parent directory), regardless of what the caller passes in. Reasoning: The number one reason to use a uid or gid option was to keep root-owned files from causing problems in the cache. In npm's case, this meant that CLI's ./lib/command.js had to work out the appropriate uid and gid, then pass it to the libnpmcommand module, which had to in turn pass the uid and gid to npm-registry-fetch, which then passed it to make-fetch-happen, which passed it to cacache. (For package fetching, pacote would be in that mix as well.) Added to that, `cacache.rm()` will actually _write_ a file into the cache index, but has no way to accept an option so that its call to entry-index.js will write the index with the appropriate uid/gid. Little ownership bugs were all over the place, and tricky to trace through. (Why should make-fetch-happen even care about accepting or passing uids and gids? It's an http library.) This change allows us to keep the cache from having mixed ownership in any situation. Of course, this _does_ mean that if you have a root-owned but user-writable folder (for example, `/tmp`), then the cache will try to chown everything to root. The solution is for the user to create a folder, make it user-owned, and use that, rather than relying on cacache to create the root cache folder. If we decide to restore the uid/gid opts, and use ownership inference only when uid/gid are unset, then take care to also make rm take an option object, and pass it through to entry-index.js. ### [11.3.3](https://github.com/npm/cacache/compare/v11.3.2...v11.3.3) (2019-06-17) ### Bug Fixes * **audit:** npm audit fix ([200a6d5](https://github.com/npm/cacache/commit/200a6d5)) * **config:** Add ssri config 'error' option ([#146](https://github.com/npm/cacache/issues/146)) ([47de8f5](https://github.com/npm/cacache/commit/47de8f5)) * **deps:** npm audit fix ([481a7dc](https://github.com/npm/cacache/commit/481a7dc)) * **standard:** standard --fix ([7799149](https://github.com/npm/cacache/commit/7799149)) * **write:** avoid another cb never called situation ([5156561](https://github.com/npm/cacache/commit/5156561)) ## [11.3.2](https://github.com/npm/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/npm/cacache/commit/b10bcd0)) ## [11.3.1](https://github.com/npm/cacache/compare/v11.3.0...v11.3.1) (2018-11-05) ### Bug Fixes * **get:** export hasContent.sync properly ([d76c920](https://github.com/npm/cacache/commit/d76c920)) # [11.3.0](https://github.com/npm/cacache/compare/v11.2.0...v11.3.0) (2018-11-05) ### Features * **get:** add sync API for reading ([db1e094](https://github.com/npm/cacache/commit/db1e094)) # [11.2.0](https://github.com/npm/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/npm/cacache/commit/fe638b6)) # [11.1.0](https://github.com/npm/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/npm/cacache/commit/b43af83)) ## [11.0.3](https://github.com/npm/cacache/compare/v11.0.2...v11.0.3) (2018-08-01) ### Bug Fixes * **config:** add ssri config options ([#136](https://github.com/npm/cacache/issues/136)) ([10d5d9a](https://github.com/npm/cacache/commit/10d5d9a)) * **perf:** refactor content.read to avoid lstats ([c5ac10e](https://github.com/npm/cacache/commit/c5ac10e)) * **test:** oops when removing safe-buffer ([1950490](https://github.com/npm/cacache/commit/1950490)) ## [11.0.2](https://github.com/npm/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/npm/cacache/issues/131)) ([c614a19](https://github.com/npm/cacache/commit/c614a19)), closes [#130](https://github.com/npm/cacache/issues/130) ## [11.0.1](https://github.com/npm/cacache/compare/v11.0.0...v11.0.1) (2018-04-10) # [11.0.0](https://github.com/npm/cacache/compare/v10.0.4...v11.0.0) (2018-04-09) ### Features * **opts:** use figgy-pudding for opts ([#128](https://github.com/npm/cacache/issues/128)) ([33d4eed](https://github.com/npm/cacache/commit/33d4eed)) ### meta * drop support for node@4 ([529f347](https://github.com/npm/cacache/commit/529f347)) ### BREAKING CHANGES * node@4 is no longer supported ## [10.0.4](https://github.com/npm/cacache/compare/v10.0.3...v10.0.4) (2018-02-16) ## [10.0.3](https://github.com/npm/cacache/compare/v10.0.2...v10.0.3) (2018-02-16) ### Bug Fixes * **content:** rethrow aggregate errors as ENOENT ([fa918f5](https://github.com/npm/cacache/commit/fa918f5)) ## [10.0.2](https://github.com/npm/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/npm/cacache/commit/347dc36)) ## [10.0.1](https://github.com/npm/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/npm/cacache/commit/073fbe1)) # [10.0.0](https://github.com/npm/cacache/compare/v9.3.0...v10.0.0) (2017-10-23) ### Features * **license:** relicense to ISC (#111) ([fdbb4e5](https://github.com/npm/cacache/commit/fdbb4e5)) ### Performance Improvements * more copyFile benchmarks ([63787bb](https://github.com/npm/cacache/commit/63787bb)) ### BREAKING CHANGES * **license:** the license has been changed from CC0-1.0 to ISC. # [9.3.0](https://github.com/npm/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/npm/cacache/commit/067b5f6)) ## [9.2.9](https://github.com/npm/cacache/compare/v9.2.8...v9.2.9) (2017-06-17) ## [9.2.8](https://github.com/npm/cacache/compare/v9.2.7...v9.2.8) (2017-06-05) ### Bug Fixes * **ssri:** bump ssri for bugfix ([c3232ea](https://github.com/npm/cacache/commit/c3232ea)) ## [9.2.7](https://github.com/npm/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/npm/cacache/commit/4131196)) ## [9.2.6](https://github.com/npm/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/npm/cacache/commit/5209ffe)) ## [9.2.5](https://github.com/npm/cacache/compare/v9.2.4...v9.2.5) (2017-05-25) ### Bug Fixes * **deps:** fix lockfile issues and bump ssri ([84e1d7e](https://github.com/npm/cacache/commit/84e1d7e)) ## [9.2.4](https://github.com/npm/cacache/compare/v9.2.3...v9.2.4) (2017-05-24) ### Bug Fixes * **deps:** bumping deps ([bbccb12](https://github.com/npm/cacache/commit/bbccb12)) ## [9.2.3](https://github.com/npm/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/npm/cacache/commit/ac90bc0)) ## [9.2.2](https://github.com/npm/cacache/compare/v9.2.1...v9.2.2) (2017-05-14) ### Bug Fixes * **i18n:** lets pretend this didn't happen ([519b4ee](https://github.com/npm/cacache/commit/519b4ee)) ## [9.2.1](https://github.com/npm/cacache/compare/v9.2.0...v9.2.1) (2017-05-14) ### Bug Fixes * **docs:** fixing translation messup ([bb9e4f9](https://github.com/npm/cacache/commit/bb9e4f9)) # [9.2.0](https://github.com/npm/cacache/compare/v9.1.0...v9.2.0) (2017-05-14) ### Features * **i18n:** add Spanish translation for API ([531f9a4](https://github.com/npm/cacache/commit/531f9a4)) # [9.1.0](https://github.com/npm/cacache/compare/v9.0.0...v9.1.0) (2017-05-14) ### Features * **i18n:** Add Spanish translation and i18n setup (#91) ([323b90c](https://github.com/npm/cacache/commit/323b90c)) # [9.0.0](https://github.com/npm/cacache/compare/v8.0.0...v9.0.0) (2017-04-28) ### Bug Fixes * **memoization:** actually use the LRU ([0e55dc9](https://github.com/npm/cacache/commit/0e55dc9)) ### Features * **memoization:** memoizers can be injected through opts.memoize (#90) ([e5614c7](https://github.com/npm/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/npm/cacache/compare/v7.1.0...v8.0.0) (2017-04-22) ### Features * **read:** change hasContent to return {sri, size} (#88) ([bad6c49](https://github.com/npm/cacache/commit/bad6c49)), closes [#87](https://github.com/npm/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/npm/cacache/compare/v7.0.5...v7.1.0) (2017-04-20) ### Features * **size:** handle content size info (#49) ([91230af](https://github.com/npm/cacache/commit/91230af)) ## [7.0.5](https://github.com/npm/cacache/compare/v7.0.4...v7.0.5) (2017-04-18) ### Bug Fixes * **integrity:** new ssri with fixed integrity stream ([6d13e8e](https://github.com/npm/cacache/commit/6d13e8e)) * **write:** wrap stuff in promises to improve errors ([3624fc5](https://github.com/npm/cacache/commit/3624fc5)) ## [7.0.4](https://github.com/npm/cacache/compare/v7.0.3...v7.0.4) (2017-04-15) ### Bug Fixes * **fix-owner:** throw away ENOENTs on chownr ([d49bbcd](https://github.com/npm/cacache/commit/d49bbcd)) ## [7.0.3](https://github.com/npm/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/npm/cacache/commit/9d4f0a5)) ## [7.0.2](https://github.com/npm/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/npm/cacache/commit/8dc2e62)) ## [7.0.1](https://github.com/npm/cacache/compare/v7.0.0...v7.0.1) (2017-04-03) ### Bug Fixes * **docs:** fix header name conflict in readme ([afcd456](https://github.com/npm/cacache/commit/afcd456)) # [7.0.0](https://github.com/npm/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/npm/cacache/commit/d2e9b6a)) ### Features * **integrity:** subresource integrity support (#78) ([b1e731f](https://github.com/npm/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/npm/cacache/compare/v6.2.0...v6.3.0) (2017-04-01) ### Bug Fixes * **fixOwner:** ignore EEXIST race condition from mkdirp ([4670e9b](https://github.com/npm/cacache/commit/4670e9b)) * **index:** ignore index removal races when inserting ([b9d2fa2](https://github.com/npm/cacache/commit/b9d2fa2)) * **memo:** use lru-cache for better mem management (#75) ([d8ac5aa](https://github.com/npm/cacache/commit/d8ac5aa)) ### Features * **dependencies:** Switch to move-concurrently (#77) ([dc6482d](https://github.com/npm/cacache/commit/dc6482d)) # [6.2.0](https://github.com/npm/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/npm/cacache/commit/f8e0f25)) * **verify:** return fixOwner.chownr promise ([6818521](https://github.com/npm/cacache/commit/6818521)) ### Features * **tmp:** safe tmp dir creation/management util (#73) ([c42da71](https://github.com/npm/cacache/commit/c42da71)) ## [6.1.2](https://github.com/npm/cacache/compare/v6.1.1...v6.1.2) (2017-03-13) ### Bug Fixes * **index:** set default hashAlgorithm ([d6eb2f0](https://github.com/npm/cacache/commit/d6eb2f0)) ## [6.1.1](https://github.com/npm/cacache/compare/v6.1.0...v6.1.1) (2017-03-13) ### Bug Fixes * **coverage:** bumping coverage for verify (#71) ([0b7faf6](https://github.com/npm/cacache/commit/0b7faf6)) * **deps:** glob should have been a regular dep :< ([0640bc4](https://github.com/npm/cacache/commit/0640bc4)) # [6.1.0](https://github.com/npm/cacache/compare/v6.0.2...v6.1.0) (2017-03-12) ### Bug Fixes * **coverage:** more coverage for content reads (#70) ([ef4f70a](https://github.com/npm/cacache/commit/ef4f70a)) * **tests:** use safe-buffer because omfg (#69) ([6ab8132](https://github.com/npm/cacache/commit/6ab8132)) ### Features * **rm:** limited rm.all and fixed bugs (#66) ([d5d25ba](https://github.com/npm/cacache/commit/d5d25ba)), closes [#66](https://github.com/npm/cacache/issues/66) * **verify:** tested, working cache verifier/gc (#68) ([45ad77a](https://github.com/npm/cacache/commit/45ad77a)) ## [6.0.2](https://github.com/npm/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/npm/cacache/commit/c3644e5)) ## [6.0.1](https://github.com/npm/cacache/compare/v6.0.0...v6.0.1) (2017-03-05) ### Bug Fixes * **docs:** Missed spots in README ([8ffb7fa](https://github.com/npm/cacache/commit/8ffb7fa)) # [6.0.0](https://github.com/npm/cacache/compare/v5.0.3...v6.0.0) (2017-03-05) ### Bug Fixes * **api:** keep memo cache mostly-internal ([2f72d0a](https://github.com/npm/cacache/commit/2f72d0a)) * **content:** use the rest of the string, not the whole string ([fa8f3c3](https://github.com/npm/cacache/commit/fa8f3c3)) * **deps:** removed `format-number@2.0.2` ([1187791](https://github.com/npm/cacache/commit/1187791)) * **deps:** removed inflight@1.0.6 ([0d1819c](https://github.com/npm/cacache/commit/0d1819c)) * **deps:** rimraf@2.6.1 ([9efab6b](https://github.com/npm/cacache/commit/9efab6b)) * **deps:** standard@9.0.0 ([4202cba](https://github.com/npm/cacache/commit/4202cba)) * **deps:** tap@10.3.0 ([aa03088](https://github.com/npm/cacache/commit/aa03088)) * **deps:** weallcontribute@1.0.8 ([ad4f4dc](https://github.com/npm/cacache/commit/ad4f4dc)) * **docs:** add security note to hashKey ([03f81ba](https://github.com/npm/cacache/commit/03f81ba)) * **hashes:** change default hashAlgorithm to sha512 ([ea00ba6](https://github.com/npm/cacache/commit/ea00ba6)) * **hashes:** missed a spot for hashAlgorithm defaults ([45997d8](https://github.com/npm/cacache/commit/45997d8)) * **index:** add length header before JSON for verification ([fb8cb4d](https://github.com/npm/cacache/commit/fb8cb4d)) * **index:** change index filenames to sha1s of keys ([bbc5fca](https://github.com/npm/cacache/commit/bbc5fca)) * **index:** who cares about race conditions anyway ([b1d3888](https://github.com/npm/cacache/commit/b1d3888)) * **perf:** bulk-read get+read for massive speed ([d26cdf9](https://github.com/npm/cacache/commit/d26cdf9)) * **perf:** use bulk file reads for index reads ([79a8891](https://github.com/npm/cacache/commit/79a8891)) * **put-stream:** remove tmp file on stream insert error ([65f6632](https://github.com/npm/cacache/commit/65f6632)) * **put-stream:** robustified and predictibilized ([daf9e08](https://github.com/npm/cacache/commit/daf9e08)) * **put-stream:** use new promise API for moves ([1d36013](https://github.com/npm/cacache/commit/1d36013)) * **readme:** updated to reflect new default hashAlgo ([c60a2fa](https://github.com/npm/cacache/commit/c60a2fa)) * **verify:** tiny typo fix ([db22d05](https://github.com/npm/cacache/commit/db22d05)) ### Features * **api:** converted external api ([7bf032f](https://github.com/npm/cacache/commit/7bf032f)) * **cacache:** exported clearMemoized() utility ([8d2c5b6](https://github.com/npm/cacache/commit/8d2c5b6)) * **cache:** add versioning to content and index ([31bc549](https://github.com/npm/cacache/commit/31bc549)) * **content:** collate content files into subdirs ([c094d9f](https://github.com/npm/cacache/commit/c094d9f)) * **deps:** `@npmcorp/move@1.0.0` ([bdd00bf](https://github.com/npm/cacache/commit/bdd00bf)) * **deps:** `bluebird@3.4.7` ([3a17aff](https://github.com/npm/cacache/commit/3a17aff)) * **deps:** `promise-inflight@1.0.1` ([a004fe6](https://github.com/npm/cacache/commit/a004fe6)) * **get:** added memoization support for get ([c77d794](https://github.com/npm/cacache/commit/c77d794)) * **get:** export hasContent ([2956ec3](https://github.com/npm/cacache/commit/2956ec3)) * **index:** add hashAlgorithm and format insert ret val ([b639746](https://github.com/npm/cacache/commit/b639746)) * **index:** collate index files into subdirs ([e8402a5](https://github.com/npm/cacache/commit/e8402a5)) * **index:** promisify entry index ([cda3335](https://github.com/npm/cacache/commit/cda3335)) * **memo:** added memoization lib ([da07b92](https://github.com/npm/cacache/commit/da07b92)) * **memo:** export memoization api ([954b1b3](https://github.com/npm/cacache/commit/954b1b3)) * **move-file:** add move fallback for weird errors ([5cf4616](https://github.com/npm/cacache/commit/5cf4616)) * **perf:** bulk content write api ([51b536e](https://github.com/npm/cacache/commit/51b536e)) * **put:** added memoization support to put ([b613a70](https://github.com/npm/cacache/commit/b613a70)) * **read:** switched to promises ([a869362](https://github.com/npm/cacache/commit/a869362)) * **rm:** added memoization support to rm ([4205cf0](https://github.com/npm/cacache/commit/4205cf0)) * **rm:** switched to promises ([a000d24](https://github.com/npm/cacache/commit/a000d24)) * **util:** promise-inflight ownership fix requests ([9517cd7](https://github.com/npm/cacache/commit/9517cd7)) * **util:** use promises for api ([ae204bb](https://github.com/npm/cacache/commit/ae204bb)) * **verify:** converted to Promises ([f0b3974](https://github.com/npm/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 node-cacache-15.0.5/LICENSE.md000066400000000000000000000013631374506532500155150ustar00rootroot00000000000000ISC 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. node-cacache-15.0.5/README.md000066400000000000000000000500601374506532500153660ustar00rootroot00000000000000# 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/npm/cacache.svg)](https://travis-ci.org/npm/cacache) [![AppVeyor](https://ci.appveyor.com/api/projects/status/github/npm/cacache?svg=true)](https://ci.appveyor.com/project/npm/cacache) [![Coverage Status](https://coveralls.io/repos/github/npm/cacache/badge.svg?branch=latest)](https://coveralls.io/github/npm/cacache?branch=latest) [`cacache`](https://github.com/npm/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. On systems that support user and group settings on files, cacache will match the `uid` and `gid` values to the folder where the cache lives, even when running as `root`. It was written to be used as [npm](https://npm.im)'s local cache, but can just as easily be used on its own. ## 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) * [`rm.all`](#rm-all) * [`rm.entry`](#rm-entry) * [`rm.content`](#rm-content) * Utilities * [`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') 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 * 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 #### `> 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. See: [options](#get-options) ##### 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. See: [options](#get-options) ##### 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 ``` ##### Options ##### `opts.integrity` If present, the pre-calculated digest for the inserted content. If this option is provided and does not match the post-insertion digest, insertion will fail with an `EINTEGRITY` error. ##### `opts.memoize` Default: null If explicitly truthy, cacache will read from memory and memoize data on bulk read. If `false`, cacache will read from disk data. Reader functions by default read from in-memory cache. ##### `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. #### `> 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. See: [options](#put-options) ##### 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. See: [options](#put-options) ##### 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}`)) ) ``` ##### Options ##### `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 is 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.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. ##### `opts.tmpPrefix` Default: null Prefix to append on the temporary directory name inside the cache's tmp dir. #### `> 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.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 given the appropriate `gid`/`uid` ownership settings to match the rest of the cache. 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) See: [options](#tmp-options) ##### Example ```javascript cacache.tmp.mkdir(cache).then(dir => { fs.writeFile(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }) ``` #### `> tmp.fix(cache) -> Promise` Sets the `uid` and `gid` properties on all files and folders within the tmp folder to match the rest of the cache. Use this after manually writing files into [`tmp.mkdir`](#tmp-mkdir) or [`tmp.withTmp`](#with-tmp). ##### Example ```javascript cacache.tmp.mkdir(cache).then(dir => { writeFile(path.join(dir, 'file'), someData).then(() => { // make sure we didn't just put a root-owned file in the cache cacache.tmp.fix().then(() => { // all uids and gids match now }) }) }) ``` #### `> 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, 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. See: [options](#tmp-options) ##### Example ```javascript cacache.tmp.withTmp(cache, dir => { return fs.writeFileAsync(path.join(dir, 'blablabla'), Buffer#<1234>, ...) }).then(() => { // `dir` no longer exists }) ``` ##### Options ##### `opts.tmpPrefix` Default: null Prefix to append on the temporary directory name inside the cache's tmp dir. #### 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.concurrency` Default: 20 Number of concurrently read files in the filesystem while doing clean up. ##### `opts.filter` Receives a formatted entry. Return false to remove it. Note: might be called more than once on the same entry. ##### `opts.log` Custom logger function: ``` log: { silly () {} } log.silly('verify', 'verifying cache at', cache) ``` ##### 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) }) }) ``` node-cacache-15.0.5/get.js000066400000000000000000000151141374506532500152250ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const index = require('./lib/entry-index') const memo = require('./lib/memoization') const read = require('./lib/content/read') const Minipass = require('minipass') const Collect = require('minipass-collect') const Pipeline = require('minipass-pipeline') const writeFile = util.promisify(fs.writeFile) 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 = {}) { const { integrity, memoize, size } = opts const memoized = byDigest ? memo.get.byDigest(cache, key, opts) : memo.get(cache, key, opts) if (memoized && memoize !== false) { return Promise.resolve( byDigest ? memoized : { metadata: memoized.entry.metadata, data: memoized.data, integrity: memoized.entry.integrity, size: memoized.entry.size } ) } return (byDigest ? Promise.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, size }) .then((data) => byDigest ? data : { data, metadata: entry.metadata, size: entry.size, integrity: entry.integrity } ) .then((res) => { if (memoize && byDigest) { memo.put.byDigest(cache, key, res, opts) } else if (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 = {}) { const { integrity, memoize, size } = opts const memoized = byDigest ? memo.get.byDigest(cache, key, opts) : memo.get(cache, key, opts) if (memoized && 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: integrity, size: size }) const res = byDigest ? data : { metadata: entry.metadata, data: data, size: entry.size, integrity: entry.integrity } if (memoize && byDigest) { memo.put.byDigest(cache, key, res, opts) } else if (memoize) { memo.put(cache, entry, res.data, opts) } return res } module.exports.stream = getStream const getMemoizedStream = (memoized) => { const stream = new Minipass() 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.end(memoized.data) return stream } function getStream (cache, key, opts = {}) { const { memoize, size } = opts const memoized = memo.get(cache, key, opts) if (memoized && memoize !== false) { return getMemoizedStream(memoized) } const stream = new Pipeline() index .find(cache, key) .then((entry) => { if (!entry) { throw new index.NotFoundError(cache, key) } 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) }) const src = read.readStream( cache, entry.integrity, { ...opts, size: typeof size !== 'number' ? entry.size : size } ) if (memoize) { const memoStream = new Collect.PassThrough() memoStream.on('collect', data => memo.put(cache, entry, data, opts)) stream.unshift(memoStream) } stream.unshift(src) }) .catch((err) => stream.emit('error', err)) return stream } module.exports.stream.byDigest = getStreamDigest function getStreamDigest (cache, integrity, opts = {}) { const { memoize } = opts const memoized = memo.get.byDigest(cache, integrity, opts) if (memoized && memoize !== false) { const stream = new Minipass() stream.end(memoized) return stream } else { const stream = read.readStream(cache, integrity, opts) if (!memoize) { return stream } const memoStream = new Collect.PassThrough() memoStream.on('collect', data => memo.put.byDigest( cache, integrity, data, opts )) return new Pipeline(stream, memoStream) } } module.exports.info = info function info (cache, key, opts = {}) { const { memoize } = opts const memoized = memo.get(cache, key, opts) if (memoized && memoize !== false) { return Promise.resolve(memoized.entry) } else { return index.find(cache, key) } } module.exports.hasContent = read.hasContent function cp (cache, key, dest, opts) { return copy(false, cache, key, dest, opts) } module.exports.copy = cp function cpDigest (cache, digest, dest, opts) { return copy(true, cache, digest, dest, opts) } module.exports.copy.byDigest = cpDigest function copy (byDigest, cache, key, dest, opts = {}) { if (read.copy) { return (byDigest ? Promise.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(() => { return byDigest ? key : { metadata: entry.metadata, size: entry.size, integrity: entry.integrity } }) }) } return getData(byDigest, cache, key, opts).then((res) => { return writeFile(dest, byDigest ? res : res.data).then(() => { return byDigest ? key : { metadata: res.metadata, size: res.size, integrity: res.integrity } }) }) } node-cacache-15.0.5/index.js000066400000000000000000000023451374506532500155570ustar00rootroot00000000000000'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 { clearMemoized } = require('./lib/memoization.js') const tmp = require('./lib/util/tmp.js') module.exports.ls = ls module.exports.ls.stream = ls.stream module.exports.get = get module.exports.get.byDigest = get.byDigest module.exports.get.sync = get.sync module.exports.get.sync.byDigest = get.sync.byDigest module.exports.get.stream = get.stream module.exports.get.stream.byDigest = get.stream.byDigest module.exports.get.copy = get.copy module.exports.get.copy.byDigest = get.copy.byDigest module.exports.get.info = get.info module.exports.get.hasContent = get.hasContent module.exports.get.hasContent.sync = get.hasContent.sync module.exports.put = put module.exports.put.stream = put.stream module.exports.rm = rm.entry module.exports.rm.all = rm.all module.exports.rm.entry = module.exports.rm module.exports.rm.content = rm.content module.exports.clearMemoized = clearMemoized module.exports.tmp = {} module.exports.tmp.mkdir = tmp.mkdir module.exports.tmp.withTmp = tmp.withTmp module.exports.verify = verify module.exports.verify.lastRun = verify.lastRun node-cacache-15.0.5/lib/000077500000000000000000000000001374506532500146545ustar00rootroot00000000000000node-cacache-15.0.5/lib/content/000077500000000000000000000000001374506532500163265ustar00rootroot00000000000000node-cacache-15.0.5/lib/content/path.js000066400000000000000000000013411374506532500176170ustar00rootroot00000000000000'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( contentDir(cache), sri.algorithm, ...hashToSegments(sri.hexDigest()) ) } module.exports.contentDir = contentDir function contentDir (cache) { return path.join(cache, `content-v${contentVer}`) } node-cacache-15.0.5/lib/content/read.js000066400000000000000000000145451374506532500176100ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const fsm = require('fs-minipass') const ssri = require('ssri') const contentPath = require('./path') const Pipeline = require('minipass-pipeline') const lstat = util.promisify(fs.lstat) const readFile = util.promisify(fs.readFile) module.exports = read const MAX_SINGLE_READ_SIZE = 64 * 1024 * 1024 function read (cache, integrity, opts = {}) { const { size } = opts return withContentSri(cache, integrity, (cpath, sri) => { // get size return lstat(cpath).then(stat => ({ stat, cpath, sri })) }).then(({ stat, cpath, sri }) => { if (typeof size === 'number' && stat.size !== size) { throw sizeError(size, stat.size) } if (stat.size > MAX_SINGLE_READ_SIZE) { return readPipeline(cpath, stat.size, sri, new Pipeline()).concat() } return readFile(cpath, null).then((data) => { if (!ssri.checkData(data, sri)) { throw integrityError(sri, cpath) } return data }) }) } const readPipeline = (cpath, size, sri, stream) => { stream.push( new fsm.ReadStream(cpath, { size, readSize: MAX_SINGLE_READ_SIZE }), ssri.integrityStream({ integrity: sri, size }) ) return stream } module.exports.sync = readSync function readSync (cache, integrity, opts = {}) { const { size } = opts return withContentSriSync(cache, integrity, (cpath, sri) => { const data = fs.readFileSync(cpath) if (typeof size === 'number' && size !== data.length) { throw sizeError(size, data.length) } if (ssri.checkData(data, sri)) { return data } throw integrityError(sri, cpath) }) } module.exports.stream = readStream module.exports.readStream = readStream function readStream (cache, integrity, opts = {}) { const { size } = opts const stream = new Pipeline() withContentSri(cache, integrity, (cpath, sri) => { // just lstat to ensure it exists return lstat(cpath).then((stat) => ({ stat, cpath, sri })) }).then(({ stat, cpath, sri }) => { if (typeof size === 'number' && size !== stat.size) { return stream.emit('error', sizeError(size, stat.size)) } readPipeline(cpath, stat.size, sri, stream) }, er => stream.emit('error', er)) return stream } let copyFile if (fs.copyFile) { module.exports.copy = copy module.exports.copy.sync = copySync copyFile = util.promisify(fs.copyFile) } function copy (cache, integrity, dest) { return withContentSri(cache, integrity, (cpath, sri) => { return copyFile(cpath, dest) }) } function copySync (cache, integrity, dest) { return withContentSriSync(cache, integrity, (cpath, sri) => { return fs.copyFileSync(cpath, dest) }) } module.exports.hasContent = hasContent function hasContent (cache, integrity) { if (!integrity) { return Promise.resolve(false) } return withContentSri(cache, integrity, (cpath, sri) => { return lstat(cpath).then((stat) => ({ size: stat.size, sri, stat })) }).catch((err) => { if (err.code === 'ENOENT') { return false } if (err.code === 'EPERM') { /* istanbul ignore else */ 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') { /* istanbul ignore else */ if (process.platform !== 'win32') { throw err } else { return false } } } }) } function withContentSri (cache, integrity, fn) { const tryFn = () => { 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 { // Can't use race here because a generic error can happen before a ENOENT error, and can happen before a valid result return Promise .all(digests.map((meta) => { return withContentSri(cache, meta, fn) .catch((err) => { if (err.code === 'ENOENT') { return Object.assign( new Error('No matching content found for ' + sri.toString()), { code: 'ENOENT' } ) } return err }) })) .then((results) => { // Return the first non error if it is found const result = results.find((r) => !(r instanceof Error)) if (result) { return result } // Throw the No matching content found error const enoentError = results.find((r) => r.code === 'ENOENT') if (enoentError) { throw enoentError } // Throw generic error throw results.find((r) => r instanceof Error) }) } } return new Promise((resolve, reject) => { try { tryFn() .then(resolve) .catch(reject) } catch (err) { reject(err) } }) } 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 digests) { try { return withContentSriSync(cache, meta, fn) } catch (err) { lastErr = err } } throw lastErr } } function sizeError (expected, found) { const err = new Error(`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) { const err = new Error(`Integrity verification failed for ${sri} (${path})`) err.code = 'EINTEGRITY' err.sri = sri err.path = path return err } node-cacache-15.0.5/lib/content/rm.js000066400000000000000000000007771374506532500173150ustar00rootroot00000000000000'use strict' const util = require('util') const contentPath = require('./path') const { hasContent } = require('./read') const rimraf = util.promisify(require('rimraf')) module.exports = rm function rm (cache, integrity) { return hasContent(cache, integrity).then((content) => { // ~pretty~ sure we can't end up with a content lacking sri, but be safe if (content && content.sri) { return rimraf(contentPath(cache, content.sri)).then(() => true) } else { return false } }) } node-cacache-15.0.5/lib/content/write.js000066400000000000000000000120201374506532500200110ustar00rootroot00000000000000'use strict' const util = require('util') const contentPath = require('./path') const fixOwner = require('../util/fix-owner') const fs = require('fs') const moveFile = require('../util/move-file') const Minipass = require('minipass') const Pipeline = require('minipass-pipeline') const Flush = require('minipass-flush') const path = require('path') const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') const uniqueFilename = require('unique-filename') const { disposer } = require('./../util/disposer') const fsm = require('fs-minipass') const writeFile = util.promisify(fs.writeFile) module.exports = write function write (cache, data, opts = {}) { const { algorithms, size, integrity } = opts if (algorithms && algorithms.length > 1) { throw new Error('opts.algorithms only supports a single algorithm for now') } if (typeof size === 'number' && data.length !== size) { return Promise.reject(sizeError(size, data.length)) } const sri = ssri.fromData(data, algorithms ? { algorithms } : {}) if (integrity && !ssri.checkData(data, integrity, opts)) { return Promise.reject(checksumError(integrity, sri)) } return disposer(makeTmp(cache, opts), makeTmpDisposer, (tmp) => { return writeFile(tmp.target, data, { flag: 'wx' }) .then(() => moveToDestination(tmp, cache, sri, opts)) }) .then(() => ({ integrity: sri, size: data.length })) } module.exports.stream = writeStream // writes proxied to the 'inputStream' that is passed to the Promise // 'end' is deferred until content is handled. class CacacheWriteStream extends Flush { constructor (cache, opts) { super() this.opts = opts this.cache = cache this.inputStream = new Minipass() this.inputStream.on('error', er => this.emit('error', er)) this.inputStream.on('drain', () => this.emit('drain')) this.handleContentP = null } write (chunk, encoding, cb) { if (!this.handleContentP) { this.handleContentP = handleContent( this.inputStream, this.cache, this.opts ) } return this.inputStream.write(chunk, encoding, cb) } flush (cb) { this.inputStream.end(() => { if (!this.handleContentP) { const e = new Error('Cache input stream was empty') e.code = 'ENODATA' // empty streams are probably emitting end right away. // defer this one tick by rejecting a promise on it. return Promise.reject(e).catch(cb) } this.handleContentP.then( (res) => { res.integrity && this.emit('integrity', res.integrity) res.size !== null && this.emit('size', res.size) cb() }, (er) => cb(er) ) }) } } function writeStream (cache, opts = {}) { return new CacacheWriteStream(cache, opts) } function handleContent (inputStream, cache, opts) { return disposer(makeTmp(cache, opts), makeTmpDisposer, (tmp) => { return pipeToTmp(inputStream, cache, tmp.target, opts) .then((res) => { return moveToDestination( tmp, cache, res.integrity, opts ).then(() => res) }) }) } function pipeToTmp (inputStream, cache, tmpTarget, opts) { let integrity let size const hashStream = ssri.integrityStream({ integrity: opts.integrity, algorithms: opts.algorithms, size: opts.size }) hashStream.on('integrity', i => { integrity = i }) hashStream.on('size', s => { size = s }) const outStream = new fsm.WriteStream(tmpTarget, { flags: 'wx' }) // NB: this can throw if the hashStream has a problem with // it, and the data is fully written. but pipeToTmp is only // called in promisory contexts where that is handled. const pipeline = new Pipeline( inputStream, hashStream, outStream ) return pipeline.promise() .then(() => ({ integrity, size })) .catch(er => rimraf(tmpTarget).then(() => { throw er })) } function makeTmp (cache, opts) { const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), opts.tmpPrefix) return fixOwner.mkdirfix(cache, path.dirname(tmpTarget)).then(() => ({ target: tmpTarget, moved: false })) } function makeTmpDisposer (tmp) { if (tmp.moved) { return Promise.resolve() } return rimraf(tmp.target) } function moveToDestination (tmp, cache, sri, opts) { const destination = contentPath(cache, sri) const destDir = path.dirname(destination) return fixOwner .mkdirfix(cache, destDir) .then(() => { return moveFile(tmp.target, destination) }) .then(() => { tmp.moved = true return fixOwner.chownr(cache, destination) }) } function sizeError (expected, found) { const err = new Error(`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) { const err = new Error(`Integrity check failed: Wanted: ${expected} Found: ${found}`) err.code = 'EINTEGRITY' err.expected = expected err.found = found return err } node-cacache-15.0.5/lib/entry-index.js000066400000000000000000000170321374506532500174630ustar00rootroot00000000000000'use strict' const util = require('util') const crypto = require('crypto') const fs = require('fs') const Minipass = require('minipass') const path = require('path') const ssri = require('ssri') const contentPath = require('./content/path') const fixOwner = require('./util/fix-owner') const hashToSegments = require('./util/hash-to-segments') const indexV = require('../package.json')['cache-version'].index const appendFile = util.promisify(fs.appendFile) const readFile = util.promisify(fs.readFile) const readdir = util.promisify(fs.readdir) module.exports.NotFoundError = class NotFoundError extends Error { constructor (cache, key) { super(`No cache entry for ${key} found in ${cache}`) this.code = 'ENOENT' this.cache = cache this.key = key } } module.exports.insert = insert function insert (cache, key, integrity, opts = {}) { const { metadata, size } = opts const bucket = bucketPath(cache, key) const entry = { key, integrity: integrity && ssri.stringify(integrity), time: Date.now(), size, metadata } return fixOwner .mkdirfix(cache, path.dirname(bucket)) .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 appendFile(bucket, `\n${hashEntry(stringified)}\t${stringified}`) }) .then(() => fixOwner.chownr(cache, bucket)) .catch((err) => { if (err.code === 'ENOENT') { return undefined } throw err // 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 = {}) { const { metadata, size } = opts const bucket = bucketPath(cache, key) const entry = { key, integrity: integrity && ssri.stringify(integrity), time: Date.now(), size, metadata } fixOwner.mkdirfix.sync(cache, path.dirname(bucket)) const stringified = JSON.stringify(entry) fs.appendFileSync(bucket, `\n${hashEntry(stringified)}\t${stringified}`) try { fixOwner.chownr.sync(cache, bucket) } 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 = new Minipass({ objectMode: true }) readdirOrEmpty(indexDir).then(buckets => Promise.all( buckets.map(bucket => { const bucketPath = path.join(indexDir, bucket) return readdirOrEmpty(bucketPath).then(subbuckets => Promise.all( subbuckets.map(subbucket => { const subbucketPath = path.join(bucketPath, subbucket) // "/cachename//./*" return readdirOrEmpty(subbucketPath).then(entries => Promise.all( entries.map(entry => { const entryPath = path.join(subbucketPath, entry) return bucketEntries(entryPath).then(entries => // using a Map here prevents duplicate keys from // showing up twice, I guess? entries.reduce((acc, entry) => { acc.set(entry.key, entry) return acc }, new Map()) ).then(reduced => { // reduced is a map of key => entry for (const entry of reduced.values()) { const formatted = formatEntry(cache, entry) if (formatted) { stream.write(formatted) } } }).catch(err => { if (err.code === 'ENOENT') { return undefined } throw err }) }) )) }) )) }) )) .then( () => stream.end(), err => stream.emit('error', err) ) return stream } module.exports.ls = ls function ls (cache) { return lsStream(cache).collect().then(entries => entries.reduce((acc, xs) => { acc[xs.key] = xs return acc }, {}) ) } function bucketEntries (bucket, filter) { return readFile(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) { const 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 readdir(dir).catch((err) => { if (err.code === 'ENOENT' || err.code === 'ENOTDIR') { return [] } throw err }) } node-cacache-15.0.5/lib/memoization.js000066400000000000000000000027161374506532500175530ustar00rootroot00000000000000'use strict' const LRU = require('lru-cache') const MAX_SIZE = 50 * 1024 * 1024 // 50MB const MAX_AGE = 3 * 60 * 1000 const MEMOIZED = new LRU({ max: MAX_SIZE, maxAge: MAX_AGE, length: (entry, key) => key.startsWith('key:') ? entry.data.length : 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 } } node-cacache-15.0.5/lib/util/000077500000000000000000000000001374506532500156315ustar00rootroot00000000000000node-cacache-15.0.5/lib/util/disposer.js000066400000000000000000000014531374506532500200220ustar00rootroot00000000000000'use strict' module.exports.disposer = disposer function disposer (creatorFn, disposerFn, fn) { const runDisposer = (resource, result, shouldThrow = false) => { return disposerFn(resource) .then( // disposer resolved, do something with original fn's promise () => { if (shouldThrow) { throw result } return result }, // Disposer fn failed, crash process (err) => { throw err // Or process.exit? }) } return creatorFn .then((resource) => { // fn(resource) can throw, so wrap in a promise here return Promise.resolve().then(() => fn(resource)) .then((result) => runDisposer(resource, result)) .catch((err) => runDisposer(resource, err, true)) }) } node-cacache-15.0.5/lib/util/fix-owner.js000066400000000000000000000066541374506532500201200ustar00rootroot00000000000000'use strict' const util = require('util') const chownr = util.promisify(require('chownr')) const mkdirp = require('mkdirp') const inflight = require('promise-inflight') const inferOwner = require('infer-owner') // Memoize getuid()/getgid() calls. // patch process.setuid/setgid to invalidate cached value on change const self = { uid: null, gid: null } const getSelf = () => { if (typeof self.uid !== 'number') { self.uid = process.getuid() const setuid = process.setuid process.setuid = (uid) => { self.uid = null process.setuid = setuid return process.setuid(uid) } } if (typeof self.gid !== 'number') { self.gid = process.getgid() const setgid = process.setgid process.setgid = (gid) => { self.gid = null process.setgid = setgid return process.setgid(gid) } } } module.exports.chownr = fixOwner function fixOwner (cache, filepath) { if (!process.getuid) { // This platform doesn't need ownership fixing return Promise.resolve() } getSelf() if (self.uid !== 0) { // almost certainly can't chown anyway return Promise.resolve() } return Promise.resolve(inferOwner(cache)).then((owner) => { const { uid, gid } = owner // No need to override if it's already what we used. if (self.uid === uid && self.gid === gid) { return } return inflight('fixOwner: fixing ownership on ' + filepath, () => chownr( filepath, typeof uid === 'number' ? uid : self.uid, typeof gid === 'number' ? gid : self.gid ).catch((err) => { if (err.code === 'ENOENT') { return null } throw err }) ) }) } module.exports.chownr.sync = fixOwnerSync function fixOwnerSync (cache, filepath) { if (!process.getuid) { // This platform doesn't need ownership fixing return } const { uid, gid } = inferOwner.sync(cache) getSelf() if (self.uid !== 0) { // almost certainly can't chown anyway return } if (self.uid === uid && self.gid === gid) { // No need to override if it's already what we used. return } try { chownr.sync( filepath, typeof uid === 'number' ? uid : self.uid, typeof gid === 'number' ? gid : self.gid ) } catch (err) { // only catch ENOENT, any other error is a problem. if (err.code === 'ENOENT') { return null } throw err } } module.exports.mkdirfix = mkdirfix function mkdirfix (cache, p, cb) { // we have to infer the owner _before_ making the directory, even though // we aren't going to use the results, since the cache itself might not // exist yet. If we mkdirp it, then our current uid/gid will be assumed // to be correct if it creates the cache folder in the process. return Promise.resolve(inferOwner(cache)).then(() => { return mkdirp(p) .then((made) => { if (made) { return fixOwner(cache, made).then(() => made) } }) .catch((err) => { if (err.code === 'EEXIST') { return fixOwner(cache, p).then(() => null) } throw err }) }) } module.exports.mkdirfix.sync = mkdirfixSync function mkdirfixSync (cache, p) { try { inferOwner.sync(cache) const made = mkdirp.sync(p) if (made) { fixOwnerSync(cache, made) return made } } catch (err) { if (err.code === 'EEXIST') { fixOwnerSync(cache, p) return null } else { throw err } } } node-cacache-15.0.5/lib/util/hash-to-segments.js000066400000000000000000000002171374506532500213550ustar00rootroot00000000000000'use strict' module.exports = hashToSegments function hashToSegments (hash) { return [hash.slice(0, 2), hash.slice(2, 4), hash.slice(4)] } node-cacache-15.0.5/lib/util/move-file.js000066400000000000000000000045461374506532500200630ustar00rootroot00000000000000'use strict' const fs = require('fs') const util = require('util') const chmod = util.promisify(fs.chmod) const unlink = util.promisify(fs.unlink) const stat = util.promisify(fs.stat) const move = require('@npmcli/move-file') const pinflight = require('promise-inflight') module.exports = moveFile function moveFile (src, dest) { const isWindows = global.__CACACHE_TEST_FAKE_WINDOWS__ || process.platform === 'win32' // 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 new Promise((resolve, reject) => { fs.link(src, dest, (err) => { if (err) { if (isWindows && err.code === 'EPERM') { // XXX This is a really weird way to handle this situation, as it // results in the src file being deleted even though the dest // might not exist. Since we pretty much always write files to // deterministic locations based on content hash, this is likely // ok (or at worst, just ends in a future cache miss). But it would // be worth investigating at some time in the future if this is // really what we want to do here. return resolve() } else if (err.code === 'EEXIST' || err.code === 'EBUSY') { // file already exists, so whatever return resolve() } else { return reject(err) } } else { return resolve() } }) }) .then(() => { // content should never change for any reason, so make it read-only return Promise.all([ unlink(src), !isWindows && chmod(dest, '0444') ]) }) .catch(() => { return pinflight('cacache-move-file:' + dest, () => { return 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 // only delete if it successfully copies return move(src, dest) }) }) }) } node-cacache-15.0.5/lib/util/tmp.js000066400000000000000000000014401374506532500167660ustar00rootroot00000000000000'use strict' const util = require('util') const fixOwner = require('./fix-owner') const path = require('path') const rimraf = util.promisify(require('rimraf')) const uniqueFilename = require('unique-filename') const { disposer } = require('./disposer') module.exports.mkdir = mktmpdir function mktmpdir (cache, opts = {}) { const { tmpPrefix } = opts const tmpTarget = uniqueFilename(path.join(cache, 'tmp'), tmpPrefix) return fixOwner.mkdirfix(cache, tmpTarget).then(() => { return tmpTarget }) } module.exports.withTmp = withTmp function withTmp (cache, opts, cb) { if (!cb) { cb = opts opts = {} } return disposer(mktmpdir(cache, opts), rimraf, cb) } module.exports.fix = fixtmpdir function fixtmpdir (cache) { return fixOwner(cache, path.join(cache, 'tmp')) } node-cacache-15.0.5/lib/verify.js000066400000000000000000000174471374506532500165330ustar00rootroot00000000000000'use strict' const util = require('util') const pMap = require('p-map') const contentPath = require('./content/path') const fixOwner = require('./util/fix-owner') const fs = require('fs') const fsm = require('fs-minipass') const glob = util.promisify(require('glob')) const index = require('./entry-index') const path = require('path') const rimraf = util.promisify(require('rimraf')) const ssri = require('ssri') const hasOwnProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key) const stat = util.promisify(fs.stat) const truncate = util.promisify(fs.truncate) const writeFile = util.promisify(fs.writeFile) const readFile = util.promisify(fs.readFile) const verifyOpts = (opts) => ({ concurrency: 20, log: { silly () {} }, ...opts }) module.exports = verify function verify (cache, opts) { opts = verifyOpts(opts) opts.log.silly('verify', 'verifying cache at', cache) const steps = [ markStartTime, fixPerms, garbageCollect, rebuildIndex, cleanTmp, writeVerifile, markEndTime ] return steps .reduce((promise, step, i) => { const label = step.name const start = new Date() return promise.then((stats) => { return 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 Promise.resolve(stats) }) }) }, Promise.resolve({})) .then((stats) => { stats.runTime.total = stats.endTime - stats.startTime opts.log.silly( 'verify', 'verification finished for', cache, 'in', `${stats.runTime.total}ms` ) return stats }) } function markStartTime (cache, opts) { return Promise.resolve({ startTime: new Date() }) } function markEndTime (cache, opts) { return Promise.resolve({ endTime: new Date() }) } function fixPerms (cache, opts) { opts.log.silly('verify', 'fixing cache permissions') return fixOwner .mkdirfix(cache, cache) .then(() => { // TODO - fix file permissions too return fixOwner.chownr(cache, cache) }) .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 new Promise((resolve, reject) => { indexStream.on('end', resolve).on('error', reject) }).then(() => { const contentDir = contentPath.contentDir(cache) return glob(path.join(contentDir, '**'), { follow: false, nodir: true, nosort: true }).then((files) => { return Promise.resolve({ verifiedContent: 0, reclaimedCount: 0, reclaimedSize: 0, badContentCount: 0, keptSize: 0 }).then((stats) => pMap( 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 stat(f).then((s) => { return rimraf(f).then(() => { stats.reclaimedSize += s.size return stats }) }) } }, { concurrency: opts.concurrency } ).then(() => stats) ) }) }) } function verifyContent (filepath, sri) { return stat(filepath) .then((s) => { const contentInfo = { size: s.size, valid: true } return ssri .checkStream(new fsm.ReadStream(filepath), sri) .catch((err) => { if (err.code !== 'EINTEGRITY') { throw err } return rimraf(filepath).then(() => { contentInfo.valid = false }) }) .then(() => contentInfo) }) .catch((err) => { if (err.code === 'ENOENT') { return { size: 0, valid: false } } throw err }) } 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 (const k in entries) { /* istanbul ignore else */ if (hasOwnProperty(entries, 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 pMap( Object.keys(buckets), (key) => { return rebuildBucket(cache, buckets[key], stats, opts) }, { concurrency: opts.concurrency } ).then(() => stats) }) } function rebuildBucket (cache, bucket, stats, opts) { return truncate(bucket._path).then(() => { // This needs to be serialized because cacache explicitly // lets very racy bucket conflicts clobber each other. return bucket.reduce((promise, entry) => { return promise.then(() => { const content = contentPath(cache, entry.integrity) return stat(content) .then(() => { return index .insert(cache, entry.key, entry.integrity, { metadata: entry.metadata, size: entry.size }) .then(() => { stats.totalEntries++ }) }) .catch((err) => { if (err.code === 'ENOENT') { stats.rejectedEntries++ stats.missingContent++ return } throw err }) }) }, Promise.resolve()) }) } 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) try { return writeFile(verifile, '' + +new Date()) } finally { fixOwner.chownr.sync(cache, verifile) } } module.exports.lastRun = lastRun function lastRun (cache) { return readFile(path.join(cache, '_lastverified'), 'utf8').then( (data) => new Date(+data) ) } node-cacache-15.0.5/ls.js000066400000000000000000000001731374506532500150630ustar00rootroot00000000000000'use strict' const index = require('./lib/entry-index') module.exports = index.ls module.exports.stream = index.lsStream node-cacache-15.0.5/package-lock.json000066400000000000000000010146321374506532500173310ustar00rootroot00000000000000{ "name": "cacache", "version": "15.0.5", "lockfileVersion": 1, "requires": true, "dependencies": { "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { "@babel/highlight": "^7.8.3" } }, "@babel/generator": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.5.tgz", "integrity": "sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ==", "dev": true, "requires": { "@babel/types": "^7.9.5", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" }, "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.9.5", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.9.5.tgz", "integrity": "sha512-JVcQZeXM59Cd1qanDUxv9fgJpt3NeKUaqBqUEvfmQ+BCOKq2xUgaWZW2hr0dkbyJgezYuplEoh5knmrnS68efw==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", "@babel/types": "^7.9.5" } }, "@babel/helper-get-function-arity": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helper-validator-identifier": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz", "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==", "dev": true }, "@babel/highlight": { "version": "7.9.0", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz", "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.9.0", "chalk": "^2.0.0", "js-tokens": "^4.0.0" }, "dependencies": { "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" } }, "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" } }, "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 }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "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" } } } }, "@babel/parser": { "version": "7.9.4", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", "dev": true }, "@babel/runtime": { "version": "7.9.2", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6" } }, "@babel/traverse": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.5.tgz", "integrity": "sha512-c4gH3jsvSuGUezlP6rzSJ6jf8fYjLj3hsMZRx/nX0h+fmHN0w+ekubRrHPqnMec0meycA2nwCsJ7dC8IPem2FQ==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.9.5", "@babel/helper-function-name": "^7.9.5", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.9.0", "@babel/types": "^7.9.5", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" }, "dependencies": { "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 } } }, "@babel/types": { "version": "7.9.5", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.5.tgz", "integrity": "sha512-XjnvNqenk818r5zMaba+sLQjnbda31UfUURv3ei0qPQw4u+j2jMyJ5b11y8ZHYTRSI3NnInQkkkRT4fLqqPdHg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.9.5", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, "@npmcli/move-file": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.0.1.tgz", "integrity": "sha512-Uv6h1sT+0DrblvIrolFtbvM1FgWm+/sy4B3pvLp67Zys+thcukzS5ekn7HsZFGpWP4Q3fYJCljbWQE/XivMRLw==", "requires": { "mkdirp": "^1.0.4" } }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, "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": "7.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true }, "acorn-jsx": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", "dev": true }, "add-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", "integrity": "sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=", "dev": true }, "aggregate-error": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", "requires": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "ajv": { "version": "6.12.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { "type-fest": "^0.11.0" }, "dependencies": { "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", "dev": true } } }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "dev": true }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "anymatch": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "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" } }, "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.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "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.1.1", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0", "is-string": "^1.0.5" } }, "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 }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, "async-hook-domain": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/async-hook-domain/-/async-hook-domain-1.1.3.tgz", "integrity": "sha512-ZovMxSbADV3+biB7oR1GL5lGyptI24alp0LWHlmz1OFc5oL47pz3EiIF6nXOkDW7yLqih4NtsiYduzdDW0i+Wg==", "dev": true, "requires": { "source-map-support": "^0.5.11" } }, "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.9.1", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.1.tgz", "integrity": "sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==", "dev": true }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "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" } }, "binary-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", "dev": true }, "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 }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "braces": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "dev": true, "requires": { "fill-range": "^7.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 }, "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" }, "dependencies": { "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" } } } }, "caller": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/caller/-/caller-1.0.1.tgz", "integrity": "sha1-uFGGD3Dhlds9J3OVqhp+I+ow7PU=", "dev": true }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "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" } }, "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, "chalk": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", "dev": true }, "chokidar": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", "dev": true, "requires": { "anymatch": "~3.1.1", "braces": "~3.0.2", "fsevents": "~2.1.2", "glob-parent": "~5.1.0", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.4.0" } }, "chownr": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==" }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { "restore-cursor": "^3.1.0" } }, "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "cliui": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", "dev": true, "requires": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" }, "dependencies": { "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.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": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "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.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "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": "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" }, "dependencies": { "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } } } }, "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.15", "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.15.tgz", "integrity": "sha512-CoWM+Z9bYyF00QzNpTnxkCLiuLAeRocJz3C/foFjvhsdltdtkJgMChp7GytQNjm4pT7JFBVJTpqLHTpxNtOzaA==", "dev": true, "requires": { "conventional-changelog-angular": "^5.0.6", "conventional-changelog-atom": "^2.0.3", "conventional-changelog-codemirror": "^2.0.3", "conventional-changelog-conventionalcommits": "^4.2.3", "conventional-changelog-core": "^4.1.1", "conventional-changelog-ember": "^2.0.4", "conventional-changelog-eslint": "^3.0.4", "conventional-changelog-express": "^2.0.1", "conventional-changelog-jquery": "^3.0.6", "conventional-changelog-jshint": "^2.0.3", "conventional-changelog-preset-loader": "^2.3.0" } }, "conventional-changelog-angular": { "version": "5.0.6", "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.6.tgz", "integrity": "sha512-QDEmLa+7qdhVIv8sFZfVxU1VSyVvnXPsxq8Vam49mKUcO1Z8VTLEJk9uI21uiJUsnmm0I4Hrsdc9TgkOQo9WSA==", "dev": true, "requires": { "compare-func": "^1.3.1", "q": "^1.5.1" } }, "conventional-changelog-atom": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.3.tgz", "integrity": "sha512-szZe2ut97qNO6vCCMkm1I/tWu6ol4Rr8a9Lx0y/VlpDnpY0PNp+oGpFgU55lplhx+I3Lro9Iv4/gRj0knfgjzg==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-codemirror": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.3.tgz", "integrity": "sha512-t2afackdgFV2yBdHhWPqrKbpaQeVnz2hSJKdWqjasPo5EpIB6TBL0er3cOP1mnGQmuzk9JSvimNSuqjWGDtU5Q==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-config-spec": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", "dev": true }, "conventional-changelog-conventionalcommits": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.2.3.tgz", "integrity": "sha512-atGa+R4vvEhb8N/8v3IoW59gCBJeeFiX6uIbPu876ENAmkMwsenyn0R21kdDHJFLQdy6zW4J6b4xN8KI3b9oww==", "dev": true, "requires": { "compare-func": "^1.3.1", "lodash": "^4.17.15", "q": "^1.5.1" } }, "conventional-changelog-core": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.1.4.tgz", "integrity": "sha512-LO58ZbEpp1Ul+y/vOI8rJRsWkovsYkCFbOCVgi6UnVfU8WC0F8K8VQQwaBZWWUpb6JvEiN4GBR5baRP2txZ+Vg==", "dev": true, "requires": { "add-stream": "^1.0.0", "conventional-changelog-writer": "^4.0.11", "conventional-commits-parser": "^3.0.8", "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": "^3.0.1", "lodash": "^4.17.15", "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": { "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" } } } }, "conventional-changelog-ember": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.4.tgz", "integrity": "sha512-q1u73sO9uCnxN4TSw8xu6MRU8Y1h9kpwtcdJuNRwu/LSKI1IE/iuNSH5eQ6aLlQ3HTyrIpTfUuVybW4W0F17rA==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-eslint": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.4.tgz", "integrity": "sha512-CPwTUENzhLGl3auunrJxiIEWncAGaby7gOFCdj2gslIuOFJ0KPJVOUhRz4Da/I53sdo/7UncUJkiLg94jEsjxg==", "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.6", "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.6.tgz", "integrity": "sha512-gHAABCXUNA/HjnZEm+vxAfFPJkgtrZvCDIlCKfdPVXtCIo/Q0lN5VKpx8aR5p8KdVRQFF3OuTlvv5kv6iPuRqA==", "dev": true, "requires": { "q": "^1.5.1" } }, "conventional-changelog-jshint": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.3.tgz", "integrity": "sha512-Pc2PnMPcez634ckzr4EOWviwRSpZcURaK7bjyD9oK6N5fsC/a+3G7LW5m/JpcHPhA9ZxsfIbm7uqZ3ZDGsQ/sw==", "dev": true, "requires": { "compare-func": "^1.3.1", "q": "^1.5.1" } }, "conventional-changelog-preset-loader": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.0.tgz", "integrity": "sha512-/rHb32J2EJnEXeK4NpDgMaAVTFZS3o1ExmjKMtYVgIC4MQn0vkNSbYpdGRotkfGGRWiqk3Ri3FBkiZGbAfIfOQ==", "dev": true }, "conventional-changelog-writer": { "version": "4.0.11", "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.11.tgz", "integrity": "sha512-g81GQOR392I+57Cw3IyP1f+f42ME6aEkbR+L7v1FBBWolB0xkjKTeCWVguzRrp6UiT1O6gBpJbEy2eq7AnV1rw==", "dev": true, "requires": { "compare-func": "^1.3.1", "conventional-commits-filter": "^2.0.2", "dateformat": "^3.0.0", "handlebars": "^4.4.0", "json-stringify-safe": "^5.0.1", "lodash": "^4.17.15", "meow": "^5.0.0", "semver": "^6.0.0", "split": "^1.0.0", "through2": "^3.0.0" } }, "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.8", "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.8.tgz", "integrity": "sha512-YcBSGkZbYp7d+Cr3NWUeXbPDFUN6g3SaSIzOybi8bjHL5IJ5225OSCxJJ4LgziyEJ7AaJtE9L2/EU6H7Nt/DDQ==", "dev": true, "requires": { "JSONStream": "^1.0.4", "is-text-path": "^1.0.1", "lodash": "^4.17.15", "meow": "^5.0.0", "split2": "^2.0.0", "through2": "^3.0.0", "trim-off-newlines": "^1.0.0" } }, "conventional-recommended-bump": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.0.5.tgz", "integrity": "sha512-srkferrB4kACPEbKYltZwX1CQZAEqbQkabKN444mavLRVMetzwJFJf23/+pwvtMsWbd+cc4HaleV1nHke0f8Rw==", "dev": true, "requires": { "concat-stream": "^2.0.0", "conventional-changelog-preset-loader": "^2.3.0", "conventional-commits-filter": "^2.0.2", "conventional-commits-parser": "^3.0.8", "git-raw-commits": "2.0.0", "git-semver-tags": "^3.0.1", "meow": "^5.0.0", "q": "^1.5.1" } }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" } }, "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=", "dev": true }, "coveralls": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.1.0.tgz", "integrity": "sha512-sHxOu2ELzW8/NC1UP5XVLbZDzO4S3VxfFye3XYCznopHy02YjNkHcj5bKaVw2O7hVaBdBjEdQGpie4II1mWhuQ==", "dev": true, "requires": { "js-yaml": "^3.13.1", "lcov-parse": "^1.0.0", "log-driver": "^1.2.7", "minimist": "^1.2.5", "request": "^2.88.2" } }, "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-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.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "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" } }, "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": "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" } }, "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": "4.0.1", "resolved": "https://registry.npmjs.org/deglob/-/deglob-4.0.1.tgz", "integrity": "sha512-/g+RDZ7yf2HvoW+E5Cy+K94YhgcFgr6C8LuHZD1O5HoNPkf3KY6RfXJ0DBGlB/NkLi5gml+G9zqRzk9S0mHZCg==", "dev": true, "requires": { "find-root": "^1.0.0", "glob": "^7.0.5", "ignore": "^5.0.0", "pkg-config": "^1.1.0", "run-parallel": "^1.1.2", "uniq": "^1.0.1" }, "dependencies": { "ignore": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "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.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true }, "diff-frag": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/diff-frag/-/diff-frag-1.0.1.tgz", "integrity": "sha512-6/v2PC/6UTGcWPPetb9acL8foberUg/CtPdALeJUdD1B/weHNvzftoo00gYznqHGRhHEbykUGzqfG9RWOSr5yw==", "dev": true }, "doctrine": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", "dev": true, "requires": { "esutils": "^2.0.2" } }, "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.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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 } } }, "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": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, "requires": { "is-arrayish": "^0.2.1" } }, "es-abstract": { "version": "1.17.5", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", "has": "^1.0.3", "has-symbols": "^1.0.1", "is-callable": "^1.1.5", "is-regex": "^1.0.5", "object-inspect": "^1.7.0", "object-keys": "^1.1.1", "object.assign": "^4.1.0", "string.prototype.trimleft": "^2.1.1", "string.prototype.trimright": "^2.1.1" } }, "es-to-primitive": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "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": "6.8.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", "chalk": "^2.1.0", "cross-spawn": "^6.0.5", "debug": "^4.0.1", "doctrine": "^3.0.0", "eslint-scope": "^5.0.0", "eslint-utils": "^1.4.3", "eslint-visitor-keys": "^1.1.0", "espree": "^6.1.2", "esquery": "^1.0.1", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^5.0.0", "globals": "^12.1.0", "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.3.0", "lodash": "^4.17.14", "minimatch": "^3.0.4", "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", "optionator": "^0.8.3", "progress": "^2.0.0", "regexpp": "^2.0.1", "semver": "^6.1.2", "strip-ansi": "^5.2.0", "strip-json-comments": "^3.0.1", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "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" } }, "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" } }, "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 }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "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" } } } }, "eslint-config-standard": { "version": "14.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-14.1.0.tgz", "integrity": "sha512-EF6XkrrGVbvv8hL/kYa/m6vnvmUT+K82pJJc4JJVMM6+Qgqh0pnwprSxdduDLB9p/7bIxD+YV5O0wfb8lmcPbA==", "dev": true }, "eslint-config-standard-jsx": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-8.1.0.tgz", "integrity": "sha512-ULVC8qH8qCqbU792ZOO6DaiaZyHNS/5CZt3hKqHkEhVlhPEPN3nfBqqxJCyp59XrjIBZPu1chMYe9T2DXZ7TMw==", "dev": true }, "eslint-import-resolver-node": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", "dev": true, "requires": { "debug": "^2.6.9", "resolve": "^1.13.1" }, "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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "eslint-module-utils": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", "dev": true, "requires": { "debug": "^2.6.9", "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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "eslint-plugin-es": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz", "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==", "dev": true, "requires": { "eslint-utils": "^1.4.2", "regexpp": "^3.0.0" }, "dependencies": { "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", "dev": true } } }, "eslint-plugin-import": { "version": "2.18.2", "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz", "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==", "dev": true, "requires": { "array-includes": "^3.0.3", "contains-path": "^0.1.0", "debug": "^2.6.9", "doctrine": "1.5.0", "eslint-import-resolver-node": "^0.3.2", "eslint-module-utils": "^2.4.0", "has": "^1.0.3", "minimatch": "^3.0.4", "object.values": "^1.1.0", "read-pkg-up": "^2.0.0", "resolve": "^1.11.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" } }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true } } }, "eslint-plugin-node": { "version": "10.0.0", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz", "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==", "dev": true, "requires": { "eslint-plugin-es": "^2.0.0", "eslint-utils": "^1.4.2", "ignore": "^5.1.1", "minimatch": "^3.0.4", "resolve": "^1.10.1", "semver": "^6.1.0" }, "dependencies": { "ignore": { "version": "5.1.4", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true } } }, "eslint-plugin-promise": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz", "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==", "dev": true }, "eslint-plugin-react": { "version": "7.14.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.14.3.tgz", "integrity": "sha512-EzdyyBWC4Uz2hPYBiEJrKCUi2Fn+BJ9B/pJQcjw5X+x/H2Nm59S4MJIvL4O5NEE0+WbnQwEBxWY03oUk+Bc3FA==", "dev": true, "requires": { "array-includes": "^3.0.3", "doctrine": "^2.1.0", "has": "^1.0.3", "jsx-ast-utils": "^2.1.0", "object.entries": "^1.1.0", "object.fromentries": "^2.0.0", "object.values": "^1.1.0", "prop-types": "^15.7.2", "resolve": "^1.10.1" }, "dependencies": { "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" } } } }, "eslint-plugin-standard": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.1.tgz", "integrity": "sha512-v/KBnfyaOMPmZc/dmc6ozOdWqekGp7bBGq4jLAecEfPGmfKiWS4sA8sC0LqiV9w5qmXAtXVn4M3p1jSyhY85SQ==", "dev": true }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-utils": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", "dev": true, "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", "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": "6.2.1", "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", "dev": true, "requires": { "acorn": "^7.1.1", "acorn-jsx": "^5.2.0", "eslint-visitor-keys": "^1.1.0" } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esquery": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "dev": true, "requires": { "estraverse": "^5.1.0" }, "dependencies": { "estraverse": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==", "dev": true } } }, "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.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "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 }, "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": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", "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": "3.1.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "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 }, "figures": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", "dev": true, "requires": { "flat-cache": "^2.0.1" } }, "fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dev": true, "requires": { "to-regex-range": "^5.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.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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 }, "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": "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" } }, "findit": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/findit/-/findit-2.0.0.tgz", "integrity": "sha1-ZQnwEmr0wXhVHPqZOU4DLhOk1W4=", "dev": true }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", "dev": true, "requires": { "flatted": "^2.0.0", "rimraf": "2.6.3", "write": "1.0.3" }, "dependencies": { "rimraf": { "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", "dev": true, "requires": { "glob": "^7.1.3" } } } }, "flatted": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", "dev": true }, "flow-parser": { "version": "0.123.0", "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.123.0.tgz", "integrity": "sha512-scMjcsICxtHm141rFTfWgKnNbz9MUubgc9kNSh+0xvTYIA/L+9AzlPRK0FMcfNiqQTWjn0IMGqiwySLzMZVvtw==", "dev": true }, "flow-remove-types": { "version": "2.123.0", "resolved": "https://registry.npmjs.org/flow-remove-types/-/flow-remove-types-2.123.0.tgz", "integrity": "sha512-sxSSPbl8sap5P6goX+zYMRsMKtSHdbgAwHXvfGVyaPTkXM6Jz4TeODwQiVTvDiu/OLMxyXk6IKYVMkWbpWiTIQ==", "dev": true, "requires": { "flow-parser": "^0.123.0", "pirates": "^3.0.2", "vlq": "^0.2.1" } }, "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" } }, "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-minipass": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", "requires": { "minipass": "^3.0.0" } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, "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": "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 }, "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" } }, "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" } }, "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" } }, "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" } }, "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" } }, "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-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" } }, "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" } }, "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" } }, "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-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" } }, "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" } }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~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": "7.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", "dev": true }, "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" }, "dependencies": { "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" } }, "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" } }, "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" } }, "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } } } }, "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": "3.0.1", "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-3.0.1.tgz", "integrity": "sha512-Hzd1MOHXouITfCasrpVJbRDg9uvW7LfABk3GQmXYZByerBDrfrEMP9HXpNT7RxAbieiocP6u+xq20DkvjwxnCA==", "dev": true, "requires": { "meow": "^5.0.0", "semver": "^6.0.0" } }, "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.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "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" } }, "glob-parent": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", "dev": true, "requires": { "is-glob": "^4.0.1" } }, "globals": { "version": "12.4.0", "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "dev": true, "requires": { "type-fest": "^0.8.1" } }, "graceful-fs": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", "dev": true }, "handlebars": { "version": "4.7.6", "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "dev": true, "requires": { "minimist": "^1.2.5", "neo-async": "^2.6.0", "source-map": "^0.6.1", "uglify-js": "^3.1.4", "wordwrap": "^1.0.0" } }, "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" } }, "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-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "has-symbols": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", "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.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", "dev": true }, "html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "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" } }, "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 }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "indent-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" }, "infer-owner": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==" }, "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.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, "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": "7.1.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", "cli-cursor": "^3.1.0", "cli-width": "^2.0.0", "external-editor": "^3.0.3", "figures": "^3.0.0", "lodash": "^4.17.15", "mute-stream": "0.0.8", "run-async": "^2.4.0", "rxjs": "^6.5.3", "string-width": "^4.1.0", "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "dependencies": { "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } } } }, "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-binary-path": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "dev": true, "requires": { "binary-extensions": "^2.0.0" } }, "is-callable": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", "dev": true }, "is-date-object": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", "dev": true }, "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", "dev": true }, "is-finite": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz", "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==", "dev": true }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "is-glob": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", "dev": true, "requires": { "is-extglob": "^2.1.1" } }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, "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-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", "dev": true, "requires": { "has": "^1.0.3" } }, "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-string": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", "dev": true }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", "dev": true, "requires": { "has-symbols": "^1.0.1" } }, "is-text-path": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", "dev": true, "requires": { "text-extensions": "^1.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 }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true }, "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" } }, "istanbul-lib-processinfo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-1.0.0.tgz", "integrity": "sha512-FY0cPmWa4WoQNlvB8VOcafiRoB5nB+l2Pz2xGuXHRSy1KM8QFOYfz/rN+bGMCAeejrY3mrpF5oJHcN0s/garCg==", "dev": true, "requires": { "archy": "^1.0.0", "cross-spawn": "^6.0.5", "istanbul-lib-coverage": "^2.0.3", "rimraf": "^2.6.3", "uuid": "^3.3.2" }, "dependencies": { "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } } } }, "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": { "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "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": { "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } } } }, "istanbul-reports": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-2.2.7.tgz", "integrity": "sha512-uu1F/L1o5Y6LzPVSVZXNOoD/KXpJue9aeLRd0sM9uMXfZvzomB0WxVamWb5ue8kA2vVWEmW7EG+A5n3f1kqHKg==", "dev": true, "requires": { "html-escaper": "^2.0.0" } }, "jackspeak": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-1.4.0.tgz", "integrity": "sha512-VDcSunT+wcccoG46FtzuBAyQKlzhHjli4q31e1fIHGOsRspqNUFjVzGb+7eIFDlTvqLygxapDHPHS0ouT2o/tw==", "dev": true, "requires": { "cliui": "^4.1.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 }, "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" } }, "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" } }, "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" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "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" } }, "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" } }, "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" } } } } } }, "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 }, "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.2.3", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.2.3.tgz", "integrity": "sha512-EdIHFMm+1BPynpKOpdPqiOsvnIrInRGJD7bzPZdPkjitQEqpdpUuFpq4T0npZFKTiB3RhWFdGN+oqOJIdhDhQA==", "dev": true, "requires": { "array-includes": "^3.0.3", "object.assign": "^4.1.0" } }, "lcov-parse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcov-parse/-/lcov-parse-1.0.0.tgz", "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "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" } }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "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.5.0", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0", "lodash.templatesettings": "^4.0.0" } }, "lodash.templatesettings": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", "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": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { "yallist": "^4.0.0" } }, "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.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "make-error": { "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, "map-obj": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", "dev": true }, "meow": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", "dev": true, "requires": { "camelcase-keys": "^4.0.0", "decamelize-keys": "^1.0.0", "loud-rejection": "^1.0.0", "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", "yargs-parser": "^10.0.0" }, "dependencies": { "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" } } } }, "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.44.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", "dev": true }, "mime-types": { "version": "2.1.27", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "dev": true, "requires": { "mime-db": "1.44.0" } }, "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 }, "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": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "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": "3.1.1", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", "requires": { "yallist": "^4.0.0" } }, "minipass-collect": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", "requires": { "minipass": "^3.0.0" } }, "minipass-flush": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "requires": { "minipass": "^3.0.0" } }, "minipass-pipeline": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz", "integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==", "requires": { "minipass": "^3.0.0" } }, "minizlib": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.0.tgz", "integrity": "sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==", "requires": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "mkdirp": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" }, "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 }, "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 }, "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "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.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, "node-modules-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=", "dev": true }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", "semver": "2 || 3 || 4 || 5", "validate-npm-package-license": "^3.0.1" }, "dependencies": { "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "dev": true } } }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, "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-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" } }, "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" } }, "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 }, "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 }, "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" } }, "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 }, "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.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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 }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } }, "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" } }, "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.3.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", "find-up": "^3.0.0", "get-caller-file": "^2.0.1", "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.2" } }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "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-inspect": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", "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 }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", "has-symbols": "^1.0.0", "object-keys": "^1.0.11" } }, "object.entries": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } }, "object.fromentries": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.2.tgz", "integrity": "sha512-r3ZiBH7MQppDJVLx6fhD618GKNG40CZYH9wgwdhKxBDDbQgjeWGGd4AtkZad84d291YxvWe7bJGuE65Anh0dxQ==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } }, "object.values": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.0-next.1", "function-bind": "^1.1.1", "has": "^1.0.3" } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "requires": { "wrappy": "1" } }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { "mimic-fn": "^2.1.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 }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" } }, "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-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-limit": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "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-map": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", "requires": { "aggregate-error": "^3.0.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" } }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", "dev": true, "requires": { "callsites": "^3.0.0" } }, "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": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, "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-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": "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" } }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, "picomatch": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "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" } }, "pirates": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/pirates/-/pirates-3.0.2.tgz", "integrity": "sha512-c5CgUJq6H2k6MJz72Ak1F5sN9n9wlSlJyEnwvpm9/y3WB4E3pHBDT2c6PEiS1vyJvq2bUxUAIu0EGf8Cx4Ic7Q==", "dev": true, "requires": { "node-modules-regexp": "^1.0.0" } }, "pkg-conf": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz", "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==", "dev": true, "requires": { "find-up": "^3.0.0", "load-json-file": "^5.2.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": "5.3.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz", "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==", "dev": true, "requires": { "graceful-fs": "^4.1.15", "parse-json": "^4.0.0", "pify": "^4.0.1", "strip-bom": "^3.0.0", "type-fest": "^0.3.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.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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" } }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", "dev": true }, "type-fest": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz", "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==", "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" } }, "platform": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", "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": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, "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.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", "dev": true }, "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": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react/-/react-16.13.1.tgz", "integrity": "sha512-YMZQQq32xHLX0bz5Mnibv1/LHb3Sqzngu7xstSM+vrkE5Kzr9xE0yMByK5kMoTK30YVJE61WfbxIFFvfeDKT1w==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2" } }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "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" } }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "readdirp": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", "dev": true, "requires": { "picomatch": "^2.2.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" }, "dependencies": { "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 } } }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true }, "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.2", "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "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.3", "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.5.0", "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": "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": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "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 }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "requires": { "glob": "^7.1.3" } }, "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", "dev": true }, "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 }, "rxjs": { "version": "6.5.5", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", "dev": true, "requires": { "tslib": "^1.9.0" } }, "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": "6.3.0", "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", "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.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, "slice-ansi": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", "is-fullwidth-code-point": "^2.0.0" }, "dependencies": { "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" } }, "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 }, "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.19", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", "dev": true, "requires": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "spawn-wrap": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-1.4.3.tgz", "integrity": "sha512-IgB8md0QW/+tWqcavuFgKYR/qIRvJkRLPJDFaoXtLLUaVcCDK0+HeFTkmQHj3eprcYhc+gOl0aEA1w7qZlYezw==", "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" }, "dependencies": { "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } } } }, "spdx-correct": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" } }, "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" } }, "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", "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" }, "dependencies": { "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", "dev": true, "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } } } }, "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": "8.0.0", "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.0.tgz", "integrity": "sha512-aq/pz989nxVYwn16Tsbj1TqFpD5LLrQxHf5zaHuieFV+R0Bbr4y8qUsOA45hXT/N4/9UNXTarBjnjVmjSOVaAA==", "requires": { "minipass": "^3.1.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": "14.3.3", "resolved": "https://registry.npmjs.org/standard/-/standard-14.3.3.tgz", "integrity": "sha512-HBEAD5eVXrr2o/KZ3kU8Wwaxw90wzoq4dOQe6vlRnPoQ6stn4LCLRLBBDp0CjH/aOTL9bDZJbRUOZcBaBnNJ0A==", "dev": true, "requires": { "eslint": "~6.8.0", "eslint-config-standard": "14.1.0", "eslint-config-standard-jsx": "8.1.0", "eslint-plugin-import": "~2.18.0", "eslint-plugin-node": "~10.0.0", "eslint-plugin-promise": "~4.2.1", "eslint-plugin-react": "~7.14.2", "eslint-plugin-standard": "~4.0.0", "standard-engine": "^12.0.0" } }, "standard-engine": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-12.0.0.tgz", "integrity": "sha512-gJIIRb0LpL7AHyGbN9+hJ4UJns37lxmNTnMGRLC8CFrzQ+oB/K60IQjKNgPBCB2VP60Ypm6f8DFXvhVWdBOO+g==", "dev": true, "requires": { "deglob": "^4.0.0", "get-stdin": "^7.0.0", "minimist": "^1.1.0", "pkg-conf": "^3.1.0" } }, "standard-version": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-7.1.0.tgz", "integrity": "sha512-bHY2E/1tYGeVl+0XSXFivb+54h2fA4pWJocXAd6FGbtSFUvGsnfmMbIXYDxrYErpq7oEqoKreV8xTAp78WoATA==", "dev": true, "requires": { "chalk": "2.4.2", "conventional-changelog": "3.1.15", "conventional-changelog-config-spec": "2.1.0", "conventional-changelog-conventionalcommits": "4.2.3", "conventional-recommended-bump": "6.0.5", "detect-indent": "6.0.0", "detect-newline": "3.1.0", "dotgitignore": "2.1.0", "figures": "3.1.0", "find-up": "4.1.0", "fs-access": "1.0.1", "git-semver-tags": "3.0.1", "semver": "6.3.0", "stringify-package": "1.0.1", "yargs": "15.0.2" }, "dependencies": { "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" } }, "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" } }, "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 }, "figures": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.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 }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.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": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "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" } } } }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" }, "dependencies": { "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } } } }, "string.prototype.trimend": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "string.prototype.trimleft": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5", "string.prototype.trimstart": "^1.0.0" } }, "string.prototype.trimright": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5", "string.prototype.trimend": "^1.0.0" } }, "string.prototype.trimstart": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", "dev": true, "requires": { "define-properties": "^1.1.3", "es-abstract": "^1.17.5" } }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { "safe-buffer": "~5.1.0" } }, "stringify-package": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", "dev": true }, "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" }, "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 } } }, "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-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": "3.1.0", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==", "dev": true }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { "has-flag": "^4.0.0" } }, "table": { "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", "dev": true, "requires": { "ajv": "^6.10.2", "lodash": "^4.17.14", "slice-ansi": "^2.1.0", "string-width": "^3.0.0" }, "dependencies": { "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 }, "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": "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" } } } }, "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", "resolved": "https://registry.npmjs.org/@iarna/cli/-/cli-2.0.0.tgz", "integrity": "sha512-kfewtgihDKSQVEjn19fXAc7UoomcZ2lm7wNbN22BFRURn5muid79OXUquqdtAdnaulrckZLEObXiYT76ZT1naA==", "dev": true, "requires": { "signal-exit": "^3.0.2" } }, "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, "glob": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", "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", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "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=", "dev": true }, "minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha1-Kk5AkLlrLbBqnX3wEFWmKnfJt3Q=", "dev": true, "requires": { "brace-expansion": "^1.0.0" } }, "minimist": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" }, "dependencies": { "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true } } }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { "wrappy": "1" } }, "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=", "dev": true }, "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { "glob": "^7.0.5" } }, "signal-exit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true } } }, "tap": { "version": "14.10.7", "resolved": "https://registry.npmjs.org/tap/-/tap-14.10.7.tgz", "integrity": "sha512-DVx00lfiMxFhofwFDP77pitRCruVQJn8Dcj/6auIU3dErJQWsKT94oG6Yj0MQRuYANhSec8ruIPyUjH/RI9Hrw==", "dev": true, "requires": { "@types/react": "^16.9.16", "async-hook-domain": "^1.1.3", "bind-obj-methods": "^2.0.0", "browser-process-hrtime": "^1.0.0", "chokidar": "^3.3.0", "color-support": "^1.1.0", "coveralls": "^3.0.8", "diff": "^4.0.1", "esm": "^3.2.25", "findit": "^2.0.0", "flow-remove-types": "^2.112.0", "foreground-child": "^1.3.3", "fs-exists-cached": "^1.0.0", "function-loop": "^1.0.2", "glob": "^7.1.6", "import-jsx": "^3.1.0", "ink": "^2.6.0", "isexe": "^2.0.0", "istanbul-lib-processinfo": "^1.0.0", "jackspeak": "^1.4.0", "minipass": "^3.1.1", "mkdirp": "^0.5.1", "nyc": "^14.1.1", "opener": "^1.5.1", "own-or": "^1.0.0", "own-or-env": "^1.0.1", "react": "^16.12.0", "rimraf": "^2.7.1", "signal-exit": "^3.0.0", "source-map-support": "^0.5.16", "stack-utils": "^1.0.2", "tap-mocha-reporter": "^5.0.0", "tap-parser": "^10.0.1", "tap-yaml": "^1.0.0", "tcompare": "^3.0.0", "treport": "^1.0.2", "trivial-deferred": "^1.0.1", "ts-node": "^8.5.2", "typescript": "^3.7.2", "which": "^2.0.2", "write-file-atomic": "^3.0.1", "yaml": "^1.7.2", "yapool": "^1.0.0" }, "dependencies": { "@babel/code-frame": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { "@babel/highlight": "^7.8.3" } }, "@babel/core": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.8.7", "@babel/helpers": "^7.8.4", "@babel/parser": "^7.8.7", "@babel/template": "^7.8.6", "@babel/traverse": "^7.8.6", "@babel/types": "^7.8.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", "source-map": "^0.5.0" }, "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/generator": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", "dev": true, "requires": { "@babel/types": "^7.8.7", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" }, "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-builder-react-jsx": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.8.3.tgz", "integrity": "sha512-JT8mfnpTkKNCboTqZsQTdGo3l3Ik3l7QIt9hh0O9DYiwVel37VoJpILKM4YFbP2euF32nkQSb+F9cUk9b7DDXQ==", "dev": true, "requires": { "@babel/types": "^7.8.3", "esutils": "^2.0.0" } }, "@babel/helper-function-name": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { "@babel/helper-get-function-arity": "^7.8.3", "@babel/template": "^7.8.3", "@babel/types": "^7.8.3" } }, "@babel/helper-get-function-arity": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helper-plugin-utils": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz", "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==", "dev": true }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { "@babel/types": "^7.8.3" } }, "@babel/helpers": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", "dev": true, "requires": { "@babel/template": "^7.8.3", "@babel/traverse": "^7.8.4", "@babel/types": "^7.8.3" } }, "@babel/highlight": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "dev": true, "requires": { "chalk": "^2.0.0", "esutils": "^2.0.2", "js-tokens": "^4.0.0" } }, "@babel/parser": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", "dev": true }, "@babel/plugin-proposal-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.8.3.tgz", "integrity": "sha512-8qvuPwU/xxUCt78HocNlv0mXXo0wdh9VT1R04WU8HGOfaOob26pF+9P5/lYjN/q7DHOX1bvX60hnhOvuQUJdbA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-object-rest-spread": "^7.8.0" } }, "@babel/plugin-syntax-jsx": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.8.3.tgz", "integrity": "sha512-WxdW9xyLgBdefoo0Ynn3MRSkhe5tFVxxKNVdnZSh318WrG2e2jH+E9wd/++JsqcLJZPfz87njQJ8j2Upjm0M0A==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } }, "@babel/plugin-syntax-object-rest-spread": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.0" } }, "@babel/plugin-transform-destructuring": { "version": "7.8.8", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz", "integrity": "sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ==", "dev": true, "requires": { "@babel/helper-plugin-utils": "^7.8.3" } }, "@babel/plugin-transform-react-jsx": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.8.3.tgz", "integrity": "sha512-r0h+mUiyL595ikykci+fbwm9YzmuOrUBi0b+FDIKmi3fPQyFokWVEMJnRWHJPPQEjyFJyna9WZC6Viv6UHSv1g==", "dev": true, "requires": { "@babel/helper-builder-react-jsx": "^7.8.3", "@babel/helper-plugin-utils": "^7.8.3", "@babel/plugin-syntax-jsx": "^7.8.3" } }, "@babel/runtime": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" } }, "@babel/template": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6" } }, "@babel/traverse": { "version": "7.8.6", "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", "@babel/generator": "^7.8.6", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", "@babel/parser": "^7.8.6", "@babel/types": "^7.8.6", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" } }, "@babel/types": { "version": "7.8.7", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", "dev": true, "requires": { "esutils": "^2.0.2", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, "@types/prop-types": { "version": "15.7.3", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz", "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==", "dev": true }, "@types/react": { "version": "16.9.23", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.23.tgz", "integrity": "sha512-SsGVT4E7L2wLN3tPYLiF20hmZTPGuzaayVunfgXzUn1x4uHVsKH6QDJQ/TdpHqwsTLd4CwrmQ2vOgxN7gE24gw==", "dev": true, "requires": { "@types/prop-types": "*", "csstype": "^2.2.0" } }, "@types/yoga-layout": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.1.tgz", "integrity": "sha512-OpfgQXWLZn5Dl7mOd8dBNcV8NywXbYYoHjUpa64vJ/RQABaxMzJ5bVicKLGIvIiMnQPtPgKNgXb5jkv9fkOQtw==", "dev": true }, "ansi-escapes": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { "type-fest": "^0.11.0" } }, "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", "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" } }, "ansicolors": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz", "integrity": "sha1-ZlWX3oap/+Oqm/vmyuXG6kJrSXk=", "dev": true }, "arrify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, "astral-regex": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", "dev": true }, "auto-bind": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-4.0.0.tgz", "integrity": "sha512-Hdw8qdNiqdJ8LqT0iK0sVzkFbzg6fhnQqqfWhBDxcHZvU75+B+ayzTy8x+k5Ix0Y92XOhOUlx74ps+bA6BeYMQ==", "dev": true }, "caller-callsite": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", "dev": true, "requires": { "callsites": "^2.0.0" } }, "caller-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", "dev": true, "requires": { "caller-callsite": "^2.0.0" } }, "callsites": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", "dev": true }, "cardinal": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz", "integrity": "sha1-fMEFXYItISlU0HsIXeolHMe8VQU=", "dev": true, "requires": { "ansicolors": "~0.3.2", "redeyed": "~2.1.0" } }, "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" } }, "ci-info": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", "dev": true }, "cli-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { "restore-cursor": "^3.1.0" } }, "cli-truncate": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", "dev": true, "requires": { "slice-ansi": "^3.0.0", "string-width": "^4.2.0" } }, "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 }, "convert-source-map": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", "dev": true, "requires": { "safe-buffer": "~5.1.1" }, "dependencies": { "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 } } }, "csstype": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.9.tgz", "integrity": "sha512-xz39Sb4+OaTsULgUERcCk+TJj8ylkL4aSVDQiX/ksxbELSqwkgt4d4RD7fovIdgJGSuNYqwZEiVjYY5l0ask+Q==", "dev": true }, "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" } }, "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "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 }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", "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 }, "gensync": { "version": "1.0.0-beta.1", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", "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 }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, "import-jsx": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-jsx/-/import-jsx-3.1.0.tgz", "integrity": "sha512-lTuMdQ/mRXC+xQSGPDvAg1VkODlX78j5hZv2tneJ+zuo7GH/XhUF/YVKoeF382a4jO4GYw9jgganbMhEcxwb0g==", "dev": true, "requires": { "@babel/core": "^7.5.5", "@babel/plugin-proposal-object-rest-spread": "^7.5.5", "@babel/plugin-transform-destructuring": "^7.5.0", "@babel/plugin-transform-react-jsx": "^7.3.0", "caller-path": "^2.0.0", "resolve-from": "^3.0.0" } }, "ink": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/ink/-/ink-2.7.1.tgz", "integrity": "sha512-s7lJuQDJEdjqtaIWhp3KYHl6WV3J04U9zoQ6wVc+Xoa06XM27SXUY57qC5DO46xkF0CfgXMKkKNcgvSu/SAEpA==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", "arrify": "^2.0.1", "auto-bind": "^4.0.0", "chalk": "^3.0.0", "cli-cursor": "^3.1.0", "cli-truncate": "^2.1.0", "is-ci": "^2.0.0", "lodash.throttle": "^4.1.1", "log-update": "^3.0.0", "prop-types": "^15.6.2", "react-reconciler": "^0.24.0", "scheduler": "^0.18.0", "signal-exit": "^3.0.2", "slice-ansi": "^3.0.0", "string-length": "^3.1.0", "widest-line": "^3.1.0", "wrap-ansi": "^6.2.0", "yoga-layout-prebuilt": "^1.9.3" }, "dependencies": { "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, "is-ci": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", "dev": true, "requires": { "ci-info": "^2.0.0" } }, "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true }, "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 }, "jsesc": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, "json5": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true }, "lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", "integrity": "sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=", "dev": true }, "log-update": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/log-update/-/log-update-3.4.0.tgz", "integrity": "sha512-ILKe88NeMt4gmDvk/eb615U/IVn7K9KWGkoYbdatQ69Z65nj1ZzjM6fHXfcs0Uge+e+EGnMW7DY4T9yko8vWFg==", "dev": true, "requires": { "ansi-escapes": "^3.2.0", "cli-cursor": "^2.1.0", "wrap-ansi": "^5.0.0" }, "dependencies": { "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": "4.1.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", "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" } }, "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 }, "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 }, "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 }, "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" } }, "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" } }, "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" } }, "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" } } } }, "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" } }, "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 }, "minimist": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, "minipass": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", "integrity": "sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w==", "dev": true, "requires": { "yallist": "^4.0.0" }, "dependencies": { "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true } } }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } }, "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 }, "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 }, "onetime": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", "dev": true, "requires": { "mimic-fn": "^2.1.0" } }, "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 }, "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" } }, "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 }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "dev": true }, "react-reconciler": { "version": "0.24.0", "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.24.0.tgz", "integrity": "sha512-gAGnwWkf+NOTig9oOowqid9O0HjTDC+XVGBCAmJYYJ2A2cN/O4gDdIuuUQjv8A4v6GDwVfJkagpBBLW5OW9HSw==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", "prop-types": "^15.6.2", "scheduler": "^0.18.0" } }, "redeyed": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz", "integrity": "sha1-iYS1gV2ZyyIEacme7v/jiRPmzAs=", "dev": true, "requires": { "esprima": "~4.0.0" } }, "regenerator-runtime": { "version": "0.13.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true }, "resolve": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { "path-parse": "^1.0.6" } }, "resolve-from": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", "dev": true }, "restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "dev": true, "requires": { "glob": "^7.1.3" } }, "scheduler": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.18.0.tgz", "integrity": "sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==", "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" } }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", "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": "3.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "astral-regex": "^2.0.0", "is-fullwidth-code-point": "^3.0.0" }, "dependencies": { "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true } } }, "string-length": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-length/-/string-length-3.1.0.tgz", "integrity": "sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA==", "dev": true, "requires": { "astral-regex": "^1.0.0", "strip-ansi": "^5.2.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 }, "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", "dev": true }, "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" } } } }, "string-width": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.0" } }, "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } }, "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" } }, "tap-parser": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", "dev": true, "requires": { "events-to-array": "^1.0.1", "minipass": "^3.0.0", "tap-yaml": "^1.0.0" } }, "tap-yaml": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", "dev": true, "requires": { "yaml": "^1.5.0" } }, "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 }, "treport": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/treport/-/treport-1.0.2.tgz", "integrity": "sha512-QCAbFtzIjQN+9k+alo8e6oo8j0eSLsttdahAgNLoC3U36rls8XRy/R11QOhHmPz7CDcB2ar29eLe4OFJoPnsPA==", "dev": true, "requires": { "cardinal": "^2.1.1", "chalk": "^3.0.0", "import-jsx": "^3.1.0", "ink": "^2.6.0", "ms": "^2.1.2", "string-length": "^3.1.0", "tap-parser": "^10.0.1", "unicode-length": "^2.0.2" }, "dependencies": { "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "chalk": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "dev": true, "requires": { "has-flag": "^4.0.0" } } } }, "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", "dev": true }, "unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==", "dev": true, "requires": { "punycode": "^2.0.0", "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "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" } } } }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", "dev": true, "requires": { "isexe": "^2.0.0" } }, "widest-line": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-3.1.0.tgz", "integrity": "sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==", "dev": true, "requires": { "string-width": "^4.0.0" } }, "wrap-ansi": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "dependencies": { "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" } }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "requires": { "color-name": "~1.1.4" } }, "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true } } }, "yaml": { "version": "1.8.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.2.tgz", "integrity": "sha512-omakb0d7FjMo3R1D2EbTKVIk6dAVLRxFXdLZMEUToeAvuqgG/YuHMuQOZ5fgk+vQ8cx+cnGKwyg+8g8PNT0xQg==", "dev": true, "requires": { "@babel/runtime": "^7.8.7" } }, "yoga-layout-prebuilt": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/yoga-layout-prebuilt/-/yoga-layout-prebuilt-1.9.5.tgz", "integrity": "sha512-+G5Ojl4/sG78mk5masCL3SRaZtkKXRBhMGf5c+4C1j32jN9KpS4lxVFdYyBi15EHN4gMeK5sIRf83T33TOaDkA==", "dev": true, "requires": { "@types/yoga-layout": "1.9.1" } } } }, "tap-mocha-reporter": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/tap-mocha-reporter/-/tap-mocha-reporter-5.0.1.tgz", "integrity": "sha512-1knFWOwd4khx/7uSEnUeaP9IPW3w+sqTgJMhrwah6t46nZ8P25atOKAjSvVDsT67lOPu0nfdOqUwoyKn+3E5pA==", "dev": true, "requires": { "color-support": "^1.1.0", "debug": "^4.1.1", "diff": "^4.0.1", "escape-string-regexp": "^2.0.0", "glob": "^7.0.5", "tap-parser": "^10.0.0", "tap-yaml": "^1.0.0", "unicode-length": "^2.0.2" }, "dependencies": { "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true } } }, "tap-parser": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-10.0.1.tgz", "integrity": "sha512-qdT15H0DoJIi7zOqVXDn9X0gSM68JjNy1w3VemwTJlDnETjbi6SutnqmBfjDJAwkFS79NJ97gZKqie00ZCGmzg==", "dev": true, "requires": { "events-to-array": "^1.0.1", "minipass": "^3.0.0", "tap-yaml": "^1.0.0" } }, "tap-yaml": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/tap-yaml/-/tap-yaml-1.0.0.tgz", "integrity": "sha512-Rxbx4EnrWkYk0/ztcm5u3/VznbyFJpyXO12dDBHKWiDVxy7O2Qw6MRrwO5H6Ww0U5YhRY/4C/VzWmFPhBQc4qQ==", "dev": true, "requires": { "yaml": "^1.5.0" } }, "tar": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/tar/-/tar-6.0.2.tgz", "integrity": "sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^3.0.0", "minizlib": "^2.1.0", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "tcompare": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/tcompare/-/tcompare-3.0.4.tgz", "integrity": "sha512-Q3TitMVK59NyKgQyFh+857wTAUE329IzLDehuPgU4nF5e8g+EUQ+yUbjUy1/6ugiNnXztphT+NnqlCXolv9P3A==", "dev": true, "requires": { "diff-frag": "^1.0.1" } }, "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.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "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-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" } } } }, "text-extensions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", "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": "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" } }, "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 }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dev": true, "requires": { "is-number": "^7.0.0" } }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" } }, "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 }, "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.9.1", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.9.1.tgz", "integrity": "sha512-yrq6ODsxEFTLz0R3BX2myf0WBCSQh9A+py8PBo1dCzWIOcvisbyH6akNKqDHMgXePF2kir5mm5JXJTH3OUJYOQ==", "dev": true, "requires": { "arg": "^4.1.0", "diff": "^4.0.1", "make-error": "^1.1.1", "source-map-support": "^0.5.17", "yn": "3.1.1" } }, "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", "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" } }, "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", "dev": true }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, "typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", "dev": true, "requires": { "is-typedarray": "^1.0.0" } }, "typescript": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==", "dev": true }, "uglify-js": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.1.tgz", "integrity": "sha512-JUPoL1jHsc9fOjVFHdQIhqEEJsQvfKDjlubcCilu8U26uZ73qOg8VsN8O1jbuei44ZPlwL7kmbAdM4tzaUvqnA==", "dev": true, "optional": true, "requires": { "commander": "~2.20.3" } }, "unicode-length": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/unicode-length/-/unicode-length-2.0.2.tgz", "integrity": "sha512-Ph/j1VbS3/r77nhoY2WU0GWGjVYOHL3xpKp0y/Eq2e5r0mT/6b649vm7KFO6RdAdrZkYLdxphYVgvODxPB+Ebg==", "dev": true, "requires": { "punycode": "^2.0.0", "strip-ansi": "^3.0.1" }, "dependencies": { "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "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" } } } }, "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.2", "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", "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=", "dev": true }, "uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", "dev": true }, "v8-compile-cache": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", "dev": true }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.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" } }, "vlq": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", "dev": true }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { "isexe": "^2.0.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 }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", "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": "6.2.0", "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, "requires": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" }, "dependencies": { "strip-ansi": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "dev": true, "requires": { "ansi-regex": "^5.0.0" } } } }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", "dev": true, "requires": { "mkdirp": "^0.5.1" }, "dependencies": { "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { "minimist": "^1.2.5" } } } }, "write-file-atomic": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { "imurmurhash": "^0.1.4", "is-typedarray": "^1.0.0", "signal-exit": "^3.0.2", "typedarray-to-buffer": "^3.1.5" } }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, "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==", "dev": true }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "yaml": { "version": "1.9.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.9.2.tgz", "integrity": "sha512-HPT7cGGI0DuRcsO51qC1j9O16Dh1mZ2bnXwsi0jrSpsLz0WxOLSLXfkABVl6bZO629py3CU+OMJtpNHDLB97kg==", "dev": true, "requires": { "@babel/runtime": "^7.9.2" } }, "yapool": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/yapool/-/yapool-1.0.0.tgz", "integrity": "sha1-9pPymjFbUNmp2iZGp6ZkXJaYW2o=", "dev": true }, "yargs": { "version": "15.0.2", "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.0.2.tgz", "integrity": "sha512-GH/X/hYt+x5hOat4LMnCqMd8r5Cv78heOMIJn1hr7QPPBqfeC6p89Y78+WB9yGDvfpCvgasfmWLzNzEioOUD9Q==", "dev": true, "requires": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^16.1.0" }, "dependencies": { "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": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { "p-locate": "^4.1.0" } }, "p-limit": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" } }, "p-locate": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, "requires": { "p-limit": "^2.2.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": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "dev": true }, "yargs-parser": { "version": "16.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" } } } }, "yargs-parser": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", "dev": true, "requires": { "camelcase": "^4.1.0" } }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true } } } node-cacache-15.0.5/package.json000066400000000000000000000042301374506532500163730ustar00rootroot00000000000000{ "name": "cacache", "version": "15.0.5", "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" ], "scripts": { "benchmarks": "node test/benchmarks", "lint": "standard", "postrelease": "npm publish", "posttest": "npm run lint", "prepublishOnly": "git push --follow-tags", "prerelease": "npm t", "release": "standard-version -s", "test": "tap", "coverage": "tap", "test-docker": "docker run -it --rm --name pacotest -v \"$PWD\":/tmp -w /tmp node:latest npm test" }, "repository": "https://github.com/npm/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": { "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "glob": "^7.1.4", "infer-owner": "^1.0.4", "lru-cache": "^6.0.0", "minipass": "^3.1.1", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.2", "mkdirp": "^1.0.3", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^8.0.0", "tar": "^6.0.2", "unique-filename": "^1.1.1" }, "devDependencies": { "benchmark": "^2.1.4", "chalk": "^4.0.0", "require-inject": "^1.4.4", "standard": "^14.3.1", "standard-version": "^7.1.0", "tacks": "^1.3.0", "tap": "^14.10.6" }, "tap": { "100": true, "test-regex": "test/[^/]*.js" }, "engines": { "node": ">= 10" } } node-cacache-15.0.5/put.js000066400000000000000000000040161374506532500152550ustar00rootroot00000000000000'use strict' const index = require('./lib/entry-index') const memo = require('./lib/memoization') const write = require('./lib/content/write') const Flush = require('minipass-flush') const { PassThrough } = require('minipass-collect') const Pipeline = require('minipass-pipeline') const putOpts = (opts) => ({ algorithms: ['sha512'], ...opts }) module.exports = putData function putData (cache, key, data, opts = {}) { const { memoize } = opts opts = putOpts(opts) return write(cache, data, opts).then((res) => { return index .insert(cache, key, res.integrity, { ...opts, size: res.size }) .then((entry) => { if (memoize) { memo.put(cache, entry, data, opts) } return res.integrity }) }) } module.exports.stream = putStream function putStream (cache, key, opts = {}) { const { memoize } = opts opts = putOpts(opts) let integrity let size let memoData const pipeline = new Pipeline() // first item in the pipeline is the memoizer, because we need // that to end first and get the collected data. if (memoize) { const memoizer = new PassThrough().on('collect', data => { memoData = data }) pipeline.push(memoizer) } // contentStream is a write-only, not a passthrough // no data comes out of it. const contentStream = write.stream(cache, opts) .on('integrity', (int) => { integrity = int }) .on('size', (s) => { size = s }) pipeline.push(contentStream) // last but not least, we write the index and emit hash and size, // and memoize if we're doing that pipeline.push(new Flush({ flush () { return index .insert(cache, key, integrity, { ...opts, size }) .then((entry) => { if (memoize && memoData) { memo.put(cache, entry, memoData, opts) } if (integrity) { pipeline.emit('integrity', integrity) } if (size) { pipeline.emit('size', size) } }) } })) return pipeline } node-cacache-15.0.5/rm.js000066400000000000000000000012301374506532500150560ustar00rootroot00000000000000'use strict' const util = require('util') const index = require('./lib/entry-index') const memo = require('./lib/memoization') const path = require('path') const rimraf = util.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-*)')) } node-cacache-15.0.5/test/000077500000000000000000000000001374506532500150655ustar00rootroot00000000000000node-cacache-15.0.5/test/benchmarks/000077500000000000000000000000001374506532500172025ustar00rootroot00000000000000node-cacache-15.0.5/test/benchmarks/content.read.js000066400000000000000000000067441374506532500221370ustar00rootroot00000000000000'use strict' const util = require('util') const CacheContent = require('../util/cache-content') const fs = require('fs') const path = require('path') const Tacks = require('tacks') const ssri = require('ssri') const read = require('../../lib/content/read') const writeFile = util.promisify(fs.writeFile) const 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) => writeFile(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) => writeFile(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.promise().then( () => deferred.resolve(), er => deferred.reject(er) ) stream.resume() } }) 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.promise().then( () => deferred.resolve(), er => deferred.reject(er) ) stream.resume() } }) } node-cacache-15.0.5/test/benchmarks/get.js000066400000000000000000000057431374506532500203300ustar00rootroot00000000000000'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') const 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.promise().then( () => deferred.resolve(), er => deferred.reject(er) ) stream.resume() } }) 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.promise().then( () => deferred.resolve(), er => deferred.reject(er) ) stream.resume() } }) 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)) } }) } node-cacache-15.0.5/test/benchmarks/index.find.js000066400000000000000000000022071374506532500215670ustar00rootroot00000000000000'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 } }) } node-cacache-15.0.5/test/benchmarks/index.insert.js000066400000000000000000000013331374506532500221520ustar00rootroot00000000000000'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)) } }) } node-cacache-15.0.5/test/benchmarks/index.js000066400000000000000000000046561374506532500206620ustar00rootroot00000000000000'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 () { const 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 }) }) node-cacache-15.0.5/test/benchmarks/put.js000066400000000000000000000027571374506532500203630ustar00rootroot00000000000000'use strict' const 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' const 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) stream.promise().then( () => deferred.resolve(), (err) => deferred.reject(err) ) stream.end(CONTENT + this.count) } }) suite.add(`cacache.put.stream() ${BIGCONTENT.length} bytes`, { defer: true, minSamples: 30, maxTime: 30, fn (deferred) { const stream = put.stream(CACHE, KEY + this.count) stream.promise().then( () => deferred.resolve(), (err) => deferred.reject(err) ) stream.end(BIGCONTENT + this.count) } }) } node-cacache-15.0.5/test/content.read.js000066400000000000000000000321121374506532500200060ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const path = require('path') const requireInject = require('require-inject') const ssri = require('ssri') const Tacks = require('tacks') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const readFile = util.promisify(fs.readFile) const CACHE = path.join(testDir, 'cache') const CacheContent = require('./util/cache-content') const read = require('../lib/content/read') // defines reusable errors const genericError = new Error('ERR') genericError.code = 'ERR' const permissionError = new Error('EPERM') permissionError.code = 'EPERM' // helpers const getRead = (opts) => requireInject('../lib/content/read', opts) const getReadLstatFailure = (err) => getRead({ fs: Object.assign({}, require('fs'), { lstat (path, cb) { cb(err) }, lstatSync () { throw err } }) }) test('read: returns a Promise 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) return Promise.all([ stream.concat(), read(CACHE, INTEGRITY, { size: CONTENT.length }) ]).then(([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) return Promise.all([ stream.concat(), read(CACHE, INTEGRITY) ]).then(([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 emitted even though stream errored') }) return Promise.all([ stream.promise().catch((err) => { if (err.code === 'ENOENT') { return err } throw err }), read(CACHE, 'sha512-whatnot').catch((err) => { if (err.code === 'ENOENT') { return err } throw err }) ]).then(([streamErr, bulkErr]) => { t.match(streamErr, { code: 'ENOENT' }, 'stream got the right error') t.match(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 emitted even though stream errored') }) return Promise.all([ stream.promise().catch((err) => { if (err.code === 'EINTEGRITY') { return err } throw err }), read(CACHE, INTEGRITY).catch((err) => { if (err.code === 'EINTEGRITY') { return err } throw err }) ]).then(([streamErr, bulkErr]) => { t.match(streamErr, { code: 'EINTEGRITY' }, 'stream got the right error') t.match(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 Promise.all([ stream.promise().catch((err) => { if (err.code === 'EBADSIZE') { return err } throw err }), read(CACHE, INTEGRITY, { size: CONTENT.length }).catch((err) => { if (err.code === 'EBADSIZE') { return err } throw err }) ]).then(([streamErr, bulkErr]) => { t.match(streamErr, { code: 'EBADSIZE' }, 'stream got the right error') t.match(bulkErr, { code: 'EBADSIZE' }, 'bulk got the right error') }) }) test('read: error while parsing provided integrity data', function (t) { const INTEGRITY = 'sha1-deadbeef' const mockedRead = getRead({ ssri: { parse (sri) { throw genericError } } }) t.plan(1) return t.rejects( mockedRead(CACHE, INTEGRITY), genericError, 'should reject promise upon catching internal errors' ) }) test('read: unknown error parsing nested integrity data', function (t) { const INTEGRITY = 'sha1-deadbeef sha1-13371337' // patches method in order to force a last error scenario const mockedRead = getRead({ ssri: { parse (sri) { if (sri !== INTEGRITY) { throw genericError } return ssri.parse(sri) } } }) t.plan(1) return t.rejects( mockedRead(CACHE, INTEGRITY), genericError, 'should throw unknown errors' ) }) test('read: returns only first result if other hashes fails', function (t) { // sets up a cache that has multiple entries under the // same algorithm but then only one has real contents in the fs const CONTENT = { foo: Buffer.from('foo'), bar: Buffer.from('bar') } const INTEGRITY = ssri.fromData(CONTENT.foo).concat( ssri.fromData(CONTENT.bar) ) const fixture = new Tacks( CacheContent({ [INTEGRITY.sha512[1]]: CONTENT.bar }) ) fixture.create(CACHE) t.plan(1) return t.resolveMatch( read(CACHE, INTEGRITY), CONTENT.bar, 'should return only the first valid result' ) }) test('read: opening large files', function (t) { const mockedRead = getRead({ fs: Object.assign({}, require('fs'), { lstat (path, cb) { cb(null, { size: Number.MAX_SAFE_INTEGER }) } }), 'fs-minipass': { ReadStream: class { constructor (path, opts) { t.matches( opts, { readSize: 64 * 1024 * 1024, size: Number.MAX_SAFE_INTEGER }, 'should use fs-minipass interface' ) } } }, 'minipass-pipeline': Array }) t.plan(1) mockedRead(CACHE, 'sha1-deadbeef') }) test('read.sync: unknown error parsing nested integrity data', (t) => { const INTEGRITY = 'sha1-deadbeef sha1-13371337' // patches method in order to force a last error scenario const mockedRead = getRead({ ssri: { parse (sri) { if (sri !== INTEGRITY) { throw genericError } return ssri.parse(sri) } } }) t.throws( () => mockedRead.sync(CACHE, INTEGRITY), genericError, 'should throw last error found when parsing multiple hashes' ) t.done() }) test('read.sync: cache contains mismatching data', (t) => { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT.slice(3) }) ) fixture.create(CACHE) t.throws( () => read.sync(CACHE, INTEGRITY), { code: 'EINTEGRITY' }, 'should throw integrity error' ) t.done() }) test('read.sync: content size value does not match option', (t) => { const CONTENT = Buffer.from('foobarbaz') const INTEGRITY = ssri.fromData(CONTENT) const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT.slice(3) }) ) fixture.create(CACHE) t.throws( () => read.sync(CACHE, INTEGRITY, { size: CONTENT.length }), { code: 'EBADSIZE' }, 'should throw size error' ) t.done() }) test('hasContent: tests content existence', (t) => { const fixture = new Tacks( CacheContent({ 'sha1-deadbeef': '' }) ) fixture.create(CACHE) return Promise.all([ 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: permission error', (t) => { // setup a syntetic permission error const mockedRead = getReadLstatFailure(permissionError) t.plan(1) t.rejects( mockedRead.hasContent(CACHE, 'sha1-deadbeef sha1-13371337'), permissionError, 'should reject on permission errors' ) }) test('hasContent: generic error', (t) => { const mockedRead = getReadLstatFailure(genericError) t.plan(1) t.resolves( mockedRead.hasContent(CACHE, 'sha1-deadbeef sha1-13371337'), 'should not reject on generic errors' ) }) test('hasContent: no integrity provided', (t) => { t.resolveMatch( read.hasContent(CACHE, ''), false, 'should resolve with a value of false' ) t.done() }) 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('hasContent.sync: permission error', (t) => { const mockedRead = getReadLstatFailure(permissionError) t.throws( () => mockedRead.hasContent.sync(CACHE, 'sha1-deadbeef sha1-13371337'), permissionError, 'should throw on permission errors' ) t.done() }) test('hasContent.sync: generic error', (t) => { const mockedRead = getReadLstatFailure(genericError) t.notOk( mockedRead.hasContent.sync(CACHE, 'sha1-deadbeef sha1-13371337'), 'should not throw on generic errors' ) t.done() }) test('hasContent.sync: no integrity provided', (t) => { t.equal( read.hasContent.sync(CACHE, ''), false, 'should returns false if no integrity provided' ) 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 readFile(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() } ) test('copyFile not supported by file system', (t) => { const mockedRead = getRead({ fs: Object.assign({}, require('fs'), { copyFile: undefined }) }) t.notOk(mockedRead.copy, 'should not define copy') t.done() }) node-cacache-15.0.5/test/content.rm.js000066400000000000000000000024731374506532500175200ustar00rootroot00000000000000'use strict' const contentPath = require('../lib/content/path') const fs = require('fs') const path = require('path') const util = require('util') const Tacks = require('tacks') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const stat = util.promisify(fs.stat) 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(() => stat(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(() => stat(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') }) }) node-cacache-15.0.5/test/content.write.chownr.js000066400000000000000000000036021374506532500215260ustar00rootroot00000000000000'use strict' const NEWUID = process.getuid() + 1 const NEWGID = process.getgid() + 1 process.getuid = () => 0 const testDir = require('./util/test-dir')(__filename) const path = require('path') const CACHE = path.join(testDir, 'cache') const fs = require('fs') const stat = fs.lstat fs.lstat = (path, cb) => { stat(path, (er, st) => { if (st && path === testDir) { st.uid = NEWUID st.gid = NEWGID } cb(er, st) }) } const statSync = fs.lstatSync fs.lstatSync = (path) => { const st = statSync(path) if (path === testDir) { st.uid = NEWUID st.gid = NEWGID } return st } const requireInject = require('require-inject') const ssri = require('ssri') const { test } = require('tap') const contentPath = require('../lib/content/path') test( 'infers ownership from cache folder owner', { skip: process.getuid ? false : 'test only works on platforms that can set uid/gid' }, (t) => { const CONTENT = 'foobarbaz' const INTEGRITY = ssri.fromData(CONTENT) 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) return write.stream(CACHE, { hashAlgorithm: 'sha1' }) .end(CONTENT) .promise() .then(() => { 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' ) }) } ) node-cacache-15.0.5/test/content.write.js000066400000000000000000000175171374506532500202410ustar00rootroot00000000000000'use strict' const fs = require('fs') const path = require('path') const rimraf = require('rimraf') const ssri = require('ssri') const Tacks = require('tacks') const { test } = require('tap') 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 return write.stream(CACHE) .on('integrity', (i) => { integrity = i }) .end(CONTENT) .promise() .then(() => { const cpath = contentPath(CACHE, integrity) t.deepEqual(integrity, INTEGRITY, 'calculated integrity value matches') t.ok(fs.lstatSync(cpath).isFile(), 'content inserted as a single file') t.equal(fs.readFileSync(cpath, 'utf8'), CONTENT, 'contents are identical to inserted content') }) }) test("checks input digest doesn't match data", (t) => { const CONTENT = 'foobarbaz' const integrity = ssri.fromData(CONTENT) let int1 = null let int2 = null return t.rejects( write.stream(CACHE, { integrity }) .on('integrity', (int) => { int1 = int }) .end('bazbarfoo') .promise(), { code: 'EINTEGRITY' }, 'returns integrity error' ) .then(() => t.equal(int1, null, 'no digest emitted')) .then(() => write.stream(CACHE, { integrity }) .on('integrity', int => { int2 = int }) .end(CONTENT) .promise()) .then(() => t.deepEqual(int2, integrity, 'returns a matching digest')) }) test('errors if stream ends with no data', (t) => { let integrity = null return t.rejects( write.stream(CACHE).end('') .on('integrity', int => { integrity = int }) .promise(), { code: 'ENODATA' }, 'get an error with a useful code' ).then(() => t.equal(integrity, null, 'no digest returned')) }) test('errors if input size does not match expected', (t) => { let int1 = null let int2 = null return t.rejects( write.stream(CACHE, { size: 5 }) .on('integrity', int => { int1 = int }) .end('abc') .promise(), { code: 'EBADSIZE', expected: 5, found: 3 }, 'get an error when data smaller than expected' ) .then(() => t.equal(int1, null, 'no digest returned')) .then(() => t.rejects( write.stream(CACHE, { size: 5 }) .on('integrity', int => { int2 = int }) .end('abcdefghi') .promise(), { code: 'EBADSIZE', expected: 5, found: 9 }, 'get an error when data bigger than expected' )) .then(() => t.equal(int2, null, 'no digest returned')) }) 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) let int1 let int2 // With a digest -- early short-circuiting return write.stream(CACHE, { integrity: INTEGRITY }) .on('integrity', int => { int1 = int }) .end(CONTENT) .promise() .then(() => { t.deepEqual(int1, INTEGRITY, 'short-circuit returns a matching digest') const d = fs.readFileSync(contentPath(CACHE, INTEGRITY), 'utf8') t.equal(d, 'nope', 'process short-circuited. Data not written.') }) .then(() => write.stream(CACHE) .on('integrity', int => { int2 = int }) .end(CONTENT) .promise() ) .then(() => { t.deepEqual(int2, INTEGRITY, 'full write returns a matching digest') const d = fs.readFileSync(contentPath(CACHE, INTEGRITY), 'utf8') t.equal(d, 'nope', 'previously-written data intact - no dupe write') }) }) test('errors if input stream errors', (t) => { let integrity = null const putter = write.stream(CACHE) .on('integrity', (int) => { integrity = int }) setTimeout(() => putter.inputStream.emit('error', new Error('bleh'))) return t.rejects(putter.promise(), { message: 'bleh' }) .then(() => { t.equal(integrity, null, 'no digest returned') t.throws(() => { fs.statSync(contentPath(CACHE, ssri.fromData('foobarbaz'))) }, { code: 'ENOENT' }, 'target file missing. No files created') }) }) 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 } write.stream(CACHE) .on('integrity', int => { integrity = int }) .end(CONTENT) .promise() .then(() => { t.deepEqual(integrity, INTEGRITY, 'returns a matching digest') fs.closeSync(fd) rimraf.sync(contentPath(CACHE, INTEGRITY)) t.end() }) }) }) test('cleans up tmp on successful completion', (t) => { const CONTENT = 'foobarbaz' return write.stream(CACHE) .end(CONTENT) .promise() .then(() => new Promise((resolve, reject) => { 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!') resolve() } else { reject(err) } }) })) }) test('cleans up tmp on error', (t) => { const CONTENT = 'foobarbaz' return t.rejects( write.stream(CACHE, { size: 1 }) .end(CONTENT) .promise(), { code: 'EBADSIZE' }, 'got expected code' ) .then(() => new Promise((resolve, reject) => { 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!') resolve() } else { reject(err) } }) })) }) test('checks the size of stream data if opts.size provided', (t) => { const CONTENT = 'foobarbaz' let int1 = null const int2 = null let int3 = null t.test('chair too small', t => { const w = write.stream(CACHE, { size: CONTENT.length }) w.write(CONTENT.slice(3)) w.on('integrity', int => { int1 = int }) setTimeout(() => w.end()) return t.rejects(w.promise(), { code: 'EBADSIZE' }, 'bad size error code') .then(() => t.equal(int1, null, 'no digest returned by first stream')) }) t.test('chair is too big', t => { const w = write.stream(CACHE, { size: CONTENT.length }) w.write(CONTENT) setTimeout(() => w.end('quux')) return t.rejects(w.promise(), { code: 'EBADSIZE' }, 'bad size error code') .then(() => t.equal(int2, null, 'no digest returned by second stream')) }) return t.test('chair is juuuuust right', t => { const w = write.stream(CACHE, { size: CONTENT.length }) w.write(CONTENT) w.on('integrity', int => { int3 = int }) setTimeout(() => w.end()) return w.promise().then(() => t.ok(int3, 'got a digest')) }) }) test('only one algorithm for now', t => { t.throws(() => write(CACHE, 'foo', { algorithms: [1, 2] }), { message: 'opts.algorithms only supports a single algorithm for now' }) t.end() }) test('writes to cache with default options', t => t.resolveMatch(write(CACHE, 'foo'), { size: 3, integrity: { sha512: [ { source: 'sha512-9/u6bgY2+JDlb7vzKD5STG+jIErimDgtYkdB0NxmODJuKCxBvl5CVNiCB3LFUYosWowMf37aGVlKfrU5RT4e1w==', digest: '9/u6bgY2+JDlb7vzKD5STG+jIErimDgtYkdB0NxmODJuKCxBvl5CVNiCB3LFUYosWowMf37aGVlKfrU5RT4e1w==', algorithm: 'sha512', options: [] } ] } })) node-cacache-15.0.5/test/disposer.js000066400000000000000000000103621374506532500172550ustar00rootroot00000000000000'use strict' const { disposer } = require('./../lib/util/disposer') const { test } = require('tap') test('disposerFn should run in resolve', (t) => { let disposerRan = false const mockCreatorResource = '__creator_resource__' const mockFunctionResult = '__function_result__' const creatorFn = () => { return Promise.resolve(mockCreatorResource) } const disposerFn = () => { disposerRan = true return Promise.resolve('Disposer Resolve') } return disposer( creatorFn(), disposerFn, (data) => { t.equal(disposerRan, false, 'disposerFn should not have been called') t.equal(data, mockCreatorResource, 'Disposer not returning the created resource to running function') return Promise.resolve(mockFunctionResult) }) .then((data) => { t.equal(disposerRan, true, 'disposerFn should have been called') t.equal(data, mockFunctionResult, 'Disposer not returning the returned result of the function') }) }) test('disposerFn should run in reject', (t) => { let disposerRan = false const mockCreatorResource = '__creator_resource__' const mockFunctionResult = '__function_result__' const creatorFn = () => { return Promise.resolve(mockCreatorResource) } const disposerFn = () => { disposerRan = true return Promise.resolve('Disposer Resolve') } return disposer( creatorFn(), disposerFn, (data) => { t.equal(disposerRan, false, 'disposerFn should not have been called') t.equal(data, mockCreatorResource, 'Disposer not returning the created resource to running function') return Promise.reject(mockFunctionResult) }) .then( () => { throw new Error('expected a failure') }, (data) => { t.equal(disposerRan, true, 'disposerFn should have been called') t.equal(data, mockFunctionResult, 'Disposer not returning the returned result of the function') }) }) test('disposer should reject on creatorFn reject', (t) => { let disposerRan = false const mockCreatorFailure = '__creator_fn_failure__' const creatorFn = () => { return Promise.reject(mockCreatorFailure) } const disposerFn = () => { disposerRan = true return Promise.resolve('Disposer Resolve') } return disposer( creatorFn(), disposerFn, (data) => { throw new Error('expected a failure') }) .catch((data) => { t.equal(disposerRan, false, 'disposerFn should have not have been called') t.equal(data, mockCreatorFailure, 'Disposer not passing along the failure from creator function') }) }) /** * Technically this is breaking the bluebird spec on disposer rejection * * * If a disposer method throws or returns a rejected promise, it's highly likely that it failed to dispose of * the resource. In that case, Bluebird has two options - it can either ignore the error and continue with * program execution or throw an exception (crashing the process in node.js). * * In bluebird we've chosen to do the latter because resources are typically scarce. For example, if a database * connection cannot be disposed of and Bluebird ignores that, the connection pool will be quickly depleted and * the process will become unusable (all requests that query the database will wait forever). Since Bluebird * doesn't know how to handle that, the only sensible default is to crash the process. That way, rather than * getting a useless process that cannot fulfill more requests, we can swap the faulty worker with a new one * letting the OS clean up the resources for us. */ test('disposer should reject on disposerFn reject', (t) => { let disposerRan = false const mockCreatorResource = '__creator_resource__' const mockDisposerReject = '__disposer_reject__' const creatorFn = () => { return Promise.resolve(mockCreatorResource) } const disposerFn = () => { disposerRan = true return Promise.reject(mockDisposerReject) } return disposer( creatorFn(), disposerFn, (data) => { return 'foo' }) .then(() => { throw new Error('expected a failure') }) .catch((data) => { t.equal(disposerRan, true, 'disposerFn should have been called') t.equal(data, mockDisposerReject, 'Disposer not passing along the failure from disposer function') }) }) node-cacache-15.0.5/test/entry-index.js000066400000000000000000000130011374506532500176640ustar00rootroot00000000000000'use strict' const path = require('path') const ssri = require('ssri') const Tacks = require('tacks') const { test } = require('tap') const requireInject = require('require-inject') const index = require('../lib/entry-index') const CacheContent = require('./util/cache-content') const testDir = require('./util/test-dir')(__filename) // defines reusable errors const genericError = new Error('ERR') genericError.code = 'ERR' const missingFileError = new Error('ENOENT') missingFileError.code = 'ENOENT' // helpers const CACHE = path.join(testDir, 'cache') const CONTENT = Buffer.from('foobarbaz', 'utf8') const INTEGRITY = ssri.fromData(CONTENT).toString() const KEY = 'my-test-key' const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) const getEntryIndex = (opts) => requireInject('../lib/entry-index', opts) const getEntryIndexReadFileFailure = (err) => getEntryIndex({ fs: Object.assign({}, require('fs'), { readFile: (path, encode, cb) => { cb(err) }, readFileSync: () => { throw genericError } }) }) const getEntryIndexFixOwnerFailure = (err) => { const chownr = () => Promise.reject(err) chownr.sync = () => { throw err } return getEntryIndex({ '../lib/util/fix-owner': { mkdirfix: require('../lib/util/fix-owner').mkdirfix, chownr } }) } test('delete.sync: removes a cache entry', (t) => { t.plan(3) index.insert(CACHE, KEY, INTEGRITY) .then(index.ls(CACHE)) .then(lsResults => { t.match(lsResults, { key: KEY }, 'should have entries') }) .then(() => { t.equal( index.delete.sync(CACHE, KEY), null, 'should return null on successful deletion' ) return index.ls(CACHE) }) .then(lsResults => { t.notOk(Object.keys(lsResults).length, 'should have no entries') }) }) test('find: error on parsing json data', (t) => { // mocks readFile in order to return a borked json payload const { find } = getEntryIndex({ fs: Object.assign({}, require('fs'), { readFile: (path, encode, cb) => { cb(null, '\ncec8d2e4685534ed189b563c8ee1cb1cb7c72874\t{"""// foo') } }) }) t.plan(1) t.resolveMatch( find(CACHE, KEY), null, 'should resolve with null' ) }) test('find: unknown error on finding entries', (t) => { const { find } = getEntryIndexReadFileFailure(genericError) t.plan(1) t.rejects( find(CACHE, KEY), genericError, 'should reject with the unknown error thrown' ) }) test('find.sync: retrieve from bucket containing multiple entries', (t) => { const entries = [ '\na7eb00332fe51ff62b1bdb1564855f2624f16f34\t{"key":"foo", "integrity": "foo"}', '\n46b1607f427665a99668c02d3a4cc52061afd83a\t{"key":"bar", "integrity": "bar"}' ] const { find } = getEntryIndex({ fs: Object.assign({}, require('fs'), { readFileSync: (path, encode) => entries.join('') }) }) t.match( find.sync(CACHE, 'foo'), { key: 'foo' }, 'should retrieve entry using key' ) t.end() }) test('find.sync: unknown error on finding entries', (t) => { const { find } = getEntryIndexReadFileFailure(genericError) t.throws( () => find.sync(CACHE, KEY), genericError, 'should throw the unknown error' ) t.end() }) test('find.sync: retrieve entry with invalid content', (t) => { const { find } = getEntryIndex({ fs: Object.assign({}, require('fs'), { readFileSync: (path, encode) => '\nb6589fc6ab0dc82cf12099d1c2d40ab994e8410c\t0' }) }) t.match( find.sync(CACHE, 'foo'), null, 'should return null' ) t.end() }) test('insert: missing files on fixing ownership', (t) => { const { insert } = getEntryIndexFixOwnerFailure(missingFileError) t.plan(1) t.resolves( insert(CACHE, KEY, INTEGRITY), 'should insert entry with no errors' ) }) test('insert: unknown errors on fixing ownership', (t) => { const { insert } = getEntryIndexFixOwnerFailure(genericError) t.plan(1) t.rejects( insert(CACHE, KEY, INTEGRITY), genericError, 'should throw the unknown error' ) }) test('insert.sync: missing files on fixing ownership', (t) => { const { insert } = getEntryIndexFixOwnerFailure(missingFileError) t.plan(1) t.doesNotThrow( () => insert.sync(CACHE, KEY, INTEGRITY), 'should insert entry with no errors' ) }) test('insert.sync: unknown errors on fixing ownership', (t) => { const { insert } = getEntryIndexFixOwnerFailure(genericError) t.throws( () => insert.sync(CACHE, KEY, INTEGRITY), genericError, 'should throw the unknown error' ) t.end() }) test('lsStream: unknown error reading files', (t) => { index.insert.sync(CACHE, KEY, INTEGRITY) const { lsStream } = getEntryIndexReadFileFailure(genericError) lsStream(CACHE) .on('error', err => { t.equal(err, genericError, 'should emit an error') t.end() }) }) test('lsStream: missing files error', (t) => { index.insert.sync(CACHE, KEY, INTEGRITY) const { lsStream } = getEntryIndexReadFileFailure(missingFileError) lsStream(CACHE) .on('error', () => { t.fail('should not error') t.end() }) .on('end', () => { t.ok('should end successfully') t.end() }) }) test('lsStream: unknown error reading dirs', (t) => { const { lsStream } = getEntryIndex({ fs: Object.assign({}, require('fs'), { readdir: (path, cb) => { cb(genericError) } }) }) lsStream(CACHE) .on('error', err => { t.equal(err, genericError, 'should emit an error') t.end() }) }) node-cacache-15.0.5/test/get.js000066400000000000000000000444631374506532500162150ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const index = require('../lib/entry-index') const memo = require('../lib/memoization') const path = require('path') const rimraf = util.promisify(require('rimraf')) const Tacks = require('tacks') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') const readFile = util.promisify(fs.readFile) 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('..') 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 integrity let metadata let size const stream = (byDigest ? get.stream.byDigest : get.stream).apply(null, args) return stream .on('integrity', (int) => { integrity = ssri.stringify(int) }) .on('metadata', (m) => { metadata = m }) .on('size', (s) => { size = s }) .concat() .then((data) => ({ data, integrity, metadata, size })) } 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('get.sync will throw ENOENT if not found', (t) => { try { get.sync('foo', 'bar') } catch (err) { t.same(err.message, 'No cache entry for bar found in foo') t.same(err.code, 'ENOENT') t.done() } }) test('get will throw 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('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('get.sync.byDigest without memoization', (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('get.sync.byDigest with memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) const res = get.sync(CACHE, KEY, { memoize: true }) t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data' ) memo.clearMemoized() t.same(memo.get.byDigest(CACHE, INTEGRITY), undefined) const resByDig = get.sync.byDigest(CACHE, INTEGRITY, { memoize: true }) t.deepEqual(resByDig, CONTENT, 'byDigest returned proper data') t.notSame(memo.get.byDigest(CACHE, INTEGRITY), undefined) const resByDig2 = get.sync.byDigest(CACHE, INTEGRITY, { memoize: true }) t.deepEqual(resByDig2, CONTENT, 'byDigest returned proper data') t.done() }) test('get.sync with memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) memo.clearMemoized() t.same(memo.get(CACHE, KEY), undefined) const res = get.sync(CACHE, KEY, { memoize: true }) t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data' ) t.notSame(memo.get(CACHE, KEY), undefined) const resByDig = get.sync(CACHE, KEY, { memoize: true }) t.deepEqual(resByDig, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'get returned proper data') t.done() }) test('get.byDigest without memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) get(CACHE, KEY) .then((res) => { t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') memo.clearMemoized() t.same(memo.get.byDigest(CACHE, INTEGRITY), undefined) return get.byDigest(CACHE, INTEGRITY) .then((resByDig) => { t.deepEqual(resByDig, CONTENT, 'byDigest returned proper data') t.same(memo.get.byDigest(CACHE, INTEGRITY), undefined) return get.byDigest(CACHE, INTEGRITY) }) .then((resByDigMemo) => { t.deepEqual(resByDigMemo, CONTENT, 'byDigest returned proper data') t.done() }) }) }) test('get.byDigest with memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) get(CACHE, KEY) .then((res) => { t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') memo.clearMemoized() t.same(memo.get.byDigest(CACHE, INTEGRITY), undefined) return get.byDigest(CACHE, INTEGRITY, { memoize: true }) .then((resByDig) => { t.deepEqual(resByDig, CONTENT, 'byDigest returned proper data') t.notSame(memo.get.byDigest(CACHE, INTEGRITY), undefined) return get.byDigest(CACHE, INTEGRITY, { memoize: true }) }) .then((resByDigMemo) => { t.deepEqual(resByDigMemo, CONTENT, 'byDigest returned proper data') t.done() }) }) }) test('get without memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) get(CACHE, KEY) .then((res) => { t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') memo.clearMemoized() t.same(memo.get(CACHE, KEY), undefined) return get(CACHE, KEY) .then((resByDig) => { t.deepEqual(resByDig, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'get returned proper data') t.same(memo.get(CACHE, KEY), undefined) return get(CACHE, KEY) }) .then((resByDigMemo) => { t.deepEqual(resByDigMemo, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'get returned proper data') t.done() }) }) }) test('get with memoization', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) index.insert.sync(CACHE, KEY, INTEGRITY, opts()) get(CACHE, KEY) .then((res) => { t.deepEqual( res, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'bulk key get returned proper data') memo.clearMemoized() t.same(memo.get(CACHE, KEY), undefined) return get(CACHE, KEY, { memoize: true }) .then((resByDig) => { t.deepEqual(resByDig, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'get returned proper data') t.notSame(memo.get(CACHE, KEY), undefined) return get(CACHE, KEY, { memoize: true }) }) .then((resByDigMemo) => { t.deepEqual(resByDigMemo, { metadata: METADATA, data: CONTENT, integrity: INTEGRITY, size: SIZE }, 'get 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 Promise.all([ streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY) ]).then(([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.stream add new listeners post stream creation', (t) => { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) t.plan(3) return index.insert(CACHE, KEY, INTEGRITY, opts()).then(() => { const OPTS = { memoize: false, size: CONTENT.length } const stream = get.stream(CACHE, KEY, OPTS) // Awaits index.find in order to synthetically retrieve a point in runtime // in which the stream has already been created and has the entry data // available, allowing for the validation of the newListener event handler return index.find(CACHE, KEY) .then(() => { [ 'integrity', 'metadata', 'size' ].forEach(ev => { stream.on(ev, () => { t.ok(`${ev} listener added`) }) }) return stream.concat() }) }) }) test('get.copy will throw ENOENT if not found', (t) => { const DEST = path.join(CACHE, 'not-found') return get.copy(CACHE, 'NOT-FOUND', DEST) .then(() => { throw new Error('lookup should fail') }) .catch((err) => { t.ok(err, 'got an error') t.equal(err.code, 'ENOENT', 'error code is ENOENT') }) }) test('get.copy with fs.copyfile', { skip: !fs.copyFile && 'Not supported on node versions without fs.copyFile' }, (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 readFile(DEST) }) .then((data) => { t.deepEqual(data, CONTENT, 'data copied by key matches') return rimraf(DEST) }) .then(() => get.copy.byDigest(CACHE, INTEGRITY, DEST)) .then(() => readFile(DEST)) .then((data) => { t.deepEqual(data, CONTENT, 'data copied by digest matches') return rimraf(DEST) }) }) test('get.copy without fs.copyfile', (t) => { const readModuleCache = require.cache[require.resolve('./../lib/content/read')] delete readModuleCache.exports.copy 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 readFile(DEST) }) .then((data) => { t.deepEqual(data, CONTENT, 'data copied by key matches') return rimraf(DEST) }) .then(() => get.copy.byDigest(CACHE, INTEGRITY, DEST)) .then(() => readFile(DEST)) .then((data) => { t.deepEqual(data, CONTENT, 'data copied by digest matches') return rimraf(DEST) }) }) 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 Promise.all([ streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY) ]) .then(() => { 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 Promise.all([ streamGet(false, CACHE, KEY), streamGet(true, CACHE, INTEGRITY) ]).then(([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 Promise.all([ streamGet(false, CACHE, KEY, { memoize: false }).catch((err) => err), streamGet(true, CACHE, INTEGRITY, { memoize: false }).catch((err) => err) ]).then(([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') node-cacache-15.0.5/test/index.find.js000066400000000000000000000135461374506532500174620ustar00rootroot00000000000000'use strict' const CacheIndex = require('./util/cache-index') const fs = require('fs') const path = require('path') const util = require('util') const Tacks = require('tacks') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const stat = util.promisify(fs.stat) 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 stat(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 Promise.all([ 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' ) }) }) node-cacache-15.0.5/test/index.insert.js000066400000000000000000000142401374506532500200360ustar00rootroot00000000000000'use strict' const util = require('util') 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') const testDir = require('./util/test-dir')(__filename) const readFile = util.promisify(fs.readFile) 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 readFile(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 readFile(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 readFile(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 readFile(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 Promise.all([ index.insert(CACHE, KEY, INTEGRITY, opts()), index.insert(CACHE, KEY.toUpperCase(), INTEGRITY + 'upper', opts()) ]).then(() => { return Promise.all([ index.find(CACHE, KEY), index.find(CACHE, KEY.toUpperCase()) ]).then(([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 readFile(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 readFile(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') node-cacache-15.0.5/test/ls.js000066400000000000000000000104121374506532500160370ustar00rootroot00000000000000'use strict' const CacheIndex = require('./util/cache-index') const contentPath = require('../lib/content/path') const index = require('../lib/entry-index.js') const path = require('path') const Tacks = require('tacks') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const CACHE = path.join(testDir, 'cache') const File = Tacks.File const { ls } = require('..') 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 stream.promise().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 stream.promise().then(() => t.deepEqual( listing, { whatever: contents.whatever, whatwhere: contents.whatwhere }, 'ls is streamable' ) ) }) }) node-cacache-15.0.5/test/memoization.js000066400000000000000000000101631374506532500177570ustar00rootroot00000000000000'use strict' const { test } = require('tap') 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() }) node-cacache-15.0.5/test/put.js000066400000000000000000000103661374506532500162410ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const index = require('../lib/entry-index') const memo = require('../lib/memoization') const path = require('path') const { test } = require('tap') const testDir = require('./util/test-dir')(__filename) const ssri = require('ssri') const readFile = util.promisify(fs.readFile) 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') const 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 readFile(dataPath) }) .then((data) => { t.deepEqual(data, CONTENT, 'content was correctly inserted') }) }) test('basic stream insertion', (t) => { let int const stream = put.stream(CACHE, KEY).on('integrity', (i) => { int = i }) return stream.end(CONTENT).promise() .then(() => { t.equal(int.toString(), INTEGRITY, 'returned integrity matches expected') return readFile(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 stream = put .stream(CACHE, KEY, { metadata: METADATA, memoize: true }) .on('integrity', (i) => { int = i }) return stream.end(CONTENT).promise() .then(() => { t.equal(int.toString(), INTEGRITY, 'integrity emitted as usual') return readFile(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 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 Promise.all([ put(CACHE, KEY, CONTENT, { size: 2 }) .then(() => { throw new Error('expected to get a bad size error') }) .catch((err) => err), put.stream(CACHE, KEY, { size: 2 }).end(CONTENT).promise() .then(() => { throw new Error('expected to get a bad size error') }) .catch((err) => err) ]).then(([bulkErr, streamErr]) => { t.equal(bulkErr.code, 'EBADSIZE', 'got error from bulk write') t.equal(streamErr.code, 'EBADSIZE', 'got error from stream write') }) }) node-cacache-15.0.5/test/rm.js000066400000000000000000000063141374506532500160450ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const index = require('../lib/entry-index') const path = require('path') const Tacks = require('tacks') const { test } = require('tap') 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 const readFile = util.promisify(fs.readFile) const mkdir = util.promisify(fs.mkdir) const writeFile = util.promisify(fs.writeFile) const readdir = util.promisify(fs.readdir) 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((err) => { if (err.code === 'ENOENT') { t.match(err.message, KEY, 'entry no longer accessible') return } throw err }) .then(() => { return readFile(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((err) => { if (err.code === 'ENOENT') { t.match(err.message, /no such file/, 'entry no longer accessible') return } throw err }) .then(() => { return readFile(contentPath(CACHE, INTEGRITY)) }) .then(() => { throw new Error('unexpected success') }) .catch((err) => { if (err.code === 'ENOENT') { t.match(err.message, /no such file/, 'content gone') return } throw err }) }) 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 mkdir(path.join(CACHE, 'tmp')) }) .then(() => { return writeFile(path.join(CACHE, 'other.js'), 'hi') }) .then(() => { return rm.all(CACHE) }) .then(() => { return readdir(CACHE) }) .then((files) => { t.deepEqual( files.sort(), ['other.js', 'tmp'], 'removes content and index directories without touching other stuff' ) }) }) node-cacache-15.0.5/test/strict.js000066400000000000000000000015111374506532500167310ustar00rootroot00000000000000'use strict' const fs = require('fs') const glob = require('glob') const path = require('path') const { test } = require('tap') 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', 'coverage/**/*.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() } ) }) node-cacache-15.0.5/test/util.fix-owner.js000066400000000000000000000140631374506532500203210ustar00rootroot00000000000000'use strict' const os = require('os') const { test } = require('tap') const requireInject = require('require-inject') const uniqueFilename = require('unique-filename') // defines reusable errors const genericError = new Error('ERR') genericError.code = 'ERR' const missingFileError = new Error('ENOENT') missingFileError.code = 'ENOENT' const pathExistsError = new Error('EEXIST') pathExistsError.code = 'EEXIST' // helpers const CACHE = require('./util/test-dir')(__filename) const filename = uniqueFilename(os.tmpdir()) const getuid = process.getuid const patchesGetuid = (t) => { process.getuid = () => 0 t.teardown(() => { process.getuid = getuid }) } const getFixOwner = (opts) => requireInject('../lib/util/fix-owner', opts) // chownr and chownr.fix error handling tests test('attempt to chownr existing path', (t) => { patchesGetuid(t) const fixOwner = getFixOwner({ chownr: function chownr (path, uid, gid, cb) { cb(missingFileError) }, 'infer-owner': () => Promise.resolve({}) }) t.plan(1) return fixOwner.chownr(CACHE, filename) .then(res => { t.notOk(res, 'should not throw if path exists') }) }) test('attempt to chownr unknown error', (t) => { patchesGetuid(t) const fixOwner = getFixOwner({ chownr: function chownr (path, uid, gid, cb) { cb(genericError) }, 'infer-owner': () => Promise.resolve({}) }) t.plan(1) t.rejects(() => fixOwner.chownr(CACHE, filename), 'should throw unknown errors') }) test('attempt to chownr using same user', (t) => { patchesGetuid(t) const fixOwner = getFixOwner({ 'infer-owner': () => Promise.resolve({ uid: process.getuid(), gid: process.getgid() }) }) t.plan(1) return fixOwner.chownr(CACHE, filename) .then(res => { t.notOk(res, 'should not throw') }) }) test('calls setuid setgid to replace user', (t) => { const setuid = process.setuid const setgid = process.setgid process.getuid = () => 0 process.setuid = () => undefined process.setgid = () => undefined t.teardown(() => { process.getuid = getuid process.stuid = setuid process.stgid = setgid }) const fixOwner = getFixOwner({ 'infer-owner': () => { process.setuid(process.getuid()) process.setgid(process.getgid()) return Promise.resolve({ uid: process.getuid(), gid: process.getgid() }) } }) t.plan(1) return fixOwner.chownr(CACHE, filename) .then(res => { t.notOk(res, 'should not throw') }) }) test('attempt to chownr.sync on platforms that do not need ownership fix', (t) => { process.getuid = undefined t.teardown(() => { process.getuid = getuid }) const fixOwner = require('../lib/util/fix-owner') t.plan(1) return fixOwner.chownr(CACHE, filename) .then(res => { t.notOk(res, 'should not throw') }) }) test('attempt to chownr.sync existing path', (t) => { patchesGetuid(t) function chownr () {} chownr.sync = () => { throw missingFileError } const fixOwner = getFixOwner({ chownr, 'infer-owner': { sync: () => ({}) } }) t.notOk(fixOwner.chownr.sync(CACHE, filename), 'should not throw if path exists') t.end() }) test('attempt to chownr.sync unknown error', (t) => { patchesGetuid(t) function chownr () {} chownr.sync = () => { throw genericError } const fixOwner = getFixOwner({ chownr, 'infer-owner': { sync: () => ({}) } }) t.throws(() => fixOwner.chownr.sync(CACHE, filename), genericError, 'should throw unknown errors') t.end() }) test('attempt to chownr.sync using same user', (t) => { patchesGetuid(t) const fixOwner = getFixOwner({ 'infer-owner': { sync: () => ({ uid: process.getuid(), gid: process.getgid() }) } }) t.notOk(fixOwner.chownr.sync(CACHE, filename), 'should not throw') t.end() }) test('attempt to chownr.sync on platforms that do not need ownership fix', (t) => { process.getuid = undefined t.teardown(() => { process.getuid = getuid }) const fixOwner = require('../lib/util/fix-owner') t.notOk(fixOwner.chownr.sync(CACHE, filename), 'should not throw') t.end() }) test('uses infer-owner ids instead of process-retrieved if valid', (t) => { const getgid = process.getgid process.getuid = () => 0 process.getgid = () => 1 t.teardown(() => { process.getuid = getuid process.getgid = getgid }) t.plan(3) function chownr () {} chownr.sync = (path, uid, gid) => { t.equal(path, filename, 'should match filename') t.equal(uid, 501, 'should match uid') t.equal(gid, 20, 'should match gid') } const fixOwner = getFixOwner({ chownr, 'infer-owner': { sync: () => ({ uid: 501, gid: 20 }) } }) fixOwner.chownr.sync(CACHE, filename) }) // mkdirfix and mkdirfix.sync error handling tests test('attempt to mkdirfix existing path', (t) => { const fixOwner = getFixOwner({ mkdirp: () => Promise.reject(pathExistsError) }) t.plan(1) return fixOwner.mkdirfix(CACHE, filename) .then(res => { t.notOk(res, 'should not throw if path exists') }) }) test('attempt to mkdirfix unknown error', (t) => { const fixOwner = getFixOwner({ mkdirp: () => Promise.reject(genericError) }) t.plan(1) t.rejects(() => fixOwner.mkdirfix(CACHE, filename), 'should throw unknown errors') }) test('attempt to mkdirfix.sync existing path', (t) => { function mkdirp () {} mkdirp.sync = () => { throw pathExistsError } const fixOwner = getFixOwner({ mkdirp }) t.notOk(fixOwner.mkdirfix.sync(CACHE, filename), 'should not throw if path exists') t.end() }) test('attempt to mkdirfix.sync unknown error', (t) => { function mkdirp () {} mkdirp.sync = () => { throw genericError } const fixOwner = getFixOwner({ mkdirp }) t.throws(() => fixOwner.mkdirfix.sync(CACHE, filename), genericError, 'should throw unknown errors') t.end() }) test('attempt to mkdirfix.sync but no dir created', (t) => { function mkdirp () {} mkdirp.sync = () => {} const fixOwner = getFixOwner({ mkdirp }) t.notOk(fixOwner.mkdirfix.sync(CACHE, filename), 'should not throw') t.end() }) node-cacache-15.0.5/test/util.move-file.js000066400000000000000000000153031374506532500202640ustar00rootroot00000000000000'use strict' const util = require('util') const fs = require('fs') const path = require('path') const requireInject = require('require-inject') const { test } = require('tap') const moveFile = require('../lib/util/move-file') const readFile = util.promisify(fs.readFile) const stat = util.promisify(fs.stat) const open = util.promisify(fs.open) const close = util.promisify(fs.close) const readdir = util.promisify(fs.readdir) const chmod = util.promisify(fs.chmod) test('move a file', function (t) { const testDir = t.testdir({ src: 'foo' }) return moveFile(testDir + '/src', testDir + '/dest') .then(() => { return readFile(testDir + '/dest', 'utf8') }) .then((data) => { t.equal(data, 'foo', 'file data correct') return stat(testDir + '/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 testDir = t.testdir({ src: 'foo', dest: 'bar' }) return moveFile(testDir + '/src', testDir + '/dest') .then(() => { return readFile(testDir + '/dest', 'utf8') }) .then((data) => { t.equal(data, 'bar', 'conflicting file left intact') return stat(testDir + '/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 testDir = t.testdir({ src: 'foo', dest: {} }) return moveFile(testDir + '/src', testDir + '/dest') .then(() => { return readdir(testDir + '/dest') }) .then((files) => { t.equal(files.length, 0, 'directory remains empty') }) }) test('does not error if destination file is open', function (t) { const testDir = t.testdir({ src: 'foo', dest: 'bar' }) return open(testDir + '/dest', 'r+').then((fd) => { return moveFile(testDir + '/src', testDir + '/dest') .then(() => { return close(fd) }) .then(() => { return readFile(testDir + '/dest', 'utf8') }) .then((data) => { t.equal(data, 'bar', 'destination left intact') return stat(testDir + '/src').catch((err) => { t.ok(err, 'src read error') t.equal(err.code, 'ENOENT', 'src does not exist') }) }) }) }) test('fallback to renaming on missing files post-move', function (t) { const testDir = t.testdir({ src: 'foo' }) // Sets up a fs mock that will fail at first unlink/stat call in order // to trigger the fallback scenario then restores the fs methods allowing // for the rename functionality to succeed let shouldMock = true const missingFileError = new Error('ENOENT') missingFileError.code = 'ENOENT' const mockFS = { ...fs, promises: { ...fs.promises, rename: async (src, dest) => { throw Object.assign(new Error('EXDEV'), { code: 'EXDEV' }) }, link: async (src, dest) => { throw new Error('nope') }, unlink: async (path) => { if (shouldMock) { throw missingFileError } else { return fs.promises.unlink(path) } }, lstat: async (path, cb) => { if (shouldMock) { shouldMock = false throw missingFileError } else { return fs.promises.lstat(path) } }, stat: async (path, cb) => { if (shouldMock) { shouldMock = false throw missingFileError } else { return fs.promises.stat(path) } } }, rename: (src, dest, cb) => { if (shouldMock) { cb(Object.assign(new Error('EXDEV'), { code: 'EXDEV' })) } else { fs.rename(src, dest, cb) } }, link (src, dest, cb) { cb(new Error('nope')) }, unlink (path, cb) { if (shouldMock) { cb(missingFileError) } else { fs.unlink(path, cb) } }, lstat (path, cb) { if (shouldMock && path === testDir + '/dest') { cb(missingFileError) shouldMock = false } else { fs.lstat(path, cb) } }, stat (path, cb) { if (shouldMock && path === testDir + '/dest') { cb(missingFileError) shouldMock = false } else { fs.stat(path, cb) } } } const mockedMoveFile = requireInject.withEmptyCache('../lib/util/move-file', { fs: mockFS, '@npmcli/move-file': requireInject.withEmptyCache('@npmcli/move-file', { fs: mockFS }) }) // actual tests are the same used in the simple "move a file" test // since the renaming fallback should accomplish the same results t.plan(3) return mockedMoveFile(testDir + '/src', testDir + '/dest') .then(() => { return readFile(testDir + '/dest', 'utf8') }) .then((data) => { t.equal(data, 'foo', 'file data correct') return stat(testDir + '/src').then(() => { t.fail('src file should not exist, but it does!') }).catch((err) => { t.ok(err, 'src read error') t.equal(err.code, 'ENOENT', 'src does not exist') }) }) }) test('verify weird EPERM on Windows behavior', t => { const gfsLink = fs.link global.__CACACHE_TEST_FAKE_WINDOWS__ = true const gfs = require('fs') let calledMonkeypatch = false gfs.link = (src, dest, cb) => { calledMonkeypatch = true setImmediate(() => cb(Object.assign(new Error('yolo'), { code: 'EPERM' }))) gfs.link = gfsLink global.__CACACHE_TEST_FAKE_WINDOWS__ = false } const testDir = t.testdir({ eperm: { src: 'epermmy' } }) return moveFile(testDir + '/eperm/src', testDir + '/eperm/dest') .then(() => t.ok(calledMonkeypatch, 'called the patched fs.link fn')) .then(() => t.rejects(readFile('eperm/dest'), { code: 'ENOENT' }, 'destination file did not get written')) .then(() => t.rejects(readFile('eperm/src'), { code: 'ENOENT' }, 'src file did get deleted')) }) test( 'errors if dest is not writable', { skip: process.platform === 'win32' }, function (t) { const testDir = t.testdir({ src: 'foo', dest: {} }) return chmod(testDir + '/dest', parseInt('400', 8)) .then(() => { return moveFile(testDir + '/src', path.join(testDir + '/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 readFile(testDir + '/src', 'utf8') }) }) .then((data) => { t.equal(data, 'foo', 'src contents left intact') }) } ) node-cacache-15.0.5/test/util.tmp.js000066400000000000000000000037311374506532500172030ustar00rootroot00000000000000'use strict' const util = require('util') const requireInject = require('require-inject') const fs = require('fs') const path = require('path') const { test } = require('tap') const CACHE = require('./util/test-dir')(__filename) const mockedFixOwner = () => Promise.resolve(1) // temporarily points to original mkdirfix implementation mockedFixOwner.mkdirfix = require('../lib/util/fix-owner').mkdirfix const tmp = requireInject('../lib/util/tmp', { '../lib/util/fix-owner': mockedFixOwner }) const stat = util.promisify(fs.stat) 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 stat(dir) }) .then((s) => { t.ok(s.isDirectory(), 'path points to an existing directory') }) }) test('provides a utility that does resource disposal on tmp', (t) => { return tmp .withTmp(CACHE, (dir) => { return stat(dir) .then((s) => { t.ok(s.isDirectory(), 'path points to an existing directory') }) .then(() => dir) }) .then((dir) => { return Promise.all([ stat(dir) .then(() => { throw new Error('expected fail') }) .catch((err) => { if (err.code === 'ENOENT') { return undefined } throw err }), stat(path.join(CACHE, 'tmp')) ]).then(([nope, yes]) => { t.notOk(nope, 'tmp subdir removed') t.ok(yes.isDirectory(), 'tmp parent dir left intact') }) }) }) test('withTmp should accept both opts and cb params', t => { return tmp.withTmp(CACHE, { tmpPrefix: {} }, dir => { t.ok(dir, 'dir should contain a valid response') }) }) test('provides a function for fixing ownership in the tmp dir', t => { return tmp.fix(CACHE).then(res => { t.ok(res, 'fixOwner is successfully called') }) }) node-cacache-15.0.5/test/util/000077500000000000000000000000001374506532500160425ustar00rootroot00000000000000node-cacache-15.0.5/test/util/cache-content.js000066400000000000000000000013641374506532500211170ustar00rootroot00000000000000'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) { const 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) } } node-cacache-15.0.5/test/util/cache-index.js000066400000000000000000000030141374506532500205460ustar00rootroot00000000000000'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) { const 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) } } node-cacache-15.0.5/test/util/test-dir.js000066400000000000000000000016431374506532500201370ustar00rootroot00000000000000'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).then(() => { process.chdir(testDir) cb() }, cb) }) } node-cacache-15.0.5/test/verify.js000066400000000000000000000275251374506532500167420ustar00rootroot00000000000000'use strict' const util = require('util') const contentPath = require('../lib/content/path') const index = require('../lib/entry-index') const fs = require('fs') const path = require('path') const Tacks = require('tacks') const requireInject = require('require-inject') const { test } = require('tap') 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 const mkdir = util.promisify(fs.mkdir) const readFile = util.promisify(fs.readFile) const truncate = util.promisify(fs.truncate) const stat = util.promisify(fs.stat) const appendFile = util.promisify(fs.appendFile) const writeFile = util.promisify(fs.writeFile) // defines reusable errors const genericError = new Error('ERR') genericError.code = 'ERR' // helpers const getVerify = (opts) => requireInject('../lib/verify', opts) function mockCache () { const fixture = new Tacks( CacheContent({ [INTEGRITY]: CONTENT }) ) fixture.create(CACHE) return mkdir(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 readFile(BUCKET, 'utf8').then((BUCKETDATA) => { // traaaaash return appendFile(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 readFile(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 readFile(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 Promise.all([ index.insert(CACHE, KEY2, INTEGRITY, { metadata: 'haayyyy' }), index.insert(CACHE, KEY3, INTEGRITY, { metadata: 'haayyyy again' }) ]).then(([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 truncate(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 stat(cpath) .then(() => { throw new Error('expected a failure') }) .catch((err) => { if (err.code === 'ENOENT') { t.match(err.message, /no such file/, 'content no longer in cache') return } throw err }) }) }) 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 Promise.all([writeFile(tmpFile, ''), writeFile(misc, '')]).then( () => verify(CACHE) ) }) .then(() => { return Promise.all([ stat(tmpFile).catch((err) => { if (err.code === 'ENOENT') { return err } throw err }), stat(misc) ]).then(([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 Promise.all([ verify.lastRun(CACHE), readFile(path.join(CACHE, '_lastverified'), 'utf8').then((data) => { return new Date(parseInt(data)) }) ]).then(([fromLastRun, fromFile]) => { t.equal(+fromLastRun, +fromFile, 'last verified was writen') }) }) }) test('fixes permissions and users on cache contents') test('missing file error when validating cache content', (t) => { const missingFileError = new Error('ENOENT') missingFileError.code = 'ENOENT' const mockVerify = getVerify({ fs: Object.assign({}, fs, { stat: (path, cb) => { cb(missingFileError) } }) }) t.plan(1) mockCache().then(() => { t.resolveMatch( mockVerify(CACHE), { verifiedContent: 0, rejectedEntries: 1, totalEntries: 0 }, 'should reject entry' ) }) }) test('unknown error when validating content', (t) => { const mockVerify = getVerify({ fs: Object.assign({}, fs, { stat: (path, cb) => { cb(genericError) } }) }) t.plan(1) mockCache().then(() => { t.rejects( mockVerify(CACHE), genericError, 'should throw any unknown errors' ) }) }) test('unknown error when checking sri stream', (t) => { const mockVerify = getVerify({ ssri: Object.assign({}, ssri, { checkStream: () => Promise.reject(genericError) }) }) t.plan(1) mockCache().then(() => { t.rejects( mockVerify(CACHE), genericError, 'should throw any unknown errors' ) }) }) test('unknown error when rebuilding bucket', (t) => { // rebuild bucket uses stat after content-validation // shouldFail controls the right time to mock the error let shouldFail = false const mockVerify = getVerify({ fs: Object.assign({}, fs, { stat: (path, cb) => { if (shouldFail) { return cb(genericError) } fs.stat(path, cb) shouldFail = true } }) }) t.plan(1) mockCache().then(() => { t.rejects( mockVerify(CACHE), genericError, 'should throw any unknown errors' ) }) }) test('re-builds the index with the size parameter', (t) => { const KEY2 = KEY + 'aaa' const KEY3 = KEY + 'bbb' return mockCache() .then(() => { return Promise.all([ 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' ) }) }) }) }) test('hash collisions', (t) => { const mockVerify = getVerify({ '../lib/entry-index': Object.assign({}, index, { hashKey: () => 'aaa' }) }) t.plan(1) mockCache() .then(() => index.insert(CACHE, 'foo', INTEGRITY, { metadata: 'foo' })) .then(() => mockVerify(CACHE)) .then((stats) => { t.deepEqual( { verifiedContent: stats.verifiedContent, rejectedEntries: stats.rejectedEntries, totalEntries: stats.totalEntries }, { verifiedContent: 1, rejectedEntries: 0, totalEntries: 2 }, 'should resolve with no errors' ) }) }) test('hash collisions excluded', (t) => { const mockVerify = getVerify({ '../lib/entry-index': Object.assign({}, index, { hashKey: () => 'aaa' }) }) t.plan(1) mockCache() .then(() => index.insert(CACHE, 'foo', INTEGRITY, { metadata: 'foo' })) .then(() => mockVerify(CACHE, { filter: () => null })) .then((stats) => { t.deepEqual( { verifiedContent: stats.verifiedContent, rejectedEntries: stats.rejectedEntries, totalEntries: stats.totalEntries }, { verifiedContent: 0, rejectedEntries: 2, totalEntries: 0 }, 'should resolve while also excluding filtered out entries' ) }) }) node-cacache-15.0.5/verify.js000066400000000000000000000000671374506532500157530ustar00rootroot00000000000000'use strict' module.exports = require('./lib/verify')